Api call using python and token_auth - python

"""
#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.

Related

Getting historical data from a wheniwork API

I'm retrieving shifts data from wheniwork API
My Python code:
import requests
wheniwork_url = 'https://api.login.wheniwork.com/login'
response = requests.post(
wheniwork_url,
headers = {
"W-Token": '98239akljfqdb3wu97982' #secret_token
"Content-Type": "application/json"},
json={"email": my_wheniwork_email, "password": my_wheniwork_password},
)
final_response = response.json()
token = final_response["token"]
headers = {"W-Token": token, "Content-Type": "application/json"}
users_url = "https://api.wheniwork.com/2/shifts"
res = requests.get(users_url, headers=headers)
output = res.json()
print(output)
I followed wheniwork shifts api documentation to get the shifts data but this is not giving me the historical data.
How/Where can I pass the date parameters in order to get the historical data.
There is start and end date but I'm not sure how to insert start and end date parameters in the API call

Requests lib changing characters to URL-encoded representation

I am trying to send a get request to an api that includes timestamps. The URL is getting changed and instead of : %253A is inserted and I get a 500 error code.
url = 'https://www.fleetTrackingSimplicity.com/REST6/api/vehiclehistory/2'
start = '2020-12-01T00:00:00Z'
end = '2020-12-02T00:00:00Z'
param = {'startdate': start, 'enddate': end, 'count':'500'}
r_auth = str(a_json['TransactionId'])
headers2 = dict (Authorization = r_auth, Accept = 'application/json')
r = requests.get(url, headers = headers2, params=param)
When I print r.url I get https://www.fleettrackingsimplicity.com/REST6/api/vehiclehistory/2?startdate=2020-12-01T00%253A00%253A00Z&enddate=2020-12-02T00%253A00%253A00Z&count=500

How can I make this API work with a payload?

I am using this API to list users. One of the parameters I could specify is a team id which is placed in an array. When I try to specify a team id it doesn't work when I put it in the payload, but it works when I change the url to include the team id.
This is the API reference: https://api-reference.pagerduty.com/#!/Users/get_users
Here is what I am basing my code off of: https://github.com/PagerDuty/API_Python_Examples/blob/master/REST_API_v2/Users/list_users.py
This is my code when I try to specify team id in the payload. It doesn't work like this for some reason, but it works when I change the url to url = 'https://api.pagerduty.com/users?team_ids%5B%5D=TEAMID&team_ids%5B%5D=' where in TEAMID I have an actual team id.
with open('config/config.json') as f:
config = json.load(f)
API_KEY = config['API_KEY']
TEAM_IDS = ['TEAMID']
def list_users():
url = 'https://api.pagerduty.com/users'
headers = {
'Accept': 'application/vnd.pagerduty+json;version=2',
'Authorization': 'Token token={token}'.format(token=API_KEY)
}
payload = {
'team_ids[]': TEAM_IDS
}
r = requests.get(url, headers=headers)
result = []
if r.status_code == 200:
# loops for each user and retrieves their email
result = [user['email'] for user in r.json()['users']]
return result
else:
return None
I want to get this work by listing team id's in the array and sending it in the payload so that I can list more than one team id and not clutter them all in the url.
Looks like you just need something like this
payload = {
'team_ids[]': TEAM_IDS
}
r = requests.get(url, headers=headers, params=payload)

How do I perform oauth2 for Sabre Dev Network using python?

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

oauth1, rsa-sha1, header params

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)

Categories

Resources