string binary file in spring - python

https://prom.ua/cloud-cgi/static/uaprom-static/docs/swagger/index.html#/Products/post_products_import_file - link documentation
import json
import http.client
import pprint
import base64
API Settigs
AUTH_TOKEN = '56bggtygugttttttttttttttyt7u7u' # Your authorization token
HOST = 'my.prom.ua' # e.g.: my.prom.ua, my.tiu.ru, my.satu.kz, my.deal.by, my.prom.md
class HTTPError(Exception):
pass
class EvoClientExample(object):
def __init__(self, token):
self.token = token
def make_request(self, method, url, body=None):
connection = http.client.HTTPSConnection(HOST)
headers = {'Authorization': 'Bearer {}'.format(self.token),
'Content-type': 'application/json'}
if body:
body = json.dumps(body)
connection.request(method, url, body=body, headers=headers)
response = connection.getresponse()
if response.status != 200:
raise HTTPError('{}: {}'.format(response.status, response.reason))
response_data = response.read()
return json.loads(response_data.decode())
def get_order_list(self):
url = '/api/v1/orders/list'
method = 'GET'
return self.make_request(method, url)
def get_order(self, order_id):
url = '/api/v1/orders/{id}'
method = 'GET'
return self.make_request(method, url.format(id=order_id))
def set_order_status(self, status, ids, cancellation_reason=None, cancellation_text=None):
url = '/api/v1/orders/set_status'
method = 'POST'
body = {
'status': status,
'ids': ids
}
if cancellation_reason:
body['cancellation_reason'] = cancellation_reason
if cancellation_text:
body['cancellation_text'] = cancellation_text
return self.make_request(method, url, body)
def set_import_file(self, string_binary):
url = '/api/v1/products/import_file'
method = 'POST'
file = open("final.xml", "rb")
string_binary = file.read()
file.close()
body = {
"file": f'{string_binary}',
"data": {
"force_update": True,
"only_available": True,
"mark_missing_product_as": "none",
"updated_fields": [
"price",
"presence"
]
}
}
return self.make_request(method, url, body)
def main():
# Initialize Client
if not AUTH_TOKEN:
raise Exception('Sorry, there's no any AUTH_TOKEN!')
api_example = EvoClientExample(AUTH_TOKEN)
# file = open("final.xml", "rb")
# encoded_string = file.read()
# print(encoded_string)
# encoded_string = base64.b64encode(file.read())
import_file_response = api_example.set_import_file("")
# file.close()
print(import_file_response)
# if not order_list['orders']:
# raise Exception('Sorry, there\'s no any order!')
#
# pprint.pprint(api_example.get_order_list())
#
# # Order example data. Requred to be setup to get example work
# order_id = order_list['orders'][0]['id']
# order_ids = [order_id]
# status = 'received'
#
# # Setting order status
# pprint.pprint(api_example.set_order_status(status=status, ids=order_ids))
#
# # # Getting order by id
# pprint.pprint(api_example.get_order(order_id))
if name == 'main':
main()
error:
Traceback (most recent call last):
File "/home/dev/Documents/Workspace/prom/unload_prom/prom_api.py", line 118, in
main()
File "/home/dev/Documents/Workspace/prom/unload_prom/prom_api.py", line 97, in main
import_file_response = api_example.set_import_file("")
File "/home/dev/Documents/Workspace/prom/unload_prom/prom_api.py", line 84, in set_import_file
return self.make_request(method, url, body)
File "/home/dev/Documents/Workspace/prom/unload_prom/prom_api.py", line 31, in make_request
raise HTTPError('{}: {}'.format(response.status, response.reason))
main.HTTPError: 400: Bad Request

Related

Flask,Discord.py requests.exceptions.HTTPError: 400

hi, i am making auth bot with flask and python, when they click on the authorization link, this error comes to the console and there is no authorization
Error coming to console when someone clicks the link
Error:
[2023-02-03 07:29:44,909] ERROR in app: Exception on /discordauth [GET]
Traceback (most recent call last):
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "C:\Users\Administrator\Desktop\Discord-baker-main\application.py", line 37, in discord
data = exchange_code(code)
File "C:\Users\Administrator\Desktop\Discord-baker-main\application.py", line 187, in exchange_code
r.raise_for_status()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\models.py", line 943, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://discord.com/api/v9/oauth2/token```
When you click on the authorization link, this error appears on the link:
500 Internal Server Error
**Internal Server Error**
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
My code:
import requests
import configparser
import os
from flask import Flask, request, redirect, url_for, render_template
config = configparser.ConfigParser()
config.read('database.ini')
application = Flask(__name__)
API_ENDPOINT = "https://discord.com/api/v9"
#leave this like this
CLIENT_ID = config['apiinfo']['CLIENT_ID']
CLIENT_SECRET = config['apiinfo']['CLIENT_SECRET']
CLIENT_TOKEN = config['botinfo']['bottoken']
DOMAIN = config['apiinfo']['DOMAIN']
exchangepass = config['apiinfo']['exchangepass']
SCOPE = "identify guilds guilds.join"
REDIRECT_URI = f"{DOMAIN}/discordauth"
welcomechannel = str(config['botinfo']['welcome_channel'])
memberrole = str(config['botinfo']['memberrole'])
restorekey = str(config['botinfo']['therestorekey'])
guildid = config['info']['guildid']
def cls():
os.system('cls' if os.name == 'nt' else 'clear')
#application.route('/working', methods=['GET', 'POST'])
def working():
return 'true'
#application.route('/discordauth', methods=['GET', 'POST'])
def discord():
print("In discordauth")
code = request.args.get('code')
data = exchange_code(code)
state = request.args.get('state')
access_token = data.get("access_token")
refresh_token = data.get("refresh_token")
data2 = getid(access_token)
userid = str(data2.get("id"))
username = data2.get("username")
country = data2.get("locale")
if userid in config['useridsincheck']:
config['users'][userid] = 'NA'
config[userid] = {}
config[userid]['refresh_tokens'] = refresh_token
config[userid]['refresh'] = 'true'
config[userid]['country'] = country
with open('database.ini', 'w') as configfile:
config.write(configfile)
if request.method == 'POST':
return 'success'
if request.method == 'GET':
return render_template('Authcomplete.html')
elif userid in config['users']:
if request.method == 'POST':
return 'success'
if request.method == 'GET':
return render_template('Authcomplete.html')
else:
return 'fail'
#application.route('/restore', methods=['GET', 'POST'])
def restore():
password = request.json['code']
if password == exchangepass:
restoreserver()
return 'succsess'
else:
print("Invalid password" + password)
return 'wrong password'
#application.route('/', methods=['GET', 'POST'])
def testbuild():
return render_template('home.html')
def getid(info):
url = "https://discord.com/api/v9/users/#me"
payload={}
accsestokentoget = info
headers = {
'Authorization': 'Bearer ' + accsestokentoget,
}
response = requests.request("GET", url, headers=headers, data=payload)
response.raise_for_status()
return response.json()
#error to fix in here
#application.route('/requestid', methods=['GET', 'POST'])
def requestid():
print("Part requestid")
key = request.json['key']
id = str(request.json['id'])
print(id)
print(key)
if key == exchangepass:
if id in config['users']:
return 'succsess'
else:
print("key was correct")
#check if the category is in the config
config['useridsincheck'] = {}
config['useridsincheck'][id] = 'waiting'
with open('database.ini', 'w') as configfile:
config.write(configfile)
return 'succsess'
else:
print("key was wrong")
return 'wrong key'
#application.route('/data', methods=['GET', 'POST'])
def data():
key = request.json['key']
dataset = request.json['dataset']
print("part data")
if key == config['apiinfo']['tempkey']:
if dataset == 'CLIENT_ID':
return CLIENT_ID
if dataset == 'guildid':
return guildid
if dataset == 'CLIENT_SECRET':
return CLIENT_SECRET
if dataset == 'bottoken':
return CLIENT_TOKEN
if dataset == 'exchangepass':
return exchangepass
if dataset == 'welcomechannel':
return welcomechannel
if dataset == 'verifiedrole':
return memberrole
if dataset == 'restorekey':
return restorekey
if config['apiinfo']['botsetupcomplete'] == 'no':
if dataset == 'pass':
return config['apiinfo']['tempkey']
config['apiinfo']['botsetupcomplete'] = 'yes'
with open('database.ini', 'w') as configfile:
config.write(configfile)
return 'error dataset wrong'
#application.route('/checkifverifydone', methods=['GET', 'POST'])
def checkifverifydone():
print("Part checkifverifydone")
key = request.json['key']
id = str(request.json['id'])
print(id)
print(key)
if key == exchangepass:
print("key was correct")
if id in config['users']:
config['useridsincheck'][id] = 'verified'
with open('database.ini', 'w') as configfile:
config.write(configfile)
print("corect")
return 'true'
else:
print("id was not found")
return 'false'
else:
return 'false'
def exchange_code(code):
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI,
'scope': SCOPE
}
r = requests.post(
f"{API_ENDPOINT}/oauth2/token",
data=data,
headers=headers
)
r.raise_for_status()
return r.json()
def get_new_token(old_token): # gets new refresh_token
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': old_token
}
r = requests.post(
f"{API_ENDPOINT}/oauth2/token",
data=data,
headers=headers
)
r.raise_for_status()
return r.json()
def add_to_guild(access_token, user_id, guild_id):
headers = {
"Authorization" : f"Bot {CLIENT_TOKEN}",
'Content-Type': 'application/json'
}
data = {
"access_token" : access_token
}
response = requests.put(
url=f"{API_ENDPOINT}/guilds/{guild_id}/members/{user_id}",
headers=headers,
json=data
)
def restoreserver():
userids = config['users']
guildid = config['info']['guildid']
for idsinlist in userids:
print(idsinlist)
code = config[idsinlist]['refresh_tokens']
if config[idsinlist]['refresh'] == "false":
try:
data = exchange_code(code)
access_token = data.get("access_token")
add_to_guild(access_token, idsinlist, guildid)
config[idsinlist]['refresh_tokens'] = data.get("refresh_token")
config[idsinlist]['refresh'] = 'true'
with open('database.ini', 'w') as configfile:
config.write(configfile)
except:
print("error")
if config[idsinlist]['refresh'] == "true":
try:
data = get_new_token(code)
access_token = data.get("access_token")
add_to_guild(access_token, idsinlist, guildid)
config[idsinlist]['refresh_tokens'] = data.get("refresh_token")
with open('database.ini', 'w') as configfile:
config.write(configfile)
except:
print("error")
else:
print("Refresh status is invalid")
print(code)
if __name__ == '__main__':
cls()
application.run(host='0.0.0.0', port=80) #change to your port default port is 80

