X-WWW Put Request List inside of Dict - python

Attempting to write a put request in Python that keeps getting denied - the issue seems to be that the request isn't accepting the list as value for the dict.
Any suggestions on how I can get this to be accepted?
import requests
key = 'Bearer abc123'
url = 'www.my_url.com'
headers = {'Content-Type':'application/x-www-form-urlencoded',
'Accept':'application/json',
'Authorization':key}
data = {}
data['first_name']='John'
data['last_name']='Doe'
data['employee_job[roles]'] = [{'name':'CEO'}]
r = requests.put(url,data=data,headers=headers)

if the server accept put request,then the problem maybe json format
you could try this,put the data as json directly,not the form encoded.
need more information to detect the problem,can you provide the api document?
import requests
key = 'Bearer abc123'
url = 'www.my_url.com'
headers = {
'Accept':'application/json',
'Authorization':key}
data = {}
data['first_name']='John'
data['last_name']='Doe'
data['employee_job'] = {'roles':[{'name':'CEO'}]}
r = requests.put(url,json=data,headers=headers)

Related

Invalid API Key by using python to encode Key and using requests to GET some data

I try to acess data from an Exchange Platform with API.
I have my API_Key and my SECRET_KEY, and I have the documentation of that Platform here:
https://apidocs.exir.io/
I generate the "signature-key" just as described in the documentation under "Authentication" chapter and then try to test it with a sample GET request with only one parameter.
Now if I run the Code I get "message": "Access Denied: Invalid API Signature"
Can you please help me to find the wrong thing in this code?
I think I do something wrong with params because if I use other GET orders without parameters it works!
Thank you in advance!
import time
import json
import hmac
import hashlib
import requests
API_KEY = '*****'
SECRET_KEY = '*****'
BASE_URL = 'https://api.exir.io'
timestamp = str(int(time.time()+10))
headers = {
'api-key': API_KEY,
'api-expires': timestamp} # see documentation under "Authentication"
PATH = '/v1/user/orders' # This ist just a simple example, which uses "params". See Exir documentation under "Get All Orders"
params = {"symbol":"btc-irt"}
string = 'GET'+timestamp+str(params) # see Exir API doumentation under "Authentication"
headers['api-signature'] = hmac.new(SECRET_KEY.encode('utf-8'), string.encode('utf-8'), hashlib.sha256).hexdigest()
url = 'https://api.exir.io/v1/user/orders?symbol=btc-irt'
r = requests.get(url, headers=headers)
data = r.json()
print(json.dumps(data, indent=2))
A lot of what you are doing is unnecessary, actually. The requests library handles most of what you are trying to do.
import requests
API_KEY = '*****'
SECRET_KEY = '*****'
BASE_URL = 'https://api.exir.io'
timestamp = str(int(time.time()+10))
headers = {
'api-key': API_KEY,
'api-expires': timestamp
}
url = 'https://api.exir.io/v1/user/orders?symbol=btc-irt'
r = requests.get(url, headers=headers)
The library will do the encoding for you.
You mixed the post and get request parameters. For the get request, you only need to include the params in the URL to sign. In your case it will be:
PATH = '/v1/user/orders?symbol=btc-irt'
string = 'GET/' + PATH + timestamp

Getting an error with syntax getting a JSON file

