<commit_before>import cgi
from webob import Request, Response
from webob.exc import HTTPNotFound
import json
import logging
from .validator import validate_args, ValidationError
from .utils import json_encode, is_file, FileIter
from .version import __version__
import threading

try:
    from inspect import signature, _empty
except:
    from funcsigs import signature, _empty

logger = logging.getLogger("firefly")

# XXX-Anand
# Hack to store the request-local context.
# Need to think of a better way to handle this
# or switch to Flask.
ctx = threading.local()
ctx.request = None

class Firefly(object):
    def __init__(self, auth_token=None):
        self.mapping = {}
        self.add_route('/', self.generate_index,internal=True)
        self.auth_token = auth_token

    def set_auth_token(self, token):
        self.auth_token = token

    def add_route(self, path, function, function_name=None, **kwargs):
        self.mapping[path] = FireflyFunction(function, function_name, **kwargs)

    def generate_function_list(self):
        return {f.name: {"path": path, "doc": f.doc, "parameters": f.sig}
                for path, f in self.mapping.items()
                if f.options.get("internal") != True}

    def generate_index(self):
        help_dict = {
            "app": "firefly",
            "version": __version__,
            "functions": self.generate_function_list()
            }
        return help_dict

    def __call__(self, environ, start_response):
        request = Request(environ)
        response = self.process_request(request)
        return response(environ, start_response)

    def verify_auth_token(self, request):
        return not self.auth_token or self.auth_token == self._get_auth_token(request)

    def _get_auth_token(self, request):
        auth = request.headers.get("Authorization")
        if auth and auth.lower().startswith("token"):
            return auth[len("token"):].strip()

    def http_error(self, status, error=None):
        response = Response()
        response.status = status
        response.text = json_encode({"error": error})
        return response

    def process_request(self, request):
        if not self.verify_auth_token(request):
            return self.http_error('403 Forbidden', error='Invalid auth token')

        # Clear all the existing state, if any
        ctx.__dict__.clear()

        ctx.request = request

        path = request.path_info
        if path in self.mapping:
            func = self.mapping[path]
            response = func(request)
        else:
            response = self.http_error('404 Not Found', error="Not found: " + path)

        ctx.request = None
        return response

class FireflyFunction(object):
    def __init__(self, function, function_name=None, **options):
        self.function = function
        self.options = options
        self.name = function_name or function.__name__
        self.doc = function.__doc__ or ""
        self.sig = self.generate_signature(function)

    def __repr__(self):
        return "<FireflyFunction %r>" % self.function<commit_msg>Added quick fix to enable CORS support.<commit_after>import cgi
from webob import Request, Response
from webob.exc import HTTPNotFound
import json
import logging
from .validator import validate_args, ValidationError
from .utils import json_encode, is_file, FileIter
from .version import __version__
import threading

try:
    from inspect import signature, _empty
except:
    from funcsigs import signature, _empty

logger = logging.getLogger("firefly")

# XXX-Anand
# Hack to store the request-local context.
# Need to think of a better way to handle this
# or switch to Flask.
ctx = threading.local()
ctx.request = None

class Firefly(object):
    def __init__(self, auth_token=None):
        self.mapping = {}
        self.add_route('/', self.generate_index,internal=True)
        self.auth_token = auth_token

    def set_auth_token(self, token):
        self.auth_token = token

    def add_route(self, path, function, function_name=None, **kwargs):
        self.mapping[path] = FireflyFunction(function, function_name, **kwargs)

    def generate_function_list(self):
        return {f.name: {"path": path, "doc": f.doc, "parameters": f.sig}
                for path, f in self.mapping.items()
                if f.options.get("internal") != True}

    def generate_index(self):
        help_dict = {
            "app": "firefly",
            "version": __version__,
            "functions": self.generate_function_list()
            }
        return help_dict

    def __call__(self, environ, start_response):
        request = Request(environ)
        response = self.process_request(request)
        return response(environ, start_response)

    def verify_auth_token(self, request):
        return not self.auth_token or self.auth_token == self._get_auth_token(request)

    def _get_auth_token(self, request):
        auth = request.headers.get("Authorization")
        if auth and auth.lower().startswith("token"):
            return auth[len("token"):].strip()

    def http_error(self, status, error=None):
        response = Response()
        response.status = status
        response.text = json_encode({"error": error})
        return response

    def process_request(self, request):
        if not self.verify_auth_token(request):
            return self.http_error('403 Forbidden', error='Invalid auth token')

        # Clear all the existing state, if any
        ctx.__dict__.clear()

        ctx.request = request

        path = request.path_info
        if path in self.mapping:
            func = self.mapping[path]
            response = func(request)
        else:
            response = self.http_error('404 Not Found', error="Not found: " + path)

        # XXX-Anand: Dec 2017 - QuickFix - CORS support
        # Adding CORS headers to every response to allow
        # making calls to the API from any JS application.
        extra_headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET,POST',
            'Access-Control-Allow-Headers': 'Content-type'
        }
        response.headerlist += list(extra_headers.items())

        ctx.request = None
        return response

class FireflyFunction(object):
    def __init__(self, function, function_name=None, **options):
        self.function = function
        self.options = options
        self.name = function_name or function.__name__
        self.doc = function.__doc__ or ""
        self.sig = self.generate_signature(function)

    def __repr__(self):
        return "<FireflyFunction %r>" % self.function
{'fraction_non_alphanumeric': 0.1000752445447705, 'fraction_numerical': 0.0024078254326561324, 'mean_word_length': 2.746335963923337, 'pattern_counts': {'":': 14, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4960007', 'n_tokens_mistral': 1853, 'n_tokens_neox': 1817, 'n_words': 514}