Lambda function throws an exception saying unhashable type: 'dict': TypeError

Getting the following error when we deploy the lambda code given in the below code
unhashable type: 'dict': TypeError
Traceback (most recent call last):
File "/var/task/lambda.py", line 69, in lambda_handler
response_body
TypeError: unhashable type: 'dict'
unhashable type: 'dict': TypeError Traceback (most recent call last): File "/var/task/lambda.py", line 69, in lambda_handler response_body TypeError: unhashable type: 'dict'
import boto3, json, logging, os
import requests
logs = boto3.client('logs')
ssm = boto3.client('ssm')
#Define logging properties
log = logging.getLogger()
log.setLevel(os.environ.get("LOGLEVEL"))
def lambda_handler(event, context):
#Initialize the status of the function
status="SUCCESS"
responseData = {}
RequestType = event['RequestType']
if RequestType == 'Delete' :
#Set Return Data
response_data = {"Message" : "Subscription filter deleted"}
#return the response back to the S3 URL to notify CloudFormation about the code being run
response=respond(event,context,status,response_data,None)
#Function returns the response from the S3 URL
response_body = {}
response_body['Dev Response'] = json.dumps(response)
return {
response_body
}
destinationArn=os.environ['alert_lambda_arn']
LogGroupName = event['ResourceProperties']['LogGroupName']
log.debug("LogGroupName :" + LogGroupName)
ServiceName=LogGroupName[25:-14]
log.debug("Service Name : {}".format(ServiceName))
CommomPre = event['ResourceProperties']['CommonPre']
log.debug("CommomPre :" + CommomPre)
NoOfcommomTerm =int( event['ResourceProperties']['NoOfCommonTerm'])
ServiceSpecPre = event['ResourceProperties']['ServiceSpecPre']
log.debug("ServiceSpecPre :" + ServiceSpecPre)
NoOfServiceSpecTerm = int (event['ResourceProperties']['NoOfServiceSpecTerm'])
filterpattern=""
filterpattern=getFilterpattern(CommomPre, NoOfcommomTerm, filterpattern)
filterpattern=getFilterpattern(ServiceSpecPre, NoOfServiceSpecTerm, filterpattern)
response = logs.put_subscription_filter(
logGroupName=LogGroupName,
filterName="vm-managed-" + ServiceName + "filter",
filterPattern=filterpattern,
destinationArn=destinationArn
)
#Set Return Data
response_data = {"Message" : "Subscription filter created"}
#return the response back to the S3 URL to notify CloudFormation about the code being run
response=respond(event,context,status,response_data,None)
#Function returns the response from the S3 URL
response_body = {}
response_body['Dev Response'] = json.dumps(response)
return {
response_body
}
def getFilterpattern(prefix, NoOfterm, filterpattern):
for i in range(0, NoOfterm):
term= prefix + str(i+1)
print(term)
response = ssm.get_parameter(
Name=term,
)
filterpattern=filterpattern + " " + response['Parameter']['Value']
return filterpattern
def respond(event, context, responseStatus, responseData, physicalResourceId):
#Build response payload required by CloudFormation
responseBody = {}
responseBody['Status'] = responseStatus
responseBody['Reason'] = 'Details in: ' + context.log_stream_name
responseBody['PhysicalResourceId'] = context.log_stream_name
responseBody['StackId'] = event['StackId']
responseBody['RequestId'] = event['RequestId']
responseBody['LogicalResourceId'] = event['LogicalResourceId']
responseBody['Data'] = responseData
#Convert json object to string and log it
json_responseBody = json.dumps(responseBody)
log.debug("Response body: " + str(json_responseBody))
#Set response URL
responseUrl = event['ResponseURL']
#Set headers for preparation for a PUT
headers = {
'content-type' : '',
'content-length' : str(len(json_responseBody))
}
#Return the response to the signed S3 URL
try:
response = requests.put(responseUrl,
data=json_responseBody,
headers=headers)
log.debug("Status code: " + str(response.reason))
status="SUCCESS"
return status
#Defind what happens if the PUT operation fails
except Exception as e:
log.error("send(..) failed executing requests.put(..): " + str(e))
status="FAILED"
return status
Instead of:
return {
response_body
}
there should be
return response_body