I'm having a problem building a Twitter random quotes generator API. I'm following this tutorial:
https://www.twilio.com/blog/build-deploy-twitter-bots-python-tweepy-pythonanywhere
But I get an error that he doesn't have. This is the code:
import requests
api_key = '*****'
api_url = 'https://andruxnet-random-famous-quotes.p.rapidapi.com'
headers = {'afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc' :
api_key, 'http://andruxnet-random-famous-quotes.p.rapidapi.com' :
api_url}
# The get method is called when we
# want to GET json data from an API endpoint
quotes = requests.get(quotes = requests.get(api_url,
headers=headers)
print(quotes.json())
And this is the error:
File "twitter_bot.py", line 12
print(quotes.json())
SyntaxError: invalid syntax
What am I doing wrong?? (I put *** on the key on purpose, I know the proper key is supposed to go there)
Thank you!
You have a copy-and-paste error; somehow you've put quotes = requests.get( twice.
It should just be:
# The get method is called when we
# want to GET json data from an API endpoint
quotes = requests.get(api_url, headers=headers)
print(quotes.json())
Tutorial is not so old but it seems it is already out of date.
Using example from RapidAPI documentation (for Random Famous Quotes API) I created Python's code which gives some information from server (but still not quotes)
import requests
url = "https://andruxnet-random-famous-quotes.p.rapidapi.com/?count=10&cat=famous"
headers={
"X-RapidAPI-Host": "andruxnet-random-famous-quotes.p.rapidapi.com",
"X-RapidAPI-Key": "afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc",
}
quotes = requests.get(url, headers=headers)
print(quotes.text)
#print(quotes.json())
Result:
{"message":"You are not subscribed to this API."}
The same for POST
import requests
url = "https://andruxnet-random-famous-quotes.p.rapidapi.com/?count=10&cat=famous"
headers={
"X-RapidAPI-Host": "andruxnet-random-famous-quotes.p.rapidapi.com",
"X-RapidAPI-Key": "afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc",
"Content-Type": "application/x-www-form-urlencoded"
}
quotes = requests.post(url, headers=headers)
print(quotes.text)
#print(quotes.json())
Result:
{"message":"You are not subscribed to this API."}
It still need some work to get quotes.

API access to trading platform using Python

I'm new to getting data using API and Python. I want to pull data from my trading platform. They've provided the following instructions:
http://www.questrade.com/api/documentation/getting-started
I'm ok up to step 4 and have an access token. I need help with step 5. How do I translate this request:
GET /v1/accounts HTTP/1.1
Host: https://api01.iq.questrade.com
Authorization: Bearer C3lTUKuNQrAAmSD/TPjuV/HI7aNrAwDp
into Python code? I've tried
import requests
r = requests.get('https://api01.iq.questrade.com/v1/accounts', headers={'Authorization': 'access_token myToken'})
I tried that after reading this: python request with authentication (access_token)
Any help would be appreciated. Thanks.
As you point out, after step 4 you should have received an access token as follows:
{
“access_token”: ”C3lTUKuNQrAAmSD/TPjuV/HI7aNrAwDp”,
“token_type”: ”Bearer”,
“expires_in”: 300,
“refresh_token”: ”aSBe7wAAdx88QTbwut0tiu3SYic3ox8F”,
“api_server”: ”https://api01.iq.questrade.com”
}
To make subsequent API calls, you will need to construct your URI as follows:
uri = [api_server]/v1/[rest_operation]
e.g.
uri = "https://api01.iq.questrade.com/v1/time"
Note: Make sure you use the same [api_server] that you received in your json object from step 4, otherwise your calls will not work with the given access_token
Next, construct your headers as follows:
headers = {'Authorization': [token_type] + ' ' + [access_token]}
e.g.
headers = {'Authorization': 'Bearer C3lTUKuNQrAAmSD/TPjuV/HI7aNrAwDp'}
Finally, make your requests call as follows
r = requests.get(uri, headers=headers)
response = r.json()
Hope this helps!
Note: You can find a Questrade API Python wrapper on GitHub which handles all of the above for you.
https://github.com/pcinat/QuestradeAPI_PythonWrapper
Improving a bit on Peter's reply (Thank you Peter!)
start by using the token you got from the QT website to obtain an access_token and get an api_server assigned to handle your requests.
# replace XXXXXXXX with the token given to you in your questrade account
import requests
r = requests.get('https://login.questrade.com/oauth2/token?grant_type=refresh_token&refresh_token=XXXXXXXX')
access_token = str(r.json()['access_token'])
refresh_token= str(r.json()['refresh_token']) # you will need this refresh_token to obtain another access_token when it expires
api_server= str(r.json()['api_server'])
token_type= str(r.json()['token_type'])
api_server= str(r.json()['api_server'])
expires_in = str(r.json()['expires_in'])
# uri = api_server+'v1/'+[action] - let's try checking the server's time:
uri = api_server+'v1/'+'time'
headers = {'Authorization': token_type +' '+access_token}
# will look sth like this
# headers will look sth like {'Authorization': 'Bearer ix7rAhcXx83judEVUa8egpK2JqhPD2_z0'}
# uri will look sth like 'https://api05.iq.questrade.com/v1/time'
# you can test now with
r = requests.get(uri, headers=headers)
response = r.json()
print(response)

Using Python to test HTTP APIs

I'm fairly new to Python programming and I don't know all the libraries needed for the following.
I would like to use Python to test some HTTP APIs. Mainly I want to use OAuth and make a few JSON calls. The APIs in question can be found on: https://developers.trustpilot.com/authentication and the generate product review link (I can only use one link)
I want to authenticate myself and then generate a product review link in one step. So far I've been using the Advanced REST client (ARC) to make these calls individually. I could also use .arc files if you think it's easier.
The idea would be make these calls successively in one go. So it would be something along the lines:
1) Make the authentication call.
The HTTP Method looks like this:
https://api.trustpilot.com/v1/oauth/oauth-business-users-for-applications/accesstoken
Method Post:
Header
Authorization: Basic Base64encode(APIkey:Secret)
Content-Type: application/x-www-form-urlencoded
Payload:
grant_type=password&username=user#mail.com&password=SomePass
Translate this bit into Python basically.
1.a) Add a header to the call
Header Authorization: base64encode hash Content-Type: application/x-www-form-urlencoded
1.b) Add a payload to the call
Payload: grant_type=password&username
4) Receive the token from call made in step 1) (Result is format)
"access token": Auth_token
5) Take the token and use it in creating a product review.
5.a) Add the token in the header
Header: Authorization: Bearer Auth_token
6.a) Add a JSON payload to the call made in step 5.
Here's the code I have so far:
Import requests
header = {'Authorization: Basic NnNrQUprTWRHTU5VSXJGYXBVRGxack1oT01oTUFRZHI6QTFvOGJjRUNDdUxBTmVqUQ==}','Content-Type: application/x-www-form-urlencoded'}
payload = {'grant_type=password&username=email#address.com&password=SomePassword'}
r = requests.post('https://api.trustpilot.com/v1/oauth/oauth-business-users-for-applications/accesstoken', headers=header, params=payload )
Ideally I want to create the requests.post(url, header, payload) and then return what the server answers in JSON format. I think that print r.text would do the last part.
So this is the code I have writtent (that works now):
import requests
import getpass
import json
from requests.auth import HTTPBasicAuth
header = {'grant_type':'password' , 'username':'mail#maildomain.com', 'password':'YourPassword'}
username= "YOURAPIKEY" #APIKey
password= "YOURSECRET" #Secret
res = requests.post(
'URL/v1/oauth/oauth-business-users-for-applications/accesstoken',
auth=HTTPBasicAuth(username, password), # basic authentication
data=header)
#print(res.content) #See content of the call result.
data = res.json() # get response as parsed json (will return a dict)
auth_token = data.get('access_token')
requests can do all what you ask without any work from your part.
See the doc for authentication, parameters, json output, json input
Make the authentication call.
import requests
import getpass
from requests.auth import HTTPBasicAuth
username = raw_input('Username: ')
password = getpass.getpass('Password: ')
res = requests.post(
'https://api.trustpilot.com/v1/oauth/oauth-business-users-for-applications/accesstoken',
auth=HTTPBasicAuth(username, password), # basic authentication
params={ # url parameters
'grant_type': 'password',
'username': 'email#address.com',
'password': 'SomePassword'
})
Receive the token from call made in step 1) (Result is format)
# res = requests.post.....
data = res.json() # get response as parsed json (will return a dict)
auth_token = data.get('access token')
Take the token and use it in creating a product review.
request.post(
'.../product_review',
headers={
'Authorization': 'Bearer ' + auth_token
},
json={'my': 'payload'}) # send data as json

