Retrieve the access token from POST request and use in GET request - python

I am using the requests library to make a POST request in order to obtain an access token. My request works properly, but, I'm not sure how to extract it and then use it in a GET request.
url = 'https://login.insideview.com/Auth/login/v1/token'
payload = {'clientId' : '****', 'clientSecret' : '****','grantType':'cred'}
headers = { 'Accept' : 'application/json'}
r = requests.post(url, headers=headers, params=payload)
solution:
data = json.loads(r.text)
data['accessTokenDetails']['accessToken']
Returns:
{"accessTokenDetails":{"accessToken":"the_access_token","tokenType":"bearer","expirationTime":"Fri, Mar 25, 2016 09:59:53 PM GMT","userInfo":{"userId":null,"firstName":null,"lastName":null,"userName":null,"companyName":null,"accountId":null,"role":null}}}

If it returns a dict, why not just access its contents as usual?
token = r['accessTokenDetails']['accessToken']

#michael-queue the response from the request to a JSON endpoint is a JSON encoded string. To load it into a dictionary and access inner properties it's needed to json.loads(json_string) into Python. For the opposite operation, to dump a dictionary into a JSON string is json.dumps(dictionary) instead.

Related

Problem on performing CRUD operation using Django REST API

Hey I am new to Django Rest Framework.I have recently created REST API name "api/studentapi" using django REST framework in local host. The CRUD operation works perfectly fine in browseable API. But When I try to access the same API from third party python file, I am not able to perform POST operation although I am able to perform GET operation.While performing POST operation the server reponse me as "Unsupported Media Type: /api/studentapi/".I am posting series of code images so that the stuffs gets more clear
The third party python app that I have created to access the "api/studentapi"
The file structure of my project
The model form that I have created
The serializer files that I have created
The urls code
And Finally the view file
Make sure you a passing the content type header during your post and put request, as that's how django_rest_framework understands which parser it will use. The Django rest framework supports content type of form-data, JSON, x-www-form-urlencoded and multipart out of the box.
If you're sending JSON data add the header to your request:
Content-Type: application/json
If you send form data or file(s) add the header:
Content-Type: multipart/form-data
If you're sending only form data use:
Content-Type: application/x-form-urlencoded
For your code this is how to add the header
r = request.post(
url=URL,
data=json_data,
headers= {
'Content-Type': 'application/json'
}
)
TL;DR:
You need to pass the payload as json argument in requests.post:
data = {
"name": "sa",
"roll": 1,
"city": "lam"
}
r = requests.post(url=URL, json=data)
Details:
As stated in the official documentation of requests library:
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))
Please note that the above code will NOT add the Content-Type header
(so in particular it will NOT set it to application/json).
If you need that header set and you don’t want to encode the dict
yourself, you can also pass it directly using the json parameter
(added in version 2.4.2) and it will be encoded automatically:
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, json=payload)
import json
import requests
url = "https://127.0.0.1:8000/api/studentapi/"
data_response = {
"name": "sa",
"roll": 1,
"city": "lam"
}
data_json = json.dumps(data_response)
req = requests.post(url, data=data_json)

Problem sending post requests to spotify api in python

def queue_song(session_id):
song_uri='spotify:track:5RwV8BvLfX5injfqYodke9'
tokens = get_user_tokens(session_id)
headers = {'Content-Type': 'application/json',
'Authorization': "Bearer " + tokens.access_token,
}
url = BASE_URL +'player/queue'
data={
'uri':song_uri
}
response = requests.post(url,headers=headers,data=data).json()
print(response)
Output:
{'error': {'status': 400, 'message': 'Required parameter uri missing'}}
https://developer.spotify.com/documentation/web-api/reference/#/operations/add-to-queue
I dont thing there is any problem with auth tokens... coz 'GET' requests are working fine
By default, using data= in requests.post() sets the content type to application/x-www-form-urlencoded which makes the body a akin to a HTTP form request.
Spotify's API is JSON based, so your data needs to be a valid json data.
You can do it in 2 ways:
response = requests.post(url,headers=headers,data=json.dumps(data)).json()
Or, more simply:
response = requests.post(url,headers=headers,json=data).json()
and in this way you don't need to manually set the application/json header as well.
Edit:
After going through the API docs you linked, there's more wrong with the call you're making.
You're sending the parameters in data - which is the body of the request. But Spotify API specifies the parameters need to be put in the Query i.e. the query string of the URI. Which means your request should be:
response = requests.post(url,headers=headers,params=data).json() # set query string not body

Passing both dict and json to a url