Python Mocking a request for a bearer token?

I'm trying to figure out how to mock my request for a bearer token in python.
I have a class:
class grab_apitokens(object):
def __init__(self, consumer_key, first_api_url, second_api_user, second_api_password, second_api_url):
self.consumer_key = consumer_key
self.second_api_user = second_api_user
self.second_api_password = second_api_password
self.first_api_url = first_api_url
self.second_api_url = second_api_url
def logintofirstsite(self):
b64val = base64.b64encode(self.consumer_key.encode()).decode()
headers = {"Authorization": "Basic %s" % b64val}
data = {'grant_type': 'client_credentials', 'validity_period': '3600'}
try:
response = requests.post(self.first_api_url, headers=headers, data=data)
decodedresponse = json.loads(response.content.decode())
access_token = decodedresponse['access_token']
return access_token
except:
return None
def logintosecondsite(self):
header = {"accept": "application/json", "Content-Type": "application/x-www-form-urlencoded"}
logindata = {'grant_type': 'password',
'username': "" + self.second_api_user + "", 'password': "" + self.second_api_password + ""
}
try:
returnedfromsite = requests.post(self.second_api_url + '/api/V1/token',
headers=header, data=logindata)
return returnedfromsite.json()['access_token']
except:
return None
What I can't figure out is how to mock that requests call and what it would look like in Python.
My test currently looks like:
class MyTestCase(unittest.TestCase):
def setUp(self) -> None: # PROBLEM BEGINS HERE
self.grab_apitokens = grab_apitokens(actual_key, actual_site1, actual_user, actual_pass, actual_2nd_site)
#patch('grab_apitokens.requests.get')
def test_login(self, mock_get):
mock_get.return_value.ok = True
response = self.grab_apitokens.logintosite()
assert_is_not_none(response)
# self.assertEqual(True, False)
if __name__ == '__main__':
unittest.main()
How would I mock the requests.post functionality?
With the help of a good mentor I figured out that my approach was all wrong. Here's what I ended up with for the unit test:
class MyTestCase(unittest.TestCase):
def setUp(self) -> None:
self.grab_apitokens = grab_apitokens("complete","gibberish","it really doesnt","matter","what is","in","here")
#patch('grab_apitokens.requests.posts')
def test_login(self, mock_get):
mock_json = {'token': 'foo'}
mock_get.return_value = Mock(ok=True)
mock_get.return_value.json.return_value = mock_json
mock_get.return_value.content = b'{"token": "foo"}'
response = self.grab_apitokens.logintofirstsite()
assert_equal(response, "foo")
if __name__ == '__main_
To understand what this does, I needed to know that what we're really mocking isn't the method logintofirstsite(), we're mocking the response that requests.post is making in the method. With mock_get, we're inject requests.posts to always be: {'token': 'foo'} . So everything after
response = requests.post(self.first_api_url, headers=headers, data=data)
in logintofirstsite() is what I'm really testing. Which is:
decodedresponse = json.loads(response.content.decode())
access_token = decodedresponse['token']
return access_token
The setup before the requests.post call doesn't matter one bit. Since with {'token': 'foo'} is what my requests.post call returns, the returned value after that bit of logic is 'foo', and so the assert_equal back in MyTestCase passes.

