You need to set the content type header:
data = {"data" : "24.3"} data_json = json.dumps(data) headers = {'Content-type': 'application/json'} response = requests.post(url, data=data_json, headers=headers)
If I set url to http://httpbin.org/post, that server echos back to me what was posted:
>>> import json >>> import requests >>> import pprint >>> url = 'http://httpbin.org/post' >>> data = {"data" : "24.3"} >>> data_json = json.dumps(data) >>> headers = {'Content-type': 'application/json'} >>> response = requests.post(url, data=data_json, headers=headers) >>> pprint.pprint(response.json()) {u'args': {}, u'data': u'{"data": "24.3"}', u'files': {}, u'form': {}, u'headers': {u'Accept': u'*/*', u'Accept-Encoding': u'gzip, deflate, compress', u'Connection': u'keep-alive', u'Content-Length': u'16', u'Content-Type': u'application/json', u'Host': u'httpbin.org', u'User-Agent': u'python-requests/1.0.3 CPython/2.6.8 Darwin/11.4.2'}, u'json': {u'data': u'24.3'}, u'origin': u'109.247.40.35', u'url': u'http://httpbin.org/post'} >>> pprint.pprint(response.json()['json']) {u'data': u'24.3'}
If you are using requests version 2.4.2 or newer, you can leave the JSON encoding to the library; it'll automatically set the correct Content-Type header for you too. Pass in the data to be sent as JSON into the json keyword argument:
data = {"data" : "24.3"} response = requests.post(url, json=data)
data = {"data": 24.3}(note: a float, not a string)? I don't know WCF, but here's another interpretation:string test(string data)might mean that your server expects a single string as an input (data_json = '"something"'(note: it is a Python string that contains json text that represents json string)), and it doesn't expect a json object. Strictly speaking "application/json" must represent either a json object (e.g.,data_json = '{"a", 1}') or a json array (e.g.,data_json = '[1,2,3]') therefore it is incorrect to accept just a string.