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.
Related
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
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
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.
I'm trying to connect via json-rpc to the trytond isntance using this class
class HttpClient:
"""HTTP Client to make JSON RPC requests to Tryton server.
User is logged in when an object is created.
"""
def __init__(self, url, database_name, user, passwd):
self._url = '{}/{}/'.format(url, database_name)
self._user = user
self._passwd = passwd
self._login()
self._id = 0
def get_id(self):
self._id += 1
return self._id
def _login(self):
"""
Returns list, where
0 - user id
1 - session token
"""
payload = json.dumps({
'params': [self._user, {'password': self._passwd}],
'jsonrpc': "2.0",
'method': 'common.db.login',
'id': 1,
})
headers = {'content-type': 'application/json'}
result = requests.post(self._url, data=payload, headers=headers)
if result.status_code in [500, 401]:
raise Exception(result.text)
if 'json' in result:
self._session = result.json()['result']
else:
self._session = json.loads(result.text)
return self._session
def call(self, prefix, method, params=[[], {}]):
"""RPC Call
"""
method = '{}.{}'.format(prefix, method)
payload = json.dumps({
'params': params,
'method': method,
'id': self.get_id(),
})
authorization = base64.b64encode(self._session[1].encode('utf-8'))
headers = {
'Content-Type': 'application/json',
'Authorization': b'Session ' + authorization
}
response = requests.post(self._url, data=payload, headers=headers)
if response.status_code in [500, 401]:
raise Exception(response.text)
return response.json()
def model(self, model, method, args=[], kwargs={}):
return self.call('model.%s' % model, method, [args, kwargs])
def system(self, method):
return self.call('system', method, params=[])
and I call it in this way
def notifieToMainServer(self):
url = "http://%s:%s" % (HOST, PORT)
headers = {'content-type': 'application/json'}
client = HttpClient(url, "tryton", CREDENTIALS[0], CREDENTIALS[1])
client.model('main.register',
'ActivateService',
{'code': self.code,
'name': self.nome,
'surname': self.cognome,
'service_type': 'registry',
'service_url': '' # qui andra messa l'url di chimata
}
)
the creatin of the HttpClient works well and I'm able to login, but when I try to call the method ActivateService I recive a 401 responce.
I also add the ActivateService into the rpc class
#classmethod
def __setup__(cls):
super(MainRegister, cls).__setup__()
cls.__rpc__.update({
'ActivateService': RPC(instantiate=0)})
and the function is like
def ActivateService(self,
code,
name,
surname,
service_type,
service_url):
"""
activate the service for the given code and the given service
"""
what I did wrong ?
best regards,
Matteo
The Authorization header should be:
'Authorization': : b'Bearer ' + authorization
At the and I finally solve the problem with this modifies class
class HttpClient:
"""HTTP Client to make JSON RPC requests to Tryton server.
User is logged in when an object is created.
"""
def __init__(self, url, database_name, user, passwd):
self._url = '{}/{}/'.format(url, database_name)
self._user = user
self._passwd = passwd
self._login()
self._id = 0
def get_id(self):
self._id += 1
return self._id
def _login(self):
"""
Returns list, where
0 - user id
1 - session token
"""
payload = json.dumps({
'params': [self._user, {'password': self._passwd}],
'jsonrpc': "2.0",
'method': 'common.db.login',
'id': 1,
})
headers = {'content-type': 'application/json'}
result = requests.post(self._url,
data=payload,
headers=headers)
if result.status_code in [500, 401]:
raise Exception(result.text)
if 'json' in result:
self._session = result.json()['result']
else:
self._session = json.loads(result.text)
return self._session
def call(self, prefix, method, params=[[], {}, {}]):
"""RPC Call
"""
method = '{}.{}'.format(prefix, method)
payload = json.dumps({
'params': params,
'method': method,
'id': self.get_id(),
})
auth = "%s:%s:%s" % (self._user, self._session[0], self._session[1])
authorization = base64.b64encode(auth.encode('utf-8'))
headers = {
'Content-Type': 'application/json',
'Authorization': b'Session ' + authorization
}
response = requests.post(self._url,
data=payload,
headers=headers)
if response.status_code in [500, 401]:
raise Exception(response.text)
return response.json()
def model(self, model, method, args=[], kwargs={}):
return self.call('model.%s' % model, method, (args, kwargs, {}))
def system(self, method):
return self.call('system', method, params=[])
the key point is the call that must be done with the context in order to be executed in the right way !!
def model(self, model, method, args=[], kwargs={}):
return self.call('model.%s' % model, method, (args, kwargs, {}))
hope it helps
regards
my deorator function...
def validate_captcha(view):
'''Decorator to validate a captcha based on settings'''
def failure():
return HttpResponse('You need to complete the captcha, please refresh and try again')
if request.method == 'POST':
url = "https://www.google.com/recaptcha/api/siteverify"
values = {
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': request.POST.get(u'g-recaptcha-response', None),
'remoteip': request.META.get("REMOTE_ADDR", None),
}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
result = json.loads(response.read())
# result["success"] will be True on a success
if result["success"]:
return view
else:
return fail
return fail
and then my view...
#validate_captcha
def sendemail(request):
...
I could put the request in the decorator args, but then it is undefined when i put it in the view args. I tried calling it a few others ways without success, how would you put it in there?
You need to have a wrapper function:
def validate_captcha(view):
def wrap(request, *args, **kwargs):
if request.method == 'POST':
url = "https://www.google.com/recaptcha/api/siteverify"
values = {
'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
'response': request.POST.get(u'g-recaptcha-response', None),
'remoteip': request.META.get("REMOTE_ADDR", None),
}
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
result = json.loads(response.read())
# result["success"] will be True on a success
if result["success"]:
return view
else:
return fail
return fail
return wrap
Make sure study this awesome and quite detailed overview on decorators in Python (I personally think, it is one of the best SO answers ever):
https://stackoverflow.com/a/1594484/771848