How to use Python format function in this case - python

I need to send a request through a link. The following link works and could return what I need:
response = requests.get(
"""https://pangeare.freshservice.com/api/v2/assets?include=type_fields&filter="updated_at:>%272022-10-09%27"&page="""+ str(page),
auth = ('xxxxxxxxx', ''),
headers = headers
)
You could see that the updated_at filter is hard coded into the url. If I try to use format function to fill the updated_at value, it will return 400
response = requests.get(
"""https://pangeare.freshservice.com/api/v2/assets?include=type_fields&filter="updated_at:>{0}"&page=""".format('2022-10-09') + str(page),
auth = ('xxxxxxxxxxxx', ''),
headers = headers
)
What is the appropriate way to use format function in this case?

The pythonic way to do this whole operation would be to use the params option
You can also use f-strings instead of .format().
BASE_URL_PATH = "https://pangeare.freshservice.com/api/v2/assets"
date_str = "2022-10-09"
response = requests.get(
BASE_URL_PATH,
params={
"include": "type_fields",
"filter": f"\"updated_at:>%27{date_str}%27\"",
"page": page,
}
auth = ('xxxxxxxxxxxx', ''),
headers = headers
)

Related

Passing variable in python request URL not working

def get_prod():
name = input('Search Query:\n')
params = {
'page': '1',
'perPage': '20',
'query': name,
}
response = requests.get('https:///api/public/search', params=params, headers=headers)
response = response.json()
id = response['results'][0]['id']
print(id)
prod_data = requests.get('https:///api/public/products/{id}', headers=headers)
print(prod_data.text)
get_prod()
from the public API Search I am returning a valid ID but when the prod_data get request returns the error {"message":"Couldn't find Product with 'id'={id} [WHERE \"products\".\"deleted_at\" IS NULL]"} implying to me that it's not using that variable I can print. When I put a standard finite ID the request works but I'm sure why this won't
Seems like the variable value is not getting printed. Unless I'm missing something.
You need a f before the string if you're going with this method; f-strings.
prod_data = requests.get(f'https:///api/public/products/{id}', headers=headers)
These might help: https://matthew-brett.github.io/teaching/string_formatting.html

Api call using python and token_auth

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

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 to preserve the Ascii encoding type with the POST request in Python?

How do I send the ASCII encoded text via POST request in Python? The length of true_input I received via the POST is always different from the length I sent.
def insert_true_input(level, iteration, true_input):
url = master_url + "/insert_true_input?"
data = {'level': level, 'iteration': iteration, 'true_input': true_input}
headers = {'Content-Type': 'text/plain'}
res = requests.post(url, params=data, headers=headers).text
return res
The sample true_input that I want to send is directly from numpy.ndarray.tostring() and looks like
'\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x08#\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x007#\x00\x00\x00\x00\x00\xc0^#\x00\x00\x00\x00\x00\xc0^#\x00\x00\x00\x00\x00\xc0^#\x00\x00\x00\x00\x00\x00(#\x00\x00\x00\x00\x00\x00?#'
As explained in the comments, the null characters \x00 are not sendable in raw text. You have to encode them one way or another (URL encoded, Base64, json, etc.). But then the other side that will receive the request must be adapted to decode them accordingly.
Actually requests will use URL encoding automatically for the parameters passed in the query string, but I suspect that your java code is not able to decode them properly.
Please post your Java code for the receiving side to see what we can do.
Suggestions on python side, using base64:
import base64
def insert_true_input(level, iteration, true_input):
url = master_url + "/insert_true_input?"
data = {'level': level, 'iteration': iteration, 'true_input': base64.b64encode(true_input)}
res = requests.post(url, params=data, headers=headers).text
return res
Using json (requests will do the work for you if you use the json parameter to .post()):
def insert_true_input(level, iteration, true_input):
url = master_url + "/insert_true_input?"
data = {'level': level, 'iteration': iteration, 'true_input': true_input}
res = requests.post(url, json=data, headers=headers).text
return res
You have to encode your string using str.encode('ascii'):
def insert_true_input(level, iteration, true_input):
url = master_url + "/insert_true_input?"
data = {'level': level, 'iteration': iteration, 'true_input': true_input.encode('ascii')}
headers = {'Content-Type': 'text/plain'}
res = requests.post(url, params=data, headers=headers).text
return res

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