I have to use a webservice endpoint that needs both JSON and non-json in the query and I don't know how to do it with the requests package. the same code provided has http.client in it, and I don't have access to that package in this project for unrelated reasons
The example code is:
import http.client
conn=http.client.HTTPSConnection('some.url')
payload="{\"some_json_dict_key\": \"some_json_dict_value\"}"
headers={'content-type': "application/json", 'accept': "application/json"}
conn.request("POST", "/someEndpoint?param1=value_of_param1", payload, headers)
res = conn.getresponse()
data = res.read().decode('utf-8')
The code i have tried which doesnt work:
import requests
headers={'content-type': "application/json", 'accept': "application/json"}
params={'param1': 'value_of_param1'}
json_payload = "{\"some_json_dict_key\": \"some_json_dict_value\"}"
url = 'https://some.url/someEndpoint'
response = requests.post(url, headers=headers, data=params, json=json_payload)
however that doesn't seem to work i get the exception
{'httpMessage': 'Bad Request', 'moreInformation': 'The body of the request, which was expected to be JSON, was invalid, and could not be decoded. The start of an object { or an array [ was expected.'}
According to the documentation:
Instead of encoding the dict yourself, you can also pass it directly using the json parameter (added in version 2.4.2) and it will be encoded automatically:
>>> url = 'https://api.github.com/some/endpoint'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)
but you're passing a string into the json parameter (I admit that the error message could be clearer). All other parameters are json/dict objects. Make json_payload an actual dictionary.
json_payload = {"some_json_dict_key": "some_json_dict_value"} # real dictionary, not a json string
url = 'https://some.url/someEndpoint'
response = requests.post(url, headers=headers, data=params, json=json_payload)
You must realize that a POST request can pass information in two places: In the body (data) of the request, and in the URL string (the request parameters, like a GET request does). In the example you didn't fully emulate, the parameters are in the URL string, and the body, according to the error message you got back, must consist of a single JSON object. Therefore, use the params dictionary for the URL parameters, like this:
response = requests.post(url, headers=headers, params=params, data=json_payload)
That ought to do it, unless there are other details to take care of.

How to call an API using Python Requests library

I can't figure out how to call this api correctly using python urllib or requests.
Let me give you the code I have now:
import requests
url = "http://api.cortical.io:80/rest/expressions/similar_terms?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = {"positions":[0,6,7,29]}
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.get(url, params=params, headers=headers)
# Print the content of the response
print(response.content)
I've even added in the rest of the parameters to the params variable:
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False,
"positions":[0,6,7,29]}
I get this message back:
An internal server error has been logged # Sun Apr 01 00:03:02 UTC
2018
So I'm not sure what I'm doing wrong. You can test out their api here, but even with testing I can't figure it out. If I go out to http://api.cortical.io/, click on the Expression tab, click on the POST /expressions/similar_terms option then paste {"positions":[0,6,7,29]} in the body textbox and hit the button, it'll give you a valid response, so nothing is wrong with their API.
I don't know what I'm doing wrong. can you help me?
The problem is that you're mixing query string parameters and post data in your params dictionary.
Instead, you should use the params parameter for your query string data, and the json parameter (since the content type is json) for your post body data.
When using the json parameter, the Content-Type header is set to 'application/json' by default. Also, when the response is json you can use the .json() method to get a dictionary.
An example,
import requests
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False
}
data = {"positions":[0,6,7,29]}
r = requests.post(url, params=params, json=data)
print(r.status_code)
print(r.json())
200
[{'term': 'headphones', 'df': 8.991197733061748e-05, 'score': 4.0, 'pos_types': ['NOUN'], 'fingerprint': {'positions': []}}]
So, I can't speak to why there's a server error in a third-party API, but I followed your suggestion to try using the API UI directly, and noticed you're using a totally different endpoint than the one you're trying to call in your code. In your code you GET from http://api.cortical.io:80/rest/expressions/similar_terms but in the UI you POST to http://api.cortical.io/rest/expressions/similar_terms/bulk. It's apples and oranges.
Calling the endpoint you mention in the UI call works for me, using the following variation on your code, which requires using requests.post, and as was also pointed out by t.m. adam, the json parameter for the payload, which also needs to be wrapped in a list:
import requests
url = "http://api.cortical.io/rest/expressions/similar_terms/bulk?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = [{"positions":[0,6,7,29]}]
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.post(url, json=params, headers=headers)
# Print the content of the response
print(response.content)
Gives:
b'[[{"term":"headphones","df":8.991197733061748E-5,"score":4.0,"pos_types":["NOUN"],"fingerprint":{"positions":[]}}]]'

How to use an auth token and submit data using Python requests.POST?

Using WheniWork's api, I need to use a token for authentication, and I also need to send data to create a new user. Does the order or name of arguments I send with requests.post() matter?
If I'm just using GET to pull information, I can have the url contain the thing I'm looking for, and then send a payload that is the token. For example:
url = 'https://api.wheniwork.com/2/users/2450964'
payload = {"W-Token": "ilovemyboss"}
r = requests.get(url, params=payload)
print r.text
When I try to add a new user however, I'm either not able to authenticate or not passing the data correctly. The api reference shows this format for using cURL:
curl https://api.wheniwork.com/2/users --data '{"first_name":"FirstName", "last_name": "LastName", "email": "user#email.com"}' -H "W-Token: ilovemyboss"
Here's what I've written out in python (2.7.10) using Requests:
url = 'https://api.wheniwork.com/2/users'
data={'first_name':'TestFirst', 'last_name': 'TestLast','email':'test#aol.com'}
params={"W-Token": "ilovemyboss"}
r = requests.post(url, data=data, params=params)
print r.text
Can someone explain if/how data(the user) gets sent separately from authentication(the token)?
I found the issue!
The data (user dict) needs to be in quotes. I'm not sure if their API is expecting a string, or if that's how requests works, or what. But here's the solution:
url = 'https://api.wheniwork.com/2/users'
data = "{'first_name':'TestFirst', 'last_name': 'TestLast','email':'test#aol.com'}"
params = {"W-Token": "ilovemyboss"}
r = requests.post(url, data=data, params=params)
print r.text
We can solve the above problem by converting the data dictionary to JSON string by using json.dumps.
data={'first_name':'TestFirst', 'last_name': 'TestLast','email':'test#aol.com'}
r = requests.post(url, data=json.dumps(data), params=params)
print r.text

Categories

Resources