Spotify API Python

I am following a tutorial from CodingEntrepreneurs and i have come across a road bump where it returns a 400 error when i run it.
Here is my code
import base64, requests
import datetime
from urllib.parse import urlencode
client_id = "my id"
client_secret = "my secret"
class SpotifyAPI(object):
access_token = None
access_token_expires = datetime.datetime.now()
access_token_did_expire = True
client_id = None
client_secret = None
token_url = "https://accounts.spotify.com/api/token"
def __init__(self, client_id, client_secret, *args, **kwargs):
super().__init__(*args, **kwargs)
self.client_id = client_id
self.client_secret = client_secret
def getClientCreds(self):
'''Returns b64 encoded string'''
client_id = self.client_id
client_secret = self.client_secret
if client_id == None or client_secret == None:
raise Exception('Must set a client id and secret')
client_creds = f"{client_id}:{client_secret}"
client_creds_b64 = base64.b64encode(client_creds.encode())
return client_creds_b64.decode()
def getTokenHeader(self):
client_creds_b64 = self.getClientCreds()
return {
'Authorization':f"Basic {client_creds_b64}"
}
def getTokenData(self):
return {
"grant_type":"client_credentials"
}
def perform_auth(self):
token_url = self.token_url
token_data = self.getTokenData()
token_header = self.getTokenHeader()
r = requests.post(token_url, data=token_data, headers=token_header)
if r.status_code not in range(200,299):
return False
now = datetime.datetime.now()
token_response_data = r.json()
access_token = token_response_data['access_token']
expires_in = token_response_data['expires_in']
expires = now + datetime.timedelta(seconds=expires_in)
self.access_token = access_token
self.access_token_expires = expires
self.access_token_did_expire = expires < now
return True
spotify = SpotifyAPI(client_id, client_secret)
print(spotify.perform_auth())
token = spotify.access_token
header = {
"Authorization": f"Bearer{token}",
}
endpoint = "https://api.spotify.com/v1/search"
data = urlencode({"q": "Time", "type": "track"})
lookupURL = f"{endpoint}?{data}"
r = requests.get(lookupURL, headers=header)
print(r.json())
When i run this it returns this
"
True
{'error': {'status': 400, 'message': 'Only valid bearer authentication supported'}}
"
Please could someone help and explain the solution.
Thanks,
Sam :)
I think it could be a problem here, as you are leaving no space between the Bearer keyword and the token:
# previous
header = {
"Authorization": f"Bearer{token}",
}
# correct
header = {
"Authorization": f"Bearer {token}",
}

