27

I'm new to web services and am trying to send the following JSON based request using a python script:

http://myserver/emoncms2/api/post?apikey=xxxxxxxxxxxxx&json={power:290.4,temperature:19.4}

If I paste the above into a browser, it works as expected. However, I am struggling to send the request from Python. The following is what I am trying:

import json
import urllib2
data = {'temperature':'24.3'}
data_json = json.dumps(data)
host = "http://myserver/emoncms2/api/post"
req = urllib2.Request(host, 'GET', data_json, {'content-type': 'application/json'})
response_stream = urllib2.urlopen(req)
json_response = response_stream.read()

How do I add the apikey data into the request?

Thank you!

3 Answers 3

41

Instead of using urllib2, you can use requests. This new python lib is really well written and it's easier and more intuitive to use.

To send your json data you can use something like the following code:

import json
import requests
data = {'temperature':'24.3'}
data_json = json.dumps(data)
payload = {'json_payload': data_json, 'apikey': 'YOUR_API_KEY_HERE'}
r = requests.get('http://myserver/emoncms2/api/post', data=payload)

You can then inspect r to obtain an http status code, content, etc

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your response! Is there a method I can use to print the actual get request string? The server is responding with "valid write apikey required", but I am using the same key that works in the browser.
Yes, you can use an event hook for that. Actually the requests docs contain an example with just that, printing the url before sending the request: docs.python-requests.org/en/latest/user/advanced/#event-hooks
Hi Simao, that gives me the ability to look at the arguments, but what do I need to do to see the actual full request string that is being sent to the server, e.g.'myserver/emoncms2/api/post?apikey=xxxxxxxxxxxxx&json={power:290.4,temperature:19.4}
OK, think I found out how to see the detail request, I needed to redirect verbose logging to stdout.
I tried using a hook as described in the documentation and it seems the data is being sent. Note that the args variable passed to your callback contain more than the url, it's a full Requests GET object. Also, in your original post, you mentioned you were trying to GET your resource, but in your last log line you are showing a POST request.
|
7

Even though this doesnt exactly answer OPs question, it should be mentioned here that requests module has a json option that can be used like this:

import requests

requests.post(
    'http://myserver/emoncms2/api/post?apikey=xxxxxxxxxxxxx',
    json={"temperature": "24.3"}
)

which would be equivalent to the curl:

curl 'http://myserver/emoncms2/api/post?apikey=xxxxxxxxxxxxx' \
    -H 'Content-Type: application/json' \
    --data-binary '{"temperature":"24.3"}'

1 Comment

And it should be noted that requests json option includes the data in the body of the request rather than directly in the URI.
3

Maybe the problem is that json.dumps puts " and in the json you put in the url there are no "s. For example:

data = {'temperature':'24.3'}
print json.dumps(data)

prints:

{"temperature": "24.3"}

and not:

{temperature: 24.3}

like you put in your url.

One way of solving this (which is trouble prone) is to do:

json.dumps(data).replace('"', '')

2 Comments

Thank you for your reply. I've tested sending the request in the browser with the quotes around the key and values, and it still works ok. Main problem I seem to be having is that the apikey data is not being sent properly from my python script.
How about changing your code to this: params = urllib.urlencode({'apikey':'xxxxxxx', 'json':{'temperature':'24.3'}}) \ urllib2.urlopen(host + '?' + params)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.