python function says " no attribute in function" - python

I am running below proecedure to get some values so that i use those values later in main program globally
import requests
import json
import sys
client= 'test'
def get_path(client):
headers = {'Content-Type': 'application/json', 'X-Vault-Token': get_token()}
URL='https://xxxxxxxx.xxx/v1/'+'ab/li/'+client
response=requests.get(URL,headers=headers)
jout = json.loads(response.text)
azure_path=jout['data']['account_id']
get_path.tenant_id=jout['data']['tenant_id']
return azure_path
tenant = ('tenant is :' + get_path(client).tenant_id)
print(tenant)
but its erroring saying there is no attribute
tenant = ('tanant is :' + get_path.tenant_id(client))
AttributeError: 'function' object has no attribute 'tenant_id'
I am sure it has value when i print variable called jout it does have tenant id
EDIT 1: Solved it by below
import requests
import json
import sys
client= 'test'
tenant_var = None
def get_path(client):
global tenant_var
headers = {'Content-Type': 'application/json', 'X-Vault-Token': get_token()}
URL='https://xxxxxxxx.xxx/v1/'+'ab/li/'+client
response=requests.get(URL,headers=headers)
jout = json.loads(response.text)
azure_path=jout['data']['account_id']
tenant_var=jout['data']['tenant_id']
return azure_path
tenant = ('tenant is :' + tenant_var)
print(tenant)

In your function, you are setting tenant_id as attribute of your function object get_path... it's a rather strange way of coding.
To make this work, you can adapt the following snippet:
def get_path(arg):
get_path.tenant_id = '123' + arg
return 'something else'
# get the function object
myfunction = get_path
# call the function
myfunction('myargument')
# consume the function object attribute
tenant = ('tenant is :' + myfunction.tenant_id)
Or the better way: as suggested in the comments, return the tenant_id as part of a tuple in the return value of your function.

Solved it by using global variable deceleration
import requests
import json
import sys
client= 'test'
tenant_var = None
def get_path(client):
global tenant_var
headers = {'Content-Type': 'application/json', 'X-Vault-Token': get_token()}
URL='https://xxxxxxxx.xxx/v1/'+'ab/li/'+client
response=requests.get(URL,headers=headers)
jout = json.loads(response.text)
azure_path=jout['data']['account_id']
tenant_var=jout['data']['tenant_id']
return azure_path
tenant = ('tenant is :' + tenant_var)
print(tenant)

Related

FTX get account info using Python gives Not logged in error

I tried to connect to FTX using Python to get account information but it keeps giving me not logged in error; my code shown below:
from requests import Request, Session
import time
import hmac
method = 'GET'
ENDPOINT = 'https://ftx.com/api/'
# ENDPOINT = 'https://ftx.us/api/'
path = 'account'
API_KEY = '...'
API_SECRET = '...'
request = Request(method, ENDPOINT + path)
ts = int(time.time() * 1000)
prepared = request.prepare()
print('{0}{1}{2}'.format(ts, prepared.method, prepared.path_url))
signature_payload = '{0}{1}{2}'.format(ts, prepared.method, prepared.path_url).encode()
if prepared.body:
signature_payload += prepared.body
signature = hmac.new(API_SECRET.encode(), signature_payload, 'sha256').hexdigest()
request.headers['FTX-KEY'] = API_KEY
request.headers['FTX-SIGN'] = signature
request.headers['FTX-TS'] = str(ts)
# get data...
request1 = request.prepare()
print('{0}{1}{2}'.format(ts, request1.method, request1.path_url))
response = Session().send(request1)
data = response.json()
the data gives me:
{'success': False, 'error': 'Not logged in'}
I wonder where I did wrong? I locate in US is this might cause issue? and my account hasn't traded anything yet not sure if that's the issue.
fwiw, it's been a while and I haven't done much more work on this.. but I believe it's because of the location.. if the account is registered under FTX international this should work...
Please change headers to the following and url to ftx.us/api
request.headers['FTXUS-KEY'] = API_KEY
request.headers['FTXUS-SIGN'] = signature
request.headers['FTXUS-TS'] = str(ts)

Parsing json GitHub api with Python

