<commit_before>"""
A request represents a client wanting to get a resource from the server.

This is automatically passed into your app route when an appropriate path is recieved.
"""

# Use the C parser if applicable.
import logging

try:
    from http_parser.parser import HttpParser
except ImportError:
    from http_parser.pyparser import HttpParser

from kyokai.exc import HTTPClientException


logger = logging.getLogger("Kyokai")

class Request(object):
    """
    A Request object.

    This should not be manually created. Instead, it is automatically provided by Kyokai.

    Attributes:
        method: str
            The method of the request.
    """

    def __init__(self, parser: HttpParser):
        """
        Create a new Request.
        """
        self._parser = parser
        self.method = parser.get_method()
        self.path = parser.get_path()
        self.headers = parser.get_headers()
        self.query = parser.get_query_string()
        self.body = parser.recv_body().decode()
        self._fully_parsed = parser.is_message_complete()

    @classmethod
    def from_data(cls, data: bytes):
        """
        Create a new request from request data.
        """
        parser = HttpParser()
        # Get the length of the data.
        data_len = len(data)
        # Execute the parser.
        parsed_len = parser.execute(data, data_len)
        logger.debug("Expected length vs parsed length: {}/{}".format(data_len, parsed_len))
        if parsed_len == 0 or (data_len != parsed_len and parser.is_message_complete()):
            logger.debug("Parsing complete and parsed length != expected length.")
            raise HTTPClientException(400, "Bad Request")

        # Create a new request.
        req = cls(parser)

        return req<commit_msg>Add query string parsing and POST body parsing.<commit_after>"""
A request represents a client wanting to get a resource from the server.

This is automatically passed into your app route when an appropriate path is recieved.
"""

import logging
import urllib.parse as uparse

# Use the C parser if applicable.
try:
    from http_parser.parser import HttpParser
except ImportError:
    from http_parser.pyparser import HttpParser

from kyokai.exc import HTTPClientException


logger = logging.getLogger("Kyokai")


class Request(object):
    """
    A Request object.

    This should not be manually created. Instead, it is automatically provided by Kyokai.

    Attributes:
        method: str
            The method of the request.
    """

    def __init__(self, parser: HttpParser):
        """
        Create a new Request.
        """
        self._parser = parser
        self.method = parser.get_method()
        self.path = parser.get_path()
        self.headers = parser.get_headers()
        self.query = parser.get_query_string()
        self.body = parser.recv_body().decode()
        self._fully_parsed = parser.is_message_complete()

        # urlparse out the items.
        self._raw_args = uparse.parse_qs(self.query, keep_blank_values=True)
        # Reparse args
        self.args = {}
        for k, v in self._raw_args.items():
            if len(v) == 1:
                self.args[k] = v[0]
            elif len(v) == 0:
                self.args[k] = None
            else:
                self.args[k] = v
        self.form = uparse.parse_qs(self.body, keep_blank_values=True)


    @classmethod
    def from_data(cls, data: bytes):
        """
        Create a new request from request data.
        """
        parser = HttpParser()
        # Get the length of the data.
        data_len = len(data)
        # Execute the parser.
        parsed_len = parser.execute(data, data_len)
        logger.debug("Expected length vs parsed length: {}/{}".format(data_len, parsed_len))
        if parsed_len == 0 or (data_len != parsed_len and parser.is_message_complete()):
            logger.debug("Parsing complete and parsed length != expected length.")
            raise HTTPClientException(400, "Bad Request")

        # Create a new request.
        req = cls(parser)

        return req
{'fraction_non_alphanumeric': 0.09068746952705997, 'fraction_numerical': 0.002681618722574354, 'mean_word_length': 2.3741776315789473, 'pattern_counts': {'":': 0, '<': 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': '1021572', 'n_tokens_mistral': 1143, 'n_tokens_neox': 1113, 'n_words': 367}