From 8a5e59325a0724710e27eefca1c7abcb8847fc8c Mon Sep 17 00:00:00 2001 From: Mike Matz Date: Wed, 11 Jul 2012 19:05:48 -0700 Subject: [PATCH 1/4] Separate input and output serializers; add support for form data Form data (application/x-www-form-urlencoded) is now supported under the "formdata" type. It is now possible to use different serializers for input and output. Pass input_format="formdata" to API.__init__() to use form data as input to the remote API (e.g. Mailgun API) --- slumber/__init__.py | 24 +++++++++++++++++------- slumber/serialize.py | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/slumber/__init__.py b/slumber/__init__.py index d6e2cf2..429c69b 100644 --- a/slumber/__init__.py +++ b/slumber/__init__.py @@ -89,16 +89,25 @@ def __call__(self, id=None, format=None, url_override=None): return self.__class__(**kwargs) def get_serializer(self): + return self.get_output_serializer() + + def get_output_serializer(self): return Serializer(default_format=self._store["format"]) + def get_input_serializer(self): + return Serializer(default_format=self._store["input_format"]) + def _request(self, method, data=None, params=None): - s = self.get_serializer() + input_serializer = self.get_input_serializer() + input_type = input_serializer.get_content_type() + output_serializer = self.get_output_serializer() + output_type = output_serializer.get_content_type() url = self._store["base_url"] if self._store["append_slash"] and not url.endswith("/"): url = url + "/" - resp = self._store["session"].request(method, url, data=data, params=params, headers={"content-type": s.get_content_type(), "accept": s.get_content_type()}) + resp = self._store["session"].request(method, url, data=data, params=params, headers={"content-type": input_type, "accept": output_type}) if 400 <= resp.status_code <= 499: raise exceptions.HttpClientError("Client Error %s: %s" % (resp.status_code, url), response=resp, content=resp.content) @@ -108,7 +117,7 @@ def _request(self, method, data=None, params=None): return resp def get(self, **kwargs): - s = self.get_serializer() + s = self.get_output_serializer() resp = self._request("GET", params=kwargs) if 200 <= resp.status_code <= 299: @@ -120,7 +129,7 @@ def get(self, **kwargs): return # @@@ We should probably do some sort of error here? (Is this even possible?) def post(self, data, **kwargs): - s = self.get_serializer() + s = self.get_input_serializer() resp = self._request("POST", data=s.dumps(data), params=kwargs) if 200 <= resp.status_code <= 299: @@ -135,9 +144,9 @@ def post(self, data, **kwargs): return def put(self, data, **kwargs): - s = self.get_serializer() + s = self.get_input_serializer() - resp = self._request("PUT", data=s.dumps(data), params=kwargs) + resp = self._request("PUT", data=s.dumps(data), params=kwargs, content_type=s.get_content_type()) if 200 <= resp.status_code <= 299: if resp.status_code == 204: return True @@ -159,10 +168,11 @@ def delete(self, **kwargs): class API(ResourceAttributesMixin, object): - def __init__(self, base_url=None, auth=None, format=None, append_slash=True, session=None): + def __init__(self, base_url=None, auth=None, format=None, input_format=None, append_slash=True, session=None): self._store = { "base_url": base_url, "format": format if format is not None else "json", + "input_format": input_format if input_format is not None else "json", "append_slash": append_slash, "session": requests.session(auth=auth) if session is None else session, } diff --git a/slumber/serialize.py b/slumber/serialize.py index 213a725..40e5a25 100644 --- a/slumber/serialize.py +++ b/slumber/serialize.py @@ -1,8 +1,11 @@ +import urllib +import urlparse from slumber import exceptions SERIALIZERS = { "json": True, "yaml": True, + "formdata": True, } try: @@ -60,11 +63,25 @@ def dumps(self, data): return yaml.dump(data) +class FormDataSerializer(BaseSerializer): + + content_type = 'application/x-www-form-urlencoded' + + def loads(self, data): + result = urlparse.parse_qs(data) + return result + + def dumps(self, data): + result = urllib.urlencode(data) + return result + + class Serializer(object): _serializers = { "json": JsonSerializer(), "yaml": YamlSerializer(), + "formdata": FormDataSerializer(), } def __init__(self, default_format="json"): From d0cd360c14885477acb5799f84040abcf0645407 Mon Sep 17 00:00:00 2001 From: Mike Matz Date: Wed, 11 Jul 2012 19:58:35 -0700 Subject: [PATCH 2/4] Remove unneeded content_type parameter Just an artifact of previous commit --- slumber/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slumber/__init__.py b/slumber/__init__.py index 429c69b..21241e5 100644 --- a/slumber/__init__.py +++ b/slumber/__init__.py @@ -146,7 +146,7 @@ def post(self, data, **kwargs): def put(self, data, **kwargs): s = self.get_input_serializer() - resp = self._request("PUT", data=s.dumps(data), params=kwargs, content_type=s.get_content_type()) + resp = self._request("PUT", data=s.dumps(data), params=kwargs) if 200 <= resp.status_code <= 299: if resp.status_code == 204: return True From 466f481eac5f02591af0243e9d0e628efd6111a1 Mon Sep 17 00:00:00 2001 From: Mike Matz Date: Wed, 11 Jul 2012 22:28:52 -0700 Subject: [PATCH 3/4] Ignore .pyc files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 229ecfa..17a6dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ docs/_build/* +*.pyc From 11fbe90eb06ecf934ad75a3380c13302bdc32e05 Mon Sep 17 00:00:00 2001 From: Steven Willis Date: Fri, 23 Jun 2017 02:09:38 -0400 Subject: [PATCH 4/4] Fix python3 issues --- slumber/serialize.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/slumber/serialize.py b/slumber/serialize.py index 45c2cd0..6f4fa3e 100644 --- a/slumber/serialize.py +++ b/slumber/serialize.py @@ -1,5 +1,8 @@ -import urllib -import urlparse +try: + from urllib.parse import urlencode, parse_qs +except ImportError: + from urllib import urlencode + from urlparse import parse_qs from slumber import exceptions _SERIALIZERS = { @@ -72,11 +75,11 @@ class FormDataSerializer(BaseSerializer): key = "formdata" def loads(self, data): - result = urlparse.parse_qs(data) + result = parse_qs(data) return result def dumps(self, data): - result = urllib.urlencode(data) + result = urlencode(data) return result