Having difficulty parsing json from GitHub api. I'm trying to populate a team with all the repos from an organisation. I'm using myteamname to obtain the teamid required for the loop which populates the team with the repo names.
import json
import requests
mytokenid = "xxx"
myorg = "xxx"
myteamname = "xxx"
headers = {
'Authorization': 'token %s' % mytokenid,
}
response = requests.get('https://api.github.com/orgs/{0}/teams/{1}'.format(myorg, myteamname), headers=headers)
teamidjson = json.loads(response.text)
myteamid = teamidjson(['id'])
g = Github(tokenid)
for repo in g.get_organization(myorg).get_repos():
myreponame = repo.name
response = requests.put('https://api.github.com/teams/{0}/repos/{1}/{2}'.format(myteamid, myorg, myreponame), headers=headers)
I get this error message
File "githubteam.py", line 74, in <module>
myteamid = teamidjson(['id'])
TypeError: 'dict' object is not callable
myteamid = teamidjson(['id'])
That seems to be causing the error. The correct way to access the id key is:
myteamid = teamidjson['id']
I think you meant
myteamid = teamidjson['id']
# you can also use this
myteamid = teamidjson.get('id', None) # it will default to None if id doesn't exist...

AWS Lambda Python Handler with class

Hello I designed a python script that works locally however I would like to push it to AWS Lambda, I'm having some issues specifically with creating the handler within a class. I have figured out how to get rid of the 'handler error' in lambda by creating the handler function outside of the class but unfortunately that doesn't run the rest of my code. My goal is to place the "lambda_handler" function either inside my class or have the function call the class. Any advice is really appreciated!
#!/usr/bin/python
import sys
import os
import json
import time
from datetime import datetime, timedelta
key = 'OKTA_AUTH'
### key = os.environ['OKTA_AUTH'] #####
outcome = 'outcome.result eq "FAILURE"'
event_type = 'eventType eq "application.provision.user.deactivate"'
app_id = 'target.id eq "SOME OKTA APP ID"'
all_params = f'{event_type} and {app_id} and {outcome}'
api_url = 'https://domain.okta.com/api/v1/logs'
slack_url = "SLACK URL"
last_hour_date_time = datetime.utcnow() - timedelta(days=10)
since = str(last_hour_date_time.strftime('%Y-%m-%dT%H:%M:%S.000Z'))
actor_list=[]
unique_list=[]
class Events:
def lambda_handler(event, context):
okta_auth()
def okta_auth(self):
event_list=[]
url = api_url.format()
params = {
'filter': all_params,
'since': since
}
response = requests.get(url, params=params,
headers={'Accept': 'application/json',
'authorization': key})
response_json = response.json()
for event_data in response_json:
events = event_data['outcome']['reason']
event_list.append(events)
actors = event_data['actor']['alternateId']
actor_list.append(actors)
unique_set = set(actor_list)
unique_list.append(unique_set)
if event_list != []:
self.post_slack()
else:
sys.exit(0)
def post_slack(self):
url = slack_url.format()
payload = "{\"text\": \" Twillio Flex provisioing failure. Please check the following users %s \"}" % (unique_list)
requests.post(url, headers={'Accept': 'application/json'}, data=payload)
### newly added code
if __name__ == "__main__":
Events().lambda_handler()
### end
####ORIGINAL CODE USED TO BE
#if __name__ == "__main__":
# Events().okta_auth()
After some solid studying, I discovered I was running into two issues with my code and how AWS Lambda works. The first issue was how I was calling the class in Lambda. I though that you had to have the function inside the class, but instead I created a function to run the class.
def lambda_handler(event, context):
Events().okta_auth() #### the function (okta_auth) within the class (Events)
My second issue was deployment via inline code. Lambda does not have the requests module installed by default, so I created a local directory, where I then pip3 installed requests, and moved the python script to. You can then zip the folder contents and upload to aws lambda.
mkdir lambda_deploy
pip3 install --target ./lambda_deploy/ requests
cd lambda_deploy/
zip -r9 ${OLDPWD}/function.zip .
heres the final code below for reference.
#!/usr/bin/python
import requests
import sys
import os
import json
import time
from datetime import datetime, timedelta
key = os.environ['OKTA_AUTH']
outcome = 'outcome.result eq "FAILURE"'
event_type = 'eventType eq "application.provision.user.deactivate"'
target_type = 'target.type eq "User"'
app_id = 'target.id eq "SOME APP ID"'
all_params = f'{event_type} and {target_type} and {app_id} and {outcome}'
api_url = f'https://domain.okta.com/api/v1/logs'
slack_url = "some slack WEBHOOK URL"
last_hour_date_time = datetime.utcnow() - timedelta(days=1)
since = str(last_hour_date_time.strftime('%Y-%m-%dT%H:%M:%S.000Z'))
unique_set=[]
def lambda_handler(event, context):
Events().okta_auth()
class Events:
def okta_auth(self):
event_list=[]
url = api_url.format()
params = {
'filter': all_params,
'since': since
}
response = requests.get(url, params=params,
headers={'Accept': 'application/json',
'authorization': key})
response_json = response.json()
for event_data in response_json:
events = event_data['outcome']['reason']
targets = event_data['target']
parse = list(map(lambda x: x['alternateId'], targets))
target_list=[]
event_list.append(events)
target_list.append(parse[1])
for item in target_list:
if item not in unique_set:
unique_set.append(item)
if event_list != []:
self.post_slack()
else:
print("no errors today")
def post_slack(self):
url = slack_url.format()
payload = "{\"text\": \" Twilio Flex provisioing failure. Please check the following users: \n %s \"}" % '\n'.join(unique_set)
requests.post(url, headers={'Accept': 'application/json'}, data=payload)
Your function
def lambda_handler(event, context):
print(event)
only prints the event and does not execute anything else. I guess that's why the lambda is not doing anything. The lambda_handler is the entry point of your lambda.

