Exemplo n.º 1
0
class HttpClient(object):
    def __init__(self, environment):
        self._injectors = []
        self.environment = environment
        self.encoder = Encoder([Json(), Text(), Multipart(), FormEncoded()])

    def get_user_agent(self):
        return "Python HTTP/1.1"

    def get_timeout(self):
        return 30

    def add_injector(self, injector):
        if injector and '__call__' in dir(injector):
            self._injectors.append(injector)
        else:
            raise TypeError(
                "injector must be a function or implement the __call__ method")

    def execute(self, request):
        reqCpy = copy.deepcopy(request)

        try:
            getattr(reqCpy, 'headers')
        except AttributeError:
            reqCpy.headers = {}

        for injector in self._injectors:
            injector(reqCpy)

        if "User-Agent" not in reqCpy.headers:
            reqCpy.headers["User-Agent"] = self.get_user_agent()

        data = None
        if hasattr(reqCpy, 'body') and reqCpy.body is not None:
            data = self.encoder.serialize_request(reqCpy)

        resp = requests.request(method=reqCpy.verb,
                                url=self.environment.base_url + reqCpy.path,
                                headers=reqCpy.headers,
                                data=data)

        return self.parse_response(resp)

    def parse_response(self, response):
        status_code = response.status_code

        if 200 <= status_code <= 299:
            body = ""
            if response.text and (len(response.text) > 0
                                  and response.text != 'None'):
                body = self.encoder.deserialize_response(
                    response.text, response.headers)

            return HttpResponse(body, response.status_code, response.headers)
        else:
            raise HttpError(response.text, response.status_code,
                            response.headers)
Exemplo n.º 2
0
    def test_Encoder_deserialize_response_text(self):
        j = 'some plain text'
        headers = {"Content-Type": "text/plain"}

        b = Encoder([Json(), Text(),
                     Multipart(),
                     FormEncoded()]).deserialize_response(j, headers)

        self.assertEqual(j, b)
Exemplo n.º 3
0
    def test_Encoder_serialize_request_withTextContentType_stringifiesData(
            self):
        req = GenericRequest()
        req.body = "some text data"
        req.headers = {"Content-Type": "text/plain; charset=utf8"}

        b = Encoder([Json(), Text(),
                     Multipart(), FormEncoded()]).serialize_request(req)

        self.assertEqual(req.body, b)
Exemplo n.º 4
0
    def test_Encoder_deserialize_response_Json(self):
        j = '{"key": "value", "list": ["one", "two"]}'

        headers = {"Content-Type": "application/json"}

        b = Encoder([Json(), Text(),
                     Multipart(),
                     FormEncoded()]).deserialize_response(j, headers)

        self.assertEqual("value", b["key"])
        self.assertEqual(["one", "two"], b["list"])
Exemplo n.º 5
0
    def test_Encoder_serialize_request_throwsWhenHeadersNone(self):
        req = GenericRequest()
        req.body = {"key": "value", "list": ["one", "two"]}

        try:
            Encoder([Json(), Text(),
                     Multipart(), FormEncoded()]).serialize_request(req)
        except Exception as e:
            self.assertIsInstance(e, IOError)
            self.assertEqual(
                "Http request does not have Content-Type header set", str(e))
Exemplo n.º 6
0
    def test_Encoder_serialize_request_withJsonContentType_stringifysData(
            self):
        req = GenericRequest()
        req.body = {"key": "value", "list": ["one", "two"]}
        req.headers = {"Content-Type": "application/json; charset=utf8"}

        j = Encoder([Json(), Text(),
                     Multipart(), FormEncoded()]).serialize_request(req)

        self.assertTrue('{' in j)
        self.assertTrue('"key": "value"' in j)
        self.assertTrue('"list": ["one", "two"]' in j)
Exemplo n.º 7
0
    def test_Encoder_serialize_request_throwsWhenContentTypeNotJson(self):
        req = GenericRequest()
        req.body = {"key": "value", "list": ["one", "two"]}
        req.headers = {"Content-Type": "application/xml"}

        try:
            Encoder([Json(), Text(),
                     Multipart(), FormEncoded()]).serialize_request(req)
        except Exception as e:
            self.assertIsInstance(e, IOError)
            self.assertTrue(
                "Unable to serialize request with Content-Type application/xml. Supported encodings are "
                in str(e))
Exemplo n.º 8
0
    def test_Encoder_deserialize_response_formEncoded(self):
        data = 'key=value&key_two=value%20with%20spaces'
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}

        try:
            b = Encoder([Json(), Text(),
                         Multipart(),
                         FormEncoded()]).deserialize_response(data, headers)
            self.fail(
                'deserialize should have thrown with content-type formencoded')
        except IOError as e:
            self.assertTrue('FormEncoded does not support deserialization',
                            str(e))
Exemplo n.º 9
0
    def test_Encoder_deserialize_response_multipart(self):
        j = 'some plain text'
        headers = {"Content-Type": "multipart/form-data"}

        try:
            b = Encoder([Json(), Text(),
                         Multipart(),
                         FormEncoded()]).deserialize_response(j, headers)
            self.fail(
                'deserialize should have thrown with content-type multipart')
        except IOError as e:
            self.assertTrue('Multipart does not support deserialization',
                            str(e))
