0

I hope I can explain myself. with out making an arse of myself.

I am trying to use python 3.4 to send a url to a sparkcore api.

I have managed to use curl direcly from the windows command line:-

curl https://api.spark.io/v1/devices/xxxxxxxxxxxxxxx/led -d access_token=yyyyyyyyyyyyyyyy -d params=l1,HIGH

All works fine. there is a space between the led and -d, but that is not a problem.

I have read that reting to do this within python using libcurl is a big pain and I saw lots of messaged about using Requests, so I though I would give it a go.

So I wrote a small routine:

import requests

r = requests.get('https://api.spark.io/v1/devices/xxxxxxxxxxxxxxxxxx/led -d access_token=yyyyyyyyyyyyyyyyy -d params=l1,HIGH')
print(r.url)
print(r)

I get as return:

<Response [400]>

When I examine the URL which actually got sent out the spaces in the URL are replaced with %20. This seems to be my actual problem, because the %20 being added by requests are confusing the server which fails

"code": 400, "error": "invalid_request", "error_description": "The access token was not found"

I have tried reading up on how to inpractice have the spaces with out having a %20 being added by the encoding, but I really could do with a pointer in the right direction.

Thanks

Liam

6
  • 1
    Can you reword the question? I don't think your explanation is clear. Commented Sep 26, 2014 at 20:50
  • that %20 is the REST interpretation of a space character and it's how google reads it when you put a set of search terms in your url bar. urls don't have spaces in them. Why does yours? Commented Sep 26, 2014 at 20:55
  • I never actaully added the %20's I did use spaces in my url, and that worked fine with curl in the windows command line, If I copy and paste the identical url in to the Requests command the python script fails, and when I use print(r.url) the spaces are replaced by %20, in the responce I get back from Requests. Commented Sep 26, 2014 at 21:05
  • 1
    The url ends at led, starting at -d are options sent to curl. Requests expects the first argument to be only the url. Commented Sep 26, 2014 at 21:12
  • 1
    Actually it means POST xxxxxx to the url. Requests is very easy to use, for a post you just need to pass it a dictionary with your data. Commented Sep 26, 2014 at 21:37

1 Answer 1

1

URLs cannot have spaces. The curl command you are using is actually making a request to the url https://api.spark.io/v1/devices/xxxxxxxxxxxxxxx/led with some command line arguments (using -d)

The curl man (manual) page says this about the -d command line argument

-d, --data

(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.

-d, --data is the same as --data-ascii. To post data purely binary, you should instead use the --data-binary option. To URL-encode the value of a form field you may use --data-urlencode.

If any of these options is used more than once on the same command line, the data pieces specified will be merged together with a separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post chunk that looks like 'name=daniel&skill=lousy'.

If you start the data with the letter @, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a file named 'foobar' would thus be done with --data @foobar. When --data is told to read from a file like that, carriage returns and newlines will be stripped out.

So that says -d is for sending data to the URL with the POST request using the content-type application/x-www-form-urlencoded

The requests documentation has a good example of how to do that using the requests library: http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests

So for your curl command, I think this should work

import requests
payload = {'access_token': 'yyyyyyyyyyyyyyyy', 'params': 'l1,HIGH'}
r = requests.post("https://api.spark.io/v1/devices/xxxxxxxxxxxxxxx/led", data=payload)
print(r.text)
Sign up to request clarification or add additional context in comments.

1 Comment

Hi Ben, Thats it on the nail, thats what I was trying to do. Thanks. I had started to look at the payload option, but it was getting a bit fuzzy in my head, particularly as it was getting late. Also you comments detailing the inherit limitations of curl/urls (no spaces), brought things in to focus. Having a worked example has really pulled it together. Thanks again. Thats is answered nicely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.