Amazon API MWS SignatureDoesNotMatch

I've been trying to get this to work for hours now. None of the solutions on other questions are working.
What I'm trying to do is get my list of orders on Amazon. To do this, I am making a call to Amazon MWS. However, this is the error message I am getting:
<?xml version="1.0"?>
<ErrorResponse xmlns="https://mws.amazonservices.com/Orders/2013-09-01">
<Error>
<Type>Sender</Type>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
</Error>
<RequestID>03686743-15a6-4207-b0b7-316d1e4e5c8f</RequestID>
</ErrorResponse>
To find out what was wrong, I went onto Amazon MWS Scratchpad and used the same values, even the timestamp (I think you have 15 minutes until it expires), and compared the signatures. They were the same. However, my program still got the same error while the scratchpad worked perfectly.
Here is all the code:
import sys, os, base64, datetime, hashlib, hmac, urllib
from time import gmtime, strftime
from requests import request
import xml.etree.ElementTree as ET
def get_timestamp():
"""Return correctly formatted timestamp"""
return strftime("%Y-%m-%dT%H:%M:%SZ", gmtime())
def calc_signature():
"""Calculate signature to send with request"""
sig_data = method + '\n' + domain.replace('https://', '').lower() + '\n' + URI + '\n' + request_description
hmac_obj = hmac.new(str(SECRET_KEY), sig_data, hashlib.sha256)
return urllib.quote(base64.b64encode(hmac_obj.digest()), safe='-_.~')
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
AWS_ACCESS_KEY = 'xxxxxxxxxxxxxxxxxxx'
SELLER_ID = 'xxxxxxxxxxxxxxxxxxxxxxx'
MARKETPLACE_ID = 'xxxxxxxxxxxxxxx'
Action = 'ListOrders'
SignatureMethod = 'HmacSHA256'
SignatureVersion = '2'
Timestamp = get_timestamp()
Version = '2013-09-01'
CreatedAfter = '2014-08-26T23:00:57Z' # TODO -1 day
URI = '/Orders/2013-09-01'
domain = 'https://mws.amazonservices.co.uk'
method = 'POST'
payload = {'AWSAccessKeyId': AWS_ACCESS_KEY,
'Action': Action,
'SellerId': SELLER_ID,
'SignatureVersion': SignatureVersion,
'Timestamp': Timestamp,
'Version': Version,
'SignatureMethod': SignatureMethod,
'CreatedAfter': '2014-08-26T23:00:00Z',
'MarketplaceId.Id.1': MARKETPLACE_ID
}
request_description = '&'.join(['%s=%s' % (k, urllib.quote(payload[k], safe='-_.~').encode('utf-8')) for k in sorted(payload)])
sig = calc_signature()
url = '%s%s?%s&Signature=%s' % (domain, URI, request_description, urllib.quote(sig))
headers = {'Host': 'amazonwebservices.co.uk', 'Content-Type': 'text/xml', 'x-amazon-user-agent': 'python-requests/1.2.0 (Language=Python)'}
response = request(method, url, headers=headers)
print response.content
Here's a print of sig_data in calc_signature():
POST
mws.amazonservices.co.uk
/Orders/2013-09-01
AWSAccessKeyId=xxxxxxxxxxxxx&Action=ListOrders&CreatedAfter=2014-08-26T23%3A00%3A00Z&MarketplaceId.Id.1=xxxxxxxxxxxxx&SellerId=xxxxxxxxxxxxxxx&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-08-28T15%3A50%3A34Z&Version=2013-09-01
Here's a print of url:
https://mws.amazonservices.co.uk/Orders/2013-09-01?AWSAccessKeyId=xxxxxxxxxxxx&Action=ListOrders&CreatedAfter=2014-08-26T23%3A00%3A00Z&MarketplaceId.Id.1=xxxxxxxxxxxx&SellerId=xxxxxxxxxxxxx&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2014-08-28T15%3A50%3A34Z&Version=2013-09-01&Signature=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I am completely out of ideas at this point. I have triple checked that my secret key, access key, seller ID and marketplace ID are correct.
Any help would be massively, massively appreciated!
I know this is a few months late but I had the exact same issue despite knowing my signature was correct and found out it was in fact the POST execution that was the problem and not the signature. If Amazon can't understand your params, it will throw an HTTP 403 error and tell you your signature is wrong even though it's not. I can't tell you why it works this way but try skipping the requests library and doing the following using urllib.request after building your url instead which worked for me:
#using python 3.4
import urllib.request
#... your code from before...
headers = {'Host': 'mws.amazonservices.com', 'Content-Type': 'text/xml', 'x-amazon-user-agent': 'SomeApp/1.1 (Language=Python)'}
req = urllib.request.Request(method=method,url=url,headers=headers)
response = urllib.request.urlopen(req)
the_page = response.read()
print(the_page)
#As seen here: https://docs.python.org/3/howto/urllib2.html#data
If that doesn't do it, take a second look at how you encoded everything and maybe dabble with urllib.parse.
Happy Amazoning!
Inside your calc_signature function, your safe parameter isn't allowing + and / which are allowed in the base64 output character set. As a result, it is percent-encoding them, and then those percents get further perecnt-encoded as %25s in the query string.
I made some additional changes, so here's all the code:
import sys, os, base64, datetime, hashlib, hmac, urllib
from time import gmtime, strftime
from requests import request
import xml.etree.ElementTree as ET
def get_timestamp():
"""Return correctly formatted timestamp"""
return strftime("%Y-%m-%dT%H:%M:%SZ", gmtime())
def calc_signature(method, domain, URI, request_description, key):
"""Calculate signature to send with request"""
sig_data = method + '\n' + \
domain.lower() + '\n' + \
URI + '\n' + \
request_description
hmac_obj = hmac.new(key, sig_data, hashlib.sha256)
digest = hmac_obj.digest()
return urllib.quote(base64.b64encode(digest), safe='-_+=/.~')
SECRET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
AWS_ACCESS_KEY = 'XXXXXXXXXXXXXX'
SELLER_ID = 'XXXXXXXXXXXXX'
MARKETPLACE_ID = 'XXXXXXXXXXXX'
Action = 'ListOrders'
SignatureMethod = 'HmacSHA256'
SignatureVersion = '2'
Timestamp = get_timestamp()
Version = '2013-09-01'
CreatedAfter = '2013-08-26T23:00:57Z'
URI = '/Orders/2013-09-01'
domain = 'mws.amazonservices.com'
proto = 'https://'
method = 'POST'
payload = {
'AWSAccessKeyId': AWS_ACCESS_KEY,
'Action': Action,
'SellerId': SELLER_ID,
'SignatureVersion': SignatureVersion,
'Timestamp': Timestamp,
'Version': Version,
'SignatureMethod': SignatureMethod,
'CreatedAfter': CreatedAfter,
'MarketplaceId.Id.1': MARKETPLACE_ID
}
request_description = '&'.join(['%s=%s' % (k, urllib.quote(payload[k], safe='-_.~').encode('utf-8')) for k in sorted(payload)])
sig = calc_signature(method, domain, URI, request_description, SECRET_KEY)
url = '%s%s?%s&Signature=%s' % \
(proto+domain, URI, request_description, urllib.quote(sig))
headers = {
'Host': domain,
'Content-Type': 'text/xml',
'x-amazon-user-agent': 'python-requests/1.2.0 (Language=Python)'
}
response = request(method, url, headers=headers)
print response.content