Exemplo n.º 10
0
    def test_Encoder_deserialize_response_throwsWhenHeadersNone(self):
        j = '{"key": "value", "list": ["one", "two"]}'

        headers = None

        try:
            b = Encoder([Json(), Text(),
                         Multipart(),
                         FormEncoded()]).deserialize_response(j, headers)
        except IOError as e:
            self.assertIsInstance(e, IOError)
            self.assertEqual(
                "Http response does not have Content-Type header set", str(e))
Exemplo n.º 11
0
    def test_Encoder_deserialize_response_throwsWhenContentTypeNotSupported(
            self):
        j = '{"key": "value", "list": ["one", "two"]}'

        headers = {"Content-Type": "application/xml"}

        try:
            b = Encoder([Json(), Text(),
                         Multipart(),
                         FormEncoded()]).deserialize_response(j, headers)
        except IOError as e:
            self.assertIsInstance(e, IOError)
            self.assertTrue(
                "Unable to deserialize response with Content-Type application/xml. Supported decodings are "
                in str(e))
Exemplo n.º 12
0
    def test_Encode_serialize_request_withFormEncodedContentType_stringifysData(
            self):
        request = GenericRequest()
        request.path = "/"
        request.verb = "POST"
        request.headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=utf8"
        }
        request.body = {'key': 'value', 'key_two': 'value with spaces'}

        serialized = Encoder([Json(),
                              Text(),
                              Multipart(),
                              FormEncoded()]).serialize_request(request)
        self.assertIsNotNone(
            re.match(
                '(key=value&key_two=value%20with%20spaces|key_two=value%20with%20spaces&key=value)',
                serialized))
Exemplo n.º 13
0
    def add_form_part(self, key, formPart):
        retValue = "Content-Disposition: form-data; name=\"{}\"".format(key)
        if formPart.headers["Content-Type"] == "application/json":
            retValue += "; filename=\"{}.json\"".format(key)
        retValue += CRLF

        for key in formPart.headers:
            retValue += "{}: {}{}".format(key, formPart.headers[key], CRLF)

        retValue += CRLF

        req = FormPartRequest()
        req.headers = formPart.headers
        req.body = formPart.value
        retValue += Encoder([Json(), Text(),
                             FormEncoded()]).serialize_request(req)

        retValue += CRLF
        return retValue
Exemplo n.º 14
0
    def test_Encoder_serialize_request_withMultipartContentType_stringifysData(
            self):
        request = GenericRequest()
        request.path = "/"
        request.verb = "POST"
        request.headers = {"Content-Type": "multipart/form-data; charset=utf8"}
        f = File(abspath('tests/resources/fileupload_test_binary.jpg'))
        data = f.read()

        request.body = {
            "some_key": "some_value",
            "some_nested[key]": "some_nested_value",
            "file": f
        }

        serialized = Encoder([Json(),
                              Text(),
                              Multipart(),
                              FormEncoded()]).serialize_request(request)
        self.assertTrue("multipart/form-data; boundary=" in
                        request.headers["Content-Type"])

        self.assertTrue(
            "Content-Disposition: form-data; name=\"some_key\"" in serialized)
        self.assertTrue("some_value" in serialized)
        self.assertTrue(
            "Content-Disposition: form-data; name=\"some_nested[key]\"" in
            serialized)
        self.assertTrue("some_nested_value" in serialized)
        self.assertTrue(
            "Content-Disposition: form-data; name=\"file\"; filename=\"fileupload_test_binary.jpg\""
            in serialized)
        self.assertTrue("Content-Type: image/jpeg" in serialized)
        self.assertTrue(str(data) in serialized)

        f.close()
Exemplo n.º 15
0
    def test_Encoder_serialize_request_withMultipartContentType_encodesFormPart(
            self):
        request = GenericRequest()
        request.path = "/"
        request.verb = "POST"
        request.headers = {"Content-Type": "multipart/form-data; charset=utf8"}
        f = File(abspath('tests/resources/fileupload_test_binary.jpg'))
        data = f.read()

        request.body = {
            "file": f,
            "input": FormPart({"key": "val"},
                              {"Content-Type": "application/json"})
        }

        serialized = Encoder([Json(),
                              Text(),
                              Multipart(),
                              FormEncoded()]).serialize_request(request)
        self.assertTrue("multipart/form-data; boundary=" in
                        request.headers["Content-Type"])

        self.assertTrue(
            "Content-Disposition: form-data; name=\"input\"; filename=\"input.json\""
            in serialized)
        self.assertTrue("{\"key\": \"val\"}" in serialized)
        self.assertTrue(
            "Content-Disposition: form-data; name=\"file\"; filename=\"fileupload_test_binary.jpg\""
            in serialized)
        self.assertTrue("Content-Type: image/jpeg" in serialized)
        self.assertTrue(str(data) in serialized)
        self.assertIsNotNone(
            re.search('.*input.json.*fileupload_test_binary.jpg.*', serialized,
                      re.MULTILINE | re.DOTALL))

        f.close()
Exemplo n.º 16
0
 def __init__(self, environment):
     self._injectors = []
     self.environment = environment
     self.encoder = Encoder([Json(), Text(), Multipart(), FormEncoded()])