<commit_before>from __future__ import absolute_import

from characteristic import Attribute, attributes
from cached_property import cached_property as calculated_once
from six import BytesIO, iteritems
from werkzeug.http import HTTP_STATUS_CODES as HTTP_STATUS_PHRASES

from minion.deferred import Deferred
from minion.http import Accept, Headers, MutableHeaders


HTTP_STATUS_CODES = dict(
    (code, "{0} {1}".format(code, phrase))
    for code, phrase in iteritems(HTTP_STATUS_PHRASES)
)


class Responder(object):
    """
    A responder represents a pending HTTP response for a corresponding request.

    """

    def __init__(self, request):
        self._after_deferreds = []
        self.request = request

    def after(self):
        """
        Return a deferred that will fire after the request is finished.

        :returns: a new :class:`Deferred` for each call to this function.

        """

        d = Deferred()
        self._after_deferreds.append(d)
        return d.chain

    def finish(self):
        for d in self._after_deferreds:
            d.succeed(self)


class Manager(object):
    """
    The request manager coordinates state during each active request.

    """

    def __init__(self):
        self.requests = {}

    def after_response(self, request, fn, *args, **kwargs):
        """
        Call the given callable after the given request has its response.

        :argument request: the request to piggyback
        :argument fn: a callable that takes at least two arguments, the request
            and the response (in that order), along with any additional
            positional and keyword arguments passed to this function which will
            be passed along. If the callable returns something other than
            ``None``, it will be used as the new response.

        """

        self.requests[request]["callbacks"].append((fn, args, kwargs))

    def request_started(self, request):
        self.requests[request] = {"callbacks": [], "assets": {}}

    def request_served(self, request, response):
        request_data = self.requests.pop(request)
        for callback, args, kwargs in request_data["callbacks"]:
            callback_response = callback(response, *args, **kwargs)
            if callback_response is not None:
                response = callback_response
        return response


@attributes(
    [
        Attribute(name="content", default_factory=BytesIO),
        Attribute(name="headers", default_factory=Headers),
        Attribute(name="path"),
        Attribute(name="method", default_value=b"GET"),
        Attribute(
            name="messages", default_factory=list, exclude_from_cmp=True,
        ),
    ],
)
class Request(object):
    @calculated_once
    def accept(self):
        header = self.headers.get("Accept")
        if header is not None:<commit_msg>Manager will change soon, but until then, avoid Python's annoying lack of frozendict by being lazy.<commit_after>from __future__ import absolute_import

from characteristic import Attribute, attributes
from cached_property import cached_property as calculated_once
from six import BytesIO, iteritems
from werkzeug.http import HTTP_STATUS_CODES as HTTP_STATUS_PHRASES

from minion.deferred import Deferred
from minion.http import Accept, Headers, MutableHeaders


HTTP_STATUS_CODES = dict(
    (code, "{0} {1}".format(code, phrase))
    for code, phrase in iteritems(HTTP_STATUS_PHRASES)
)


class Responder(object):
    """
    A responder represents a pending HTTP response for a corresponding request.

    """

    def __init__(self, request):
        self._after_deferreds = []
        self.request = request

    def after(self):
        """
        Return a deferred that will fire after the request is finished.

        :returns: a new :class:`Deferred` for each call to this function.

        """

        d = Deferred()
        self._after_deferreds.append(d)
        return d.chain

    def finish(self):
        for d in self._after_deferreds:
            d.succeed(self)


class Manager(object):
    """
    The request manager coordinates state during each active request.

    """

    def __init__(self):
        self._requests = {}

    def after_response(self, request, fn, *args, **kwargs):
        """
        Call the given callable after the given request has its response.

        :argument request: the request to piggyback
        :argument fn: a callable that takes at least two arguments, the request
            and the response (in that order), along with any additional
            positional and keyword arguments passed to this function which will
            be passed along. If the callable returns something other than
            ``None``, it will be used as the new response.

        """

        self._requests[id(request)]["callbacks"].append((fn, args, kwargs))

    def request_started(self, request):
        self._requests[id(request)] = {"callbacks": [], "assets": {}}

    def request_served(self, request, response):
        request_data = self._requests.pop(id(request))
        for callback, args, kwargs in request_data["callbacks"]:
            callback_response = callback(response, *args, **kwargs)
            if callback_response is not None:
                response = callback_response
        return response


@attributes(
    [
        Attribute(name="content", default_factory=BytesIO),
        Attribute(name="headers", default_factory=Headers),
        Attribute(name="path"),
        Attribute(name="method", default_value=b"GET"),
        Attribute(
            name="messages", default_factory=list, exclude_from_cmp=True,
        ),
    ],
)
class Request(object):
    @calculated_once
    def accept(self):
        header = self.headers.get("Accept")
        if header is not None:
{'fraction_non_alphanumeric': 0.09034482758620689, 'fraction_numerical': 0.000689655172413793, 'mean_word_length': 2.854485049833887, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 3, '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': '1500409', 'n_tokens_mistral': 1553, 'n_tokens_neox': 1512, 'n_words': 508}