Python - Updating a JSON REST array

I am new to Python, what I am trying to do is write a script that will take the IP address I am supplying it and updating an array that I am pulling from a JSON RESTful API. I can pull the data out of the array fine. Here is what my code looks like so far(please excuse the look of the code)
import requests
import json
import sys
pool_name = sys.argv[1]
add_node = sys.argv[2]
url = 'https://<stingray RESTApi>:9070/api/tm/1.0/config/active/pools/' + pool_name
jsontype = {'content-type': 'application/json'}
client = requests.Session()
client.auth = ('<username>', '<password>')
client.verify = 0
response = client.get(url)
pools = json.loads(response.content)
nodes = pools['properties']['basic']['nodes']
Now I have been looking at using this
client.put(url, <I am stuck>, headers = jsontype)
At this point I have reached the limits of my current know how of Python(As I just started to learn on the last few days). I have looked at using something like this as well to get the data I have collected append to the array and then trying to PUT it.
updatepool['properties']['basic']['nodes'].append(add_node)
When I print updatepool, I see that what I am after is working but again PUTing it in the array has stumped me.
Any help would be really appreciated.
Thanks
UPDATE: Here is an update to my code, getting a 400 response from the API
#!/usr/bin/python
import requests
import json
import sys
pool_name = sys.argv[1]
#add_node = sys.argv[2]
add_node = u'10.10.10.1:80'
url = 'https://<uri>:9070/api/tm/1.0/config/active/pools/' + pool_name
jsontype = {'content-type': 'application/json'}
client = requests.Session()
client.auth = ('<username>', '<password')
client.verify = 0
response = client.get(url)
pools = json.loads(response.content)
nodes = pools['properties']['basic']['nodes']
data = nodes
data.append(add_node)
print client.put(url,json.dumps(data), headers=jsontype)
From the docs
print requests.put.doc
Sends a PUT request. Returns :class:Response object.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
so client.put(url, {'key':'value'}, headers = jsontype)
works.
what you need to know now is what key val that url is accepting: supposing it accepts a 'node' and key you could use
client.put(url, {'node':add_node}, headers = jsontype)
or
client.put(url, {'node':updatepool['properties']['basic']['nodes']**[0]**}, headers = jsontype)
to send first node
As per documentation
put(url, data=None, **kwargs)
Sends a PUT request. Returns Response object.
Parameters:
url – URL for the new Request object.
data – (optional) Dictionary, bytes, or file-like object to send in the body of the Request.
**kwargs – Optional arguments that request takes.
You can give 'dictwithlist` (array).

Categories

Resources