Attribute error in nested method

I have the following class:
class Connection(object):
defaults = {
'application_key':None,
}
def __init__(self, application_key="None"):
self.application_key = application_key or Connection.defaults.get('application_key')
def make_request(self, params=None, method=None):
url = URL_FORMAT % {
'params': params,
}
headers = {
'Authorization': 'Token token='+ self.application_key,
'content-type': 'application/json',
}
if method == "get":
request = requests.get(url, headers=headers)
if request.status_code == requests.codes.ok:
return request.json()
else:
raise APIError("%s status received (not 200)" % request.status_code)
elif method == "post":
request = requests.post(url, headers=headers)
request.status_code == requests.codes.ok
if request.status_code == requests.codes.ok:
return request.json()
else:
raise APIError("%s status received (not 200)" % request.status_code)
def get_geofence(self):
try:
data = self.make_request('geofences', 'get')
return data
except APIError:
raise GeofenceNotFound("Geofence not found")
def get_geofence_id(self, geofence_id=None):
try:
data = self.make_request('geofences/'+self.geofence_id+'/', 'get')
return data
except APIError:
raise GeofenceNotFound("Geofence not found with id #%s" % self.geofence_id)
The problem line seems to be data = self.make_request('geofences/'+self.geofence_id+'/', 'get') returning AttributeError: 'Connection' object has no attribute 'geofence_id'
I'm pretty stumped here.
geofence_id is not a class attribute, it is a function parameter. Thus, you should just refer to is as geofence_id and not self.geofence_id.

Categories

Resources