I have been using requests-oauthlib, which do have rsa-sha1 signature algorithm, but there can't seem to be a way to add extra params to the authorization header, and if i do modify the header manually before making the request i get
"The request contains an incomplete or invalid oauth_signature."
because it had already created the oauth_signature when i have added the new oauth_body_hash to the authorization header.
i have pasted the code, the first call using oauth passes correctly, but the second one is giving the error.
any possible way to workaround this ? another library that has both options to add extra params and provide rsa-sha1 signature ?
oauth = OAuth1(
consumer_key,
signature_method='RSA-SHA1',
signature_type='auth_header',
rsa_key=key,
callback_uri=callback_uri
)
oauth.client.realm = 'eWallet'
r = requests.post(url=request_token_url, auth=oauth)
credentials = parse_qs(r.content)
# end of request
# post shopingcart
root = ET.fromstring(shopping_cart_xml)
root.find('OAuthToken').text = credentials['oauth_token'][0]
xml = ET.tostring(root, encoding="us-ascii", method="xml")
sha1 = hashlib.sha1()
sha1.update(xml)
oauth_body_hash = sha1.digest()
oauth_body_hash = base64.b64encode(oauth_body_hash)
oauth.client.oauth_body_hash = oauth_body_hash
req = Request('POST', shopping_cart_url, data=xml, auth=oauth)
prepped = req.prepare()
auth_header = prepped.headers['Authorization'] + ', oauth_body_hash="%s"' % (oauth_body_hash)
headers = {'Content-Type': 'application/xml', 'Authorization': auth_header}
r = requests.post(url=shopping_cart_url, headers=headers, data=xml)
Related
I'm finding the Kraken Futures API confusing compared to other providers. Using a demo account I'm trying to make basic private requests and not working so far with authentication error. The code mainly comes from Kraken docs (non-futures)
Futures auth doc: https://support.kraken.com/hc/en-us/articles/360022635592-Generate-authentication-strings-REST-API-
api_sec = "MxA2FwIQxCxsfy2XDa4R8PwTjwLKjzT8GSOw+qOVuWGh3Lx6PtyW0f94J5XXKz9mP8bztRJSDQJVKBsHFicrDr/N"
api_url = "https://futures.kraken.com/derivatives/api/v3"
api_key = 'Y7kVv/hW0JWRRAhJtA8BuJkUX+E0gWmTL5NWf4lRPN8f+iYoJp9AoYwW'
def get_kraken_signature(urlpath, data, secret):
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()
message = urlpath.encode() + hashlib.sha256(encoded).digest()
mac = hmac.new(base64.b64decode(secret), message, hashlib.sha256)
sigdigest = base64.b64encode(mac.digest())
return sigdigest.decode()
# Attaches auth headers and returns results of a get request
def kraken_request(uri_path, data, api_key, api_sec):
headers = {}
headers['API-Key'] = api_key
# get_kraken_signature() as defined in the 'Authentication' section
headers['API-Sign'] = get_kraken_signature(uri_path, data, api_sec)
req = requests.get((api_url + uri_path), headers=headers, data=data)
return req
# Construct the request and print the result
resp = kraken_request('/accounts', {
"nonce": str(int(1000*time.time()))
}, api_key, api_sec)
Output
{"result":"error","error":"authenticationError","serverTime":"2022-05-13T10:14:50.838Z"}
"""
#Collects basic metrics from Matomo installation and returns a pandas dataframe
"""
token = os.getenv("token")
# Build url string
base_url = 'https://matomo.___.com/index.php?module=API'
site_num = '&idSite=1'
return_format = '&format=json'
period = '&period=day'
date_range = '&date=last30'
method = '&method=VisitsSummary.get'
token_string = "&token_auth=" + token
my_url = base_url + site_num + return_format + period + date_range + method + token_string
# send request for report
r = requests.get(my_url)
# parse and tidy collected data
data = pd.DataFrame(r.json()).T
data = data.reset_index()
data.columns = [
"date",
"uniq_visitors",
"users",
"visits",
"actions",
"visits_converted",
"bounces",
"sum_visit_length",
"max_actions",
"bounce_rate",
"actions_per_visit",
"avg_time_on_site",
]
return data
I am trying to get data from the matomo API using an auth_token and parameters by using above code but i am not able to access it and my url is not taking token code any one has idea how i can solve this
Given that you are using the request library, passing parameters and headers can be done using the following params in your get call:
r = requests.get(my_url, params=payload)
In the same way, an auth token is usually passed within headers:
r = requests.get(my_url, params=payload, headers=headers)
Using this format you can simply create a headers object which contains your token_auth and directly pass your parameters in a payload object:
headers = {'token_auth': token}
payload = {'module':'API', 'idSite':1, 'format':'json', 'period':'day', 'date':'last30', 'method':'VisitsSummary.get'}
Since you are now passing your parameters in you get request, there is no need to add them to the end of your url. Thus, your url should stay as https://matomo.___.com/index.php. These can then be used within your params and headers respectively. Please note that this assumes that the matomo API places the token_auth in its headers such as most APIs do. If this is not the case you could pass it directly within the params payload.
Here is a global overview:
token = os.getenv("token")
# Get url, headers and params
my_url = 'https://matomo.___.com/index.php'
payload = {'module':'API', 'idSite':1, 'format':'json', 'period':'day', 'date':'last30', 'method':'VisitsSummary.get'}
headers = {'token_auth': token}
# send request for report
r = requests.get(my_url, params=payload, headers=headers)
Note this answers your question specifically regarding the API call and not the processing after.
I am trying to read out out some of my stats from chess.com. I am struggling to log in with python.
I am trying to follow the tutorial here
I have identified the following tags from the login-page. _username as the username, _password as the password and _token as the hidden token.
My code:
session_requests = requests.session()
login_url = 'https://www.chess.com/login'
result = session_requests.get(login_url)
tree = html.fromstring(result.text)
token = list(set(tree.xpath("//input[#name='_token']/#value")))[0]
payload = {
"_username": "ChristianSloper",
"_password": "mypasswordgoeshere",
"_token": token
}
result = session_requests.post( login_url, data = payload, headers = dict(referer=login_url), verify=True)
Unfortunately, I just get sent back to the login page. I am very new to front end /web and would be very pleased for any help.
your payloads aren't entirely correct (there are a few things missing in it) and it appears that you are sending the POST request to the wrong URL, try this code:
session_requests = requests.session()
login_url = 'https://www.chess.com/login'
result = session_requests.get(login_url)
tree = html.fromstring(result.text)
token = list(set(tree.xpath("//input[#name='_token']/#value")))[0]
payload={"_username": "ChristianSloper",
"_password": "mypasswordgoeshere",
"login": '',
"_target_path": "https://www.chess.com/home",
"_token": token
}
session_requests.headers.update(dict(referer=login_url))
result = session_requests.post("https://www.chess.com:443/login_check", data = payload, verify=True)
Hope this helps!
I'm trying to send a string array to the bing translate api, which I have received and encoded as UTF-8.
However, when I make the call with the variable the service spits out an error:
"There was an error deserializing the object of type System.String[]. Encountered unexpected character 'ï'."
If I manually add the string array as a string not within a variable, it works. I'm using the Requests module, so I'm thinking it's encoding the url... I have no idea.
class getLanguages(apiFunctions):
def GET(self):
#get the access token
data = self.accessToken()
token = data['access_token']
codes = self.getCodes(token)
languageNames = self.getLanguageNames(token,codes)
codesList = ast.literal_eval(codes)
return languageNames + codes
def getCodes(self,token):
url = 'http://api.microsofttranslator.com/V2/Ajax.svc/GetLanguagesForTranslate'
auth_header = {'Authorization': 'Bearer ' + token}
r = requests.get(url, headers=auth_header)
return r.text.encode('utf-8')
def getLanguageNames(self,token,codes):
url = 'http://api.microsofttranslator.com/V2/Ajax.svc/GetLanguageNames'
#this is where I add the language codes string to the query
payload = {'locale': 'en', 'languageCodes': codes}
auth_header = {'Authorization': 'Bearer ' + token}
r = requests.post(url, params=payload, headers=auth_header)
return r.text.encode('utf-8')
And this is the string:
["ar","bg","ca","zh-CHS","zh-CHT","cs","da","nl","en","et","fi","fr","de","el","ht","he","hi","mww","hu","id","it","ja","tlh","tlh-Qaak","ko","lv","lt","ms","mt","no","fa","pl","pt","ro","ru","sk","sl","es","sv","th","tr","uk","ur","vi","cy"]
I am trying to get an authentication token from the Sabre Dev Studio. I am following the generic directions given here https://developer.sabre.com/docs/read/rest_basics/authentication(need to login to view) but I cannot figure out how to obtain a token using Python - specifically using the python-oauth2 library as it seems to be recommended to simplify the process.
Here's a sample of my code:
config = ConfigParser.ConfigParser()
config.read("conf.ini")
clientID = config.get('DEV', 'Key').strip()
clientSecret = config.get('DEV', 'SharedSecret').strip()
consumer = oauth.Consumer(key=base64.b64encode(clientID),
secret=base64.b64encode(clientSecret))
# Request token URL for Sabre.
request_token_url = "https://api.sabre.com/v1/auth/token"
# Create our client.
client = oauth.Client(consumer)
# create headers as per Sabre Dev Guidelines https://developer.sabre.com/docs/read/rest_basics/authentication
headers = {'Content-Type':'application/x-www-form-urlencoded'}
params = {'grant_type':'client_credentials'}
# The OAuth Client request works just like httplib2 for the most part.
resp, content = client.request(request_token_url, "POST", headers=headers)
print resp
print content
The response is a type 401. Where the credentials are incomplete or misformed.
Any suggestions appreciated.
I could not with oauth2, but I did with requests package I think you can get it from here
My code is:
import requests
import base64
import json
def encodeBase64(stringToEncode):
retorno = ""
retorno = base64.b64encode(stringToEncode)
return retorno
parameters = {"user": "YOUR_USER", "group": "YOUR_GROUP", "domain": "YOUR_DOMAIN", "password": "YOUR_PASSWORD"}
endpoint = "https://api.test.sabre.com/v1"
urlByService = "/auth/token?="
url = endpoint + urlByService
user = parameters["user"]
group = parameters["group"]
domain = parameters["domain"]
password = parameters["password"]
encodedUserInfo = encodeBase64("V1:" + user + ":" + group + ":" + domain)
encodedPassword = encodeBase64(password)
encodedSecurityInfo = encodeBase64(encodedUserInfo + ":" + encodedPassword)
data = {'grant_type':'client_credentials'}
headers = {'content-type': 'application/x-www-form-urlencoded ','Authorization': 'Basic ' + encodedSecurityInfo}
response = requests.post(url, headers=headers,data=data)
print "Post Request to: " + url
print response
print "Response Message: " + response.text
Regards,
First get your credentials:
Register in https://developer.sabre.com/member/register
Sign in into https://developer.sabre.com
Go to https://developer.sabre.com/apps/mykeys and get your credentials. They should look like this (where spam and eggs will look like garbage):
client_id = 'V1:spam:DEVCENTER:EXT'
client_secret = 'eggs'
Then call the /v2/auth/token endpoint in order to get an access token:
import requests
credentials = ":".join([part.encode('base64').strip()
for part in (client_id, client_secret)]
).encode('base64').strip()
url = 'https://api.test.sabre.com/v2/auth/token'
headers = {'Authorization': 'Basic ' + credentials}
params = {'grant_type': 'client_credentials'}
r = requests.post(url, headers=headers, data=params)
assert r.status_code is 200, 'Oops...'
token = r.json()
print(token)
You should get something like this:
{u'access_token': u'T1RLAQJwPBoAuz...x8zEJg**',
u'token_type': u'bearer',
u'expires_in': 604800}
Now you can call others endpoints using an Authorization header containing your access token. For example, if you want the list of supported countries:
headers = {'Authorization': 'Bearer ' + token[u'access_token']}
endpoint = 'https://api.test.sabre.com/v1/lists/supported/countries'
r = requests.get(endpoint, headers=headers)
assert r.status_code is 200, 'Oops...'
print (r.json())
If everything went well, you should receive the list of supported countries:
{u'DestinationCountries': [
{u'CountryName': u'Antigua And Barbuda', u'CountryCode': u'AG'},
{u'CountryName': u'Argentina', u'CountryCode': u'AR'},
{u'CountryName': u'Armenia', u'CountryCode': u'AM'},
{u'CountryName': u'Aruba', u'CountryCode': u'AW'},
...
}
I'm pretty sure you're using this oauth library: https://pypi.python.org/pypi/oauth2 Despite being named "oauth2" it does not implement the OAuth 2 specification. Here is the best library I could find that provides OAuth 2 support and has documentation: http://requests-oauthlib.readthedocs.org/en/latest/oauth2_workflow.html