summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarol Willing <carolcode@willingconsulting.com>2014-07-17 12:34:31 -0700
committerCarol Willing <carolcode@willingconsulting.com>2014-08-28 12:53:19 -0700
commit8f17741849edb5e7eba0356f90cb17e43c938a2f (patch)
tree1d16bc49a8d30fb62a1162fd625417486286a4b9
parentd22b8d8e7e8fcb8d16efba6841977dc81ac2c935 (diff)
downloadpython-requests-8f17741849edb5e7eba0356f90cb17e43c938a2f.tar.gz
Adds json parameter for POST requests
-rw-r--r--requests/api.py6
-rw-r--r--requests/models.py22
-rw-r--r--requests/sessions.py10
-rwxr-xr-xtest_requests.py8
4 files changed, 36 insertions, 10 deletions
diff --git a/requests/api.py b/requests/api.py
index 01d853d5..88db7dc7 100644
--- a/requests/api.py
+++ b/requests/api.py
@@ -22,6 +22,7 @@ def request(method, url, **kwargs):
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
+ :param json: (optional) json data to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of 'name': file-like-objects (or {'name': ('filename', fileobj)}) for multipart encoding upload.
@@ -77,15 +78,16 @@ def head(url, **kwargs):
return request('head', url, **kwargs)
-def post(url, data=None, **kwargs):
+def post(url, data=None, json=None, **kwargs):
"""Sends a POST request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
+ :param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
- return request('post', url, data=data, **kwargs)
+ return request('post', url, data=data, json=json, **kwargs)
def put(url, data=None, **kwargs):
diff --git a/requests/models.py b/requests/models.py
index 03ff627a..b6ef9190 100644
--- a/requests/models.py
+++ b/requests/models.py
@@ -190,6 +190,7 @@ class Request(RequestHooksMixin):
:param headers: dictionary of headers to send.
:param files: dictionary of {filename: fileobject} files to multipart upload.
:param data: the body to attach the request. If a dictionary is provided, form-encoding will take place.
+ :param json: json for the body to attach the request.
:param params: dictionary of URL parameters to append to the URL.
:param auth: Auth handler or (user, pass) tuple.
:param cookies: dictionary or CookieJar of cookies to attach to this request.
@@ -209,6 +210,7 @@ class Request(RequestHooksMixin):
headers=None,
files=None,
data=None,
+ json=None,
params=None,
auth=None,
cookies=None,
@@ -216,6 +218,7 @@ class Request(RequestHooksMixin):
# Default empty dicts for dict params.
data = [] if data is None else data
+ json = [] if json is None else json
files = [] if files is None else files
headers = {} if headers is None else headers
params = {} if params is None else params
@@ -230,6 +233,7 @@ class Request(RequestHooksMixin):
self.headers = headers
self.files = files
self.data = data
+ self.json = json
self.params = params
self.auth = auth
self.cookies = cookies
@@ -246,6 +250,7 @@ class Request(RequestHooksMixin):
headers=self.headers,
files=self.files,
data=self.data,
+ json=self.json,
params=self.params,
auth=self.auth,
cookies=self.cookies,
@@ -289,7 +294,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
self.hooks = default_hooks()
def prepare(self, method=None, url=None, headers=None, files=None,
- data=None, params=None, auth=None, cookies=None, hooks=None):
+ data=None, json=None, params=None, auth=None, cookies=None, hooks=None):
"""Prepares the entire request with the given parameters."""
self.prepare_method(method)
@@ -397,7 +402,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
else:
self.headers = CaseInsensitiveDict()
- def prepare_body(self, data, files):
+ def prepare_body(self, data, files, _json=None):
"""Prepares the given HTTP body data."""
# Check if file, fo, generator, iterator.
@@ -408,6 +413,10 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
content_type = None
length = None
+ if _json is not None:
+ content_type = 'application/json'
+ data = json.dumps(_json)
+
is_stream = all([
hasattr(data, '__iter__'),
not isinstance(data, (basestring, list, tuple, dict))
@@ -435,10 +444,11 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
else:
if data:
body = self._encode_params(data)
- if isinstance(data, basestring) or hasattr(data, 'read'):
- content_type = None
- else:
- content_type = 'application/x-www-form-urlencoded'
+ if not _json:
+ if isinstance(data, basestring) or hasattr(data, 'read'):
+ content_type = None
+ else:
+ content_type = 'application/x-www-form-urlencoded'
self.prepare_content_length(body)
diff --git a/requests/sessions.py b/requests/sessions.py
index 508b0ef2..7942447f 100644
--- a/requests/sessions.py
+++ b/requests/sessions.py
@@ -365,6 +365,7 @@ class Session(SessionRedirectMixin):
url=request.url,
files=request.files,
data=request.data,
+ json=request.json,
headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict),
params=merge_setting(request.params, self.params),
auth=merge_setting(auth, self.auth),
@@ -376,6 +377,7 @@ class Session(SessionRedirectMixin):
def request(self, method, url,
params=None,
data=None,
+ json=None,
headers=None,
cookies=None,
files=None,
@@ -396,6 +398,8 @@ class Session(SessionRedirectMixin):
string for the :class:`Request`.
:param data: (optional) Dictionary or bytes to send in the body of the
:class:`Request`.
+ :param json: (optional) json to send in the body of the
+ :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the
:class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the
@@ -426,6 +430,7 @@ class Session(SessionRedirectMixin):
headers = headers,
files = files,
data = data or {},
+ json = json or {},
params = params or {},
auth = auth,
cookies = cookies,
@@ -479,15 +484,16 @@ class Session(SessionRedirectMixin):
kwargs.setdefault('allow_redirects', False)
return self.request('HEAD', url, **kwargs)
- def post(self, url, data=None, **kwargs):
+ def post(self, url, data=None, json=None, **kwargs):
"""Sends a POST request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
+ :param json: (optional) json to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
"""
- return self.request('POST', url, data=data, **kwargs)
+ return self.request('POST', url, data=data, json=json, **kwargs)
def put(self, url, data=None, **kwargs):
"""Sends a PUT request. Returns :class:`Response` object.
diff --git a/test_requests.py b/test_requests.py
index 716c0dcf..2e98cb91 100755
--- a/test_requests.py
+++ b/test_requests.py
@@ -986,6 +986,14 @@ class RequestsTestCase(unittest.TestCase):
assert item.history == total[0:i]
i=i+1
+ def test_json_param_post_content_type_works(self):
+ r = requests.post(
+ httpbin('post'),
+ json={'life': 42}
+ )
+ assert r.status_code == 200
+ assert 'application/json' in r.headers['Content-Type']
+
class TestContentEncodingDetection(unittest.TestCase):