Passing variable in python request URL not working - python

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

Related

How to use Python format function in this case

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
)

Roblox Purchasing an item from catalog

I have written a script that should purchase an asset from catalog.
import re
from requests import post, get
cookie = "blablabla"
ID = 1562150
# getting x-csrf-token
token = post("https://auth.roblox.com/v2/logout", cookies={".ROBLOSECURITY": cookie}).headers['X-CSRF-TOKEN']
print(token)
# getting item details
detail_res = get(f"https://www.roblox.com/library/{ID}")
text = detail_res.text
productId = int(get(f"https://api.roblox.com/marketplace/productinfo?assetId={ID}").json()["ProductId"])
expectedPrice = int(re.search("data-expected-price=\"(\d+)\"", text).group(1))
expectedSellerId = int(re.search("data-expected-seller-id=\"(\d+)\"", text).group(1))
headers = {
"x-csrf-token": token,
"content-type": "application/json; charset=UTF-8"
}
data = {
"expectedCurrency": 1,
"expectedPrice": expectedPrice,
"expectedSellerId": expectedSellerId
}
buyres = post(f"https://economy.roblox.com/v1/purchases/products/{productId}", headers=headers,
data=data,
cookies={".ROBLOSECURITY": cookie})
if buyres.status_code == 200:
print("Successfully bought item")
The problem is that it somehow doesn't purchase any item with error 500 (InternalServerError).
Someone told me that if I add json.dumps() to the script it might work.
How to add json.dumps() here (I don't understand it though I read docs) and how to fix this so the script purchases item?
Big thanks to anyone who can help me.
Import the json package.
json.dumps() converts a python dictionary to a json string.
I'm guessing this is what you want.
buyres =
post(f"https://economy.roblox.com/v1/purchases/products/{productId}",
headers=json.dumps(headers),
data=json.dumps(data),
cookies={".ROBLOSECURITY": cookie})
I found the answer finally, I had to do it like this:
dataLoad = json.dumps(data)
buyres = post(f"https://economy.roblox.com/v1/purchases/products/{productId}", headers=headers,
data=dataLoad,
cookies={".ROBLOSECURITY": cookie})

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 convert dict to string in concatenation?

I have python dictionary class that is generated from API call returning below result
{'url': 'https://propertypro.zendesk.com/api/v2/tickets/4249.json',
'id': 4249,
'external_id': None}
{'url': 'https://propertypro.zendesk.com/api/v2/tickets/4089.json',
'id': 4089,
'external_id': None}
the code as follow;
from urllib.parse import urlencode
import requests
credentials = 'some email', 'some password'
session = requests.Session()
session.auth = credentials
params = {
'query': 'type:ticket tags:test_python',
'sort_order': 'asc'
}
url = 'https://propertypro.zendesk.com/api/v2/search.json?' + urlencode(params)
response = session.get(url)
if response.status_code != 200:
print('Status:', response.status_code,
'Problem with the request. Exiting.')
exit()
# Print the subject of each ticket in the results
data = response.json()
I iterate the data in order to get all values from key 'id' to be assigned to variable id_merged as String with comma separated
for result in data['results']:
# Ticket to update
id_merged = (result['id'])
but get only one result instead of 2, the var gets overwritten in the loop?
from test_search import data
import json
import requests
# Iterate the search result
for result in data['results']:
# Ticket to update
id_merged = (result['id'])
print("**Start**")
print(id)
body = 'Test ticket'
# Package the data in a dictionary matching the expected JSON
data_comment = {'ticket': {'comment': {'body': body}}}
# Encode the data to create a JSON payload
payload = json.dumps(data_comment)
# Set the request parameters
url = 'https://propertypro.zendesk.com/api/v2/tickets/update_many.json?' + \
'ids=' + str(id_merged)
user = 'some email'
pwd = 'some password'
headers = {'content-type': 'application/json'}
# Do the HTTP put request
response = requests.put(url, data=payload,
auth=(user, pwd), headers=headers)
# Check for HTTP codes other than 200
if response.status_code != 200:
print('Status:', response.status_code,
'Problem with the request. Exiting.')
exit()
# Report success
print('Successfully added comment to ticket #{}'.format(id))
I'd like to get a result like 'https://propertypro.zendesk.com/api/v2/tickets/update_many.json?' + \
'ids=' + 4249,4089 .
How do I get this?
If you want to turn the values of id into a comma delimited string, you can do the following.
','.join(id.values())
So change your code to
url = 'str,' + 'str1:' + ','.join(id.values())
For completeness, if you wanted to do the same thing with the dictionary keys, you'd just use
','.join(id)
Looks like you are getting list of list in dict values, in that case you can flatten the list and join on string "," like:
>>> import itertools
>>> ",".join(map(str, list(itertools.chain(*[[1,2,3],[4,5]]))))
'1,2,3,4,5'

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

Categories

Resources