'module' object has no attribute 'HTTPSConncetion'

Hi I have the following code but am getting an error that the module object has no attribute HTTPSConnection:
from ecomstore import settings
import httplib
import urllib
def do_auth_capture(amount='0.00', card_num=None, exp_date=None, card_cvv=None):
delimiter = '|'
raw_params = {
'x_login':settings.AUTHNET_LOGIN,
'x_tran_key':settings.AUTHNET_KEY,
'x_type':'AUTH_CAPTURE',
'x_amount':amount,
'x_version':'3.1',
'x_card_num':card_num,
'x_exp_date':exp_date,
'x_delim_char':delimiter,
'x_relay_response':'FALSE',
'x_delim_data':'TRUE',
'x_card_code':card_cvv
}
params = urllib.urlencode(raw_params)
headers = {'content-type':'application/x-www-form-urlencoded',
'content-length':len(params)}
post_url = settings.AUTHNET_POST_URL
post_path = settings.AUTHNET_POST_PATH
cn = httplib.HTTPSConncetion(post_url,httplib.HTTPS_PORT)
cn.request('POST',post_path, params, headers)
return cn.getresponse().read().split(delimiter)
Is there a reason this is happening?
cn = httplib.HTTPSConncetion(post_url,httplib.HTTPS_PORT)
You've misspelled "Connection".

Categories