Job Requests and URLFetch not

I am trying to make a request for particle servers in python on a google apps app.

In my terminal, I can execute a request simply and successfully with requests like:

res = requests.get('https://api.particle.io/v1/devices', params={"access_token": {ACCESS_TOKEN}})

      

But in my app the same thing doesn't work with urlfetch, which keeps telling me that it can't find the access token:

    url = 'https://api.particle.io/v1/devices'
    payload = {"access_token": {ACCESS_TOKEN}}
    form_data = urllib.urlencode(payload)
    res = urlfetch.fetch(
        url=url,
        payload=form_data,
        method=urlfetch.GET,
        headers={
            'Content-Type':
            'application/x-www-form-urlencoded'
        },
        follow_redirects=False 
    )

      

I have no idea what the problem is and there is no way to debug. Thank!

+3


source to share


2 answers


In short, your problem is that in your example, urlfetch

you are inserting your access token into the request body, and since you are sending a GET request that cannot carry the request body, this information is discarded.

Why does your first snippet work?

Since it requests.get()

takes an optional argument params

which means "take this dictionary I give you, convert all of its key / value pairs to a query string and add it to the main url"

So, behind the curtains, it requests.get()

builds a line like this:

https://api.particle.io/v1/devices?access_token=ACCESS_TOKEN

For the correct endpoint, you must specify your GET requests.

Why is your second snippet not working?



This time urlfetch.fetch()

uses a different syntax than requests.get()

(but equivalent nonetheless). It is important to note that argument payload

does not mean the same as our argument params

you used earlier in requests.get()

.

urlfetch.fetch()

expects our query string if any else is urlencoded in the url (which is why urllib.urlencode()

it comes into play here). On the other hand, payload

this is where you should put the request body in case you send a POST, PUT, or PATCH request, but the particle.io endpoint is not expecting your OAuth access token.

Something like this should work (disclaimer: not tested):

auth = {"access_token": {ACCESS_TOKEN}}
url_params = urllib.urlencode(auth)
url = 'https://api.particle.io/v1/devices?%s' % url_params

res = urlfetch.fetch(
    url=url,
    method=urlfetch.GET,
    follow_redirects=False 
)

      

Please note that now we no longer need your previous title Content-type

, as we still do not transfer content. Therefore, the parameter headers

can be removed from this call example.

For more information, see the urlfetch.fetch()

link and this SO thread , which will hopefully give you a better understanding of HTTP methods, parameters and request bodies than my poor explanation here.

PS: If particle.io servers support it (they should) you should drop this authentication scheme and move your tokens to the header Authorization: Bearer <access_token>

. It is not a good idea to carry access tokens in URLs because they are much more visible this way and tend to stay on the server, which poses a security risk. On the other hand, in a TLS session, all request headers are always encrypted, so your authentication tokens are well hidden.

+10


source


So, as it turns out, you cannot include the payload for a GET request using Urlfetch. Instead, you need to include the parameters in the url using '?' the syntax is as follows:

url = 'https://api.particle.io/v1/devices'
url = url + '?access_token=' + {ACCESS_TOKEN}
res = urlfetch.fetch(
    url=url,
    method=urlfetch.GET,
    follow_redirects=False 
)

      



it worked for me.

0


source







All Articles