Python - how to access nested dictionary items from REST call - python

I want to access a nested dictionary item from a REST call but I can't figure out how to access it.
Here is the response:
{"deck_id": "z4p8ee99e7wu", "success": true, "cards": [{"suit": "DIAMONDS", "code": "6D", "value": "6", "images": {"png": "https://deckofcardsapi.com/static/img/6D.png", "svg": "https://deckofcardsapi.com/static/img/6D.svg"}, "image": "https://deckofcardsapi.com/static/img/6D.png"}], "remaining": 51}
(I am really interested in the image link)
This is a public REST API, so anyone could run this code.
My goal is to eventually create a card game, but as you can see, I am just a beginner.)
Here is the code:
import requests
import json
response =
requests.get('https://deckofcardsapi.com/api/deck/new/shuffle/?
deck_count=1')
print(response.text)
print(" ")
print("Status code: " + str(response.status_code))
print("Content type: " + response.headers['content-type'])
data = response.json()
print("deck ID: %s" % data["deck_id"])
print("remaining: %s" % data["remaining"])
deckid=data["deck_id"]
remaining=data["remaining"]
card_var =
requests.get('https://deckofcardsapi.com/api/deck/'+deckid+'/draw/?
count=1')
print(card_var.text)
carddata = card_var.json()
Thank you very much for your help.

You can access card image with :
carddata['cards'][0]['image']

what about carddata['cards'][0]['images']?
More specifically, carddata['cards'][0]['images']['svg'], and
carddata['cards'][0]['images']['png'] will return individual formats, svg and png links.

for card in data['cards']:
print 'card code is %s' % card['code']
for ext in card['images']:
print '%s image url is %s' % (ext, card['images'][ext])

Related

Firebase delete method

i have a json in Realtime firebase that look something like that :
{
"-NMtZNTISnGhT-rdibeb": {
"motorista": "Jose",
"plate": "IZC2F45",
"produto": "caroco",
"transp": "VIDAL"
},
"-NN1zI2MHFtbi6G5qUvR": {
"motorista": "ANTONIO",
"plate": "AWJ-9353",
"produto": "CAROCO",
"transp": "GRANLIDER"
}
}
I'm working with a python code that sould delete a select line from a Treeview(Tkinter) and also delete from this database. The method Delete is called from a Button(tkinter). Actually he delete only the select line from Treeview, but don't delete from database.
def delete(self):
selected_item = self.tree.selection()
if selected_item:
id = self.tree.item(selected_item, "text")
url = self.base_url + id + '.json'
response = requests.delete(url)
print(url)
print(response)
if response.status_code == 200:
self.tree.delete(selected_item)
messagebox.showinfo("Info", "Linha deletada com sucesso!")
else:
messagebox.showerror("Erro", "Não foi possível deletar a linha!")
else:
messagebox.showerror("Erro", "Nenhum item selecionado para deletar!")
also, i made 2 prints to check what he gave me. and this is what i got from prints:
ttps://fila2-6bd6b-default-rtdb.firebaseio.com/-NNh38XBrRen17bGWHga.json
<Response [200]>
already tried chatgpt, reddit. Already check the Rules from laboratory in firebase and he allowed to use Delete, get, update.
https://github.com/ChristopherMachad/truckQueueOnline/blob/main/Main.py

How to validate payload for facebook whatsapp webhook in AWS Lambda?

I am trying to validate facebook's webhook payload using the instruction they have given in their developer docs. The signature I am generating (expectedHash) is not matching the signature that I am receiving from Facebook (signatureHash). I think I am following what they are saying but I am doing something wrong which I cannot pinpoint yet.
Validating Payloads
We sign all Event Notification payloads with a SHA256 signature and
include the signature in the request's X-Hub-Signature-256 header,
preceded with sha256=. You don't have to validate the payload, but you
should.
To validate the payload:
Generate a SHA256 signature using the payload and your app's App Secret.
Compare your signature to the signature in the X-Hub-Signature-256 header (everything after sha256=).
If the signatures match, the payload is genuine.
Please note that we generate the signature using an escaped unicode
version of the payload, with lowercase hex digits. If you just
calculate against the decoded bytes, you will end up with a different
signature. For example, the string äöå should be escaped to
\u00e4\u00f6\u00e5.
Below is my code in lambda
def lambda_handler(event, context):
response = {
"status": 500,
"body" : "failed"
}
print("event is")
print(event)
signature = event["headers"]["X-Hub-Signature-256"]
if(not signature):
return(f"couldn't find {signature} in headers")
else:
elements = signature.split("=")
print("elements is")
print(elements)
signatureHash = elements[1]
print("signature hash is " + str(signatureHash))
app_secret = os.environ.get('APP_SECRET')
print("app_secret is " + str(app_secret))
expectedHash = hmac.new(bytes(app_secret,'utf-8') ,digestmod=hashlib.sha256).hexdigest()
print("expected hash is " + expectedHash)
if(signatureHash != expectedHash):
return response
else:
response["status"] = 200
response["body"] = expectedHash
return response
response I am getting is:
{ "status": 500, "body": "failed" }
expected response:
{ "status": 200, "body": value of expectedHash }
Could you please help me with this?
Edit 1:
Figured out how to do it.
Apparently I was using a wrong content mapping in AWS API Gateway. I needed to use the $input.body to get the raw payload data in the event argument of AWS lambda handler function. My content mapping looks like this:
#set($allParams = $input.params())
{
"method": "$context.httpMethod",
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"body" : $input.body
}
Below is my lambda handler function for validating payload:
def lambda_handler(event, context):
response = {
"status": 500,
"body" : "failed"
}
print("event is")
print(event)
signature = event["params"]["header"]["X-Hub-Signature-256"]
if(not signature):
return(f"couldn't find {signature} in headers")
else:
try:
elements = signature.split("=")
print("elements is")
print(elements)
signatureHash = elements[1]
#print("signature hash is " + str(signatureHash))
app_secret = os.environ.get('APP_SECRET')
key = bytes(app_secret, 'UTF-8')
payload = event['body']
json_string = json.dumps(payload)
print("payload json_string is " + json_string)
expectedHash = hmac.new(key, msg=json_string.encode(), digestmod=hashlib.sha256).hexdigest()
print("expected hash is " + expectedHash)
if(signatureHash != expectedHash):
print(response)
return response
else:
response["status"] = 200
response["body"] = expectedHash
print(response)
return response
except Exception as e:
return e
As of 12/14/2022, the above function works for all webhook fields except messages (which is the one I really need). Trying to figure it out.
This is your code but using Lambda Proxy Integration, so event keys are a bit different, event["body"], is a raw string, then you can parse it to get the elements you need from it, i think that is easier than all the mapping stuff without the lambda proxy:
import os
import json
import hmac
import hashlib
def lambda_handler(event, context):
response = {
'statusCode': '200',
'body' : "OK"
}
print("event is")
print(event)
signature = event["headers"]["X-Hub-Signature-256"]
if(not signature):
response["body"] = (f"couldn't find {signature} in headers")
return response
else:
try:
elements = signature.split("=")
print("elements is")
print(elements)
signatureHash = elements[1]
#print("signature hash is " + str(signatureHash))
app_secret = os.environ.get('APP_SECRET')
key = bytes(app_secret, 'UTF-8')
payload = event['body']
#json_string = json.dumps(payload)
#print("payload json_string is " + json_string)
expectedHash = hmac.new(key, msg=bytes(payload,'UTF-8'), digestmod=hashlib.sha256).hexdigest()
print("expected hash is " + expectedHash)
if(signatureHash != expectedHash):
response["body"] = "eh " + expectedHash + " sh " + signatureHash
print(response)
return response
else:
response["statusCode"] = 200
response["body"] = "Check ok"
print(response)
return response
except Exception as err:
response["body"] = f"Unexpected {err=}, {type(err)=}"
return response

List object has no attribute 'detectedLanguage'

I'm using microsoft azure translator api to detect and translate the language the user is inputting and translating it back to english. After translating it, I'm printing the results in json format, which can be seen here: https://i.stack.imgur.com/Zcq9l.png
Afterwards, I'm trying to print whatever is translated after the 'text:' bit, however, I keep getting an error each time I try to do so. I tried using a for loop and referencing them, but it doesn't work.
Here is the code bit:
path = '/translate'
constructed_url = endpoint + path
params = {
'api-version': '3.0',
'to': ['en']
}
constructed_url = endpoint + path
headers = {
'Ocp-Apim-Subscription-Key': subscription_key,
'Ocp-Apim-Subscription-Region': location,
'Content-type': 'application/json',
'X-ClientTraceId': str(uuid.uuid4())
}
user_input = input("You: ")
body = [{
"text": user_input
}]
request = requests.post(constructed_url, params=params, headers=headers, json=body)
response = request.json()
json_data = json.dumps(response, sort_keys=True, ensure_ascii=False, indent=4, separators=(",", ": "))
print(json_data)
print("Translated Text: " + response.detectedLanguage.translations.text)
The final line is what's causing the error, but I'm not sure how to resolve it. I would appreciate if someone can guide me accordingly.
[1]: https://i.stack.imgur.com/Zcq9l.png
The object is a List of Dictionaries (just one in this case). As seen in the linked image.
In this particular case, to reach the translation text, you need to do:
response[0]["translations"]["text"]

Unable to set category to 'Education' in Upload

I am using Dailymotion python sdk to upload videos to dailymotion. I am unable to set category to 'Education'
Unable to set category to 'Education', works fine if I set it to 'news'.
upload_folder = r"D:\My Folder\Dailymotion\Download_DM\automated_upload"
for file in os.listdir(upload_folder):
try:
d.set_grant_type(
"password",
api_key=_API_KEY,
api_secret=_API_SECRET,
scope=["manage_videos"],
info={"username": _USERNAME, "password": _PASSWORD},
)
# Uploading the file on dailymotion servers
file_path = upload_folder +'\\' + os.path.splitext(file)[0] + ".mp4"
url = d.upload(file_path)
# Filling the information about the video
parameters = {
"url": url,
"title": os.path.splitext(file)[0],
"tags": "life,love,reality,god,spirituality,education,truth,saints,scriptures",
#"description": "my first automatic uplaod",
"published": 1,
"channel": "education"
}
# Sending the information to create the video on dailymotion
result = d.post("/me/videos?fields=id,url", parameters)
print("Uploaded video: ", os.path.splitext(file)[0], "\nDailymotion url: ", result['url'], "\n\n")
except Exception as e:
print("An error occured: %s" % str(e))
Error Message: DailymotionApiError: not_found: Can't find object channel for `channel' parameter
Education is the label of the channel, you have to pass its id which is 'school'.
You can retrieve all the channel ids at this endpoint: https://api.dailymotion.com/channels?fields=id,name

Add entries into JSON

I am working with an API that doesn't have all the information I need in a single call, and I need to the project code it came from into the call that I am making. Right now it appends the project data to the list, but I really need it to be part of the original call. Here is my output now:
[{"committer_email": "justin.m.boucher#example.com", "short_id": "981147b9", "title": "Added .gitignore", "author_email": "justin.m.boucher#example.com", "authored_date": "2017-08-29T08:31:11.000-07:00", "created_at": "2017-08-29T08:31:11.000-07:00", "author_name": "Justin Boucher", "parent_ids": [], "committed_date": "2017-08-29T08:31:11.000-07:00", "message": "Added .gitignore\n", "committer_name": "Justin Boucher", "id": "981147b905913a60796283ce10f915c53679df49"}, {"project_id": "2"}]
Here is the output I want to achieve:
[{"project_id": "2", "committer_email": "justin.m.boucher#example.com", "short_id": "981147b9", "title": "Added .gitignore", "author_email": "justin.m.boucher#example.com", "authored_date": "2017-08-29T08:31:11.000-07:00", "created_at": "2017-08-29T08:31:11.000-07:00", "author_name": "Justin Boucher", "parent_ids": [], "committed_date": "2017-08-29T08:31:11.000-07:00", "message": "Added .gitignore\n", "committer_name": "Justin Boucher", "id": "981147b905913a60796283ce10f915c53679df49"}]
Here is my code so far:
get_commits.py:
import gitlab
import json
gitlab = gitlab.Gitlab()
projects = gitlab.getProjectID()
for i in projects:
api_str = '/projects/' + str(i) + '/repository/commits'
connect = gitlab.connectAPI(apiCall=api_str)
data = json.dumps(connect)
# Append project id to json, since it isn't created
# in the commits from Gitlab
commit = json.loads(data)
commit.append({'project_id': str(i)})
# make it pretty again for Splunk to read
commit = json.dumps(commit)
print commit
gitlab.py
import os
import ConfigParser
import requests
import json
# Setup Splunk Environment
APPNAME = 'splunk_gitlab'
CONFIG = 'appconfig.conf'
SPLUNK_HOME = os.environ['SPLUNK_HOME']
parser = ConfigParser.SafeConfigParser()
class Gitlab():
# # Load Settings
# parser.read(SPLUNK_HOME + '/etc/apps/' + APPNAME + '/local/' + CONFIG)
# if parser.has_section('Authentication'):
# pass
# else:
# parser.read(SPLUNK_HOME + '/etc/apps/' + APPNAME + '/default/' + CONFIG)
#
# GITLAB_URL = parser.get('Authentication', 'GITLAB_URL')
# API_KEY = parser.get('Authentication', 'API_KEY')
# Used for testing only
GITLAB_URL = 'http://<my_address>'
API_KEY = '<my_key>'
API_SERVER = GITLAB_URL + '/api/v4'
# Place api call to retrieve data
def connectAPI(self, apiCall='/projects'):
headers = {
'PRIVATE-TOKEN': self.API_KEY
}
final_url = self.API_SERVER + apiCall
resp = requests.get(final_url, headers=headers)
status_code = resp.status_code
resp = resp.json()
if status_code == 200:
return resp
else:
raise Exception("Something went wrong requesting (%s): %s" % (
resp['errors'][0]['errorType'], resp['errors'][0]['message']))
def getProjectID(self):
connect = self.connectAPI(apiCall='/projects')
data = json.dumps(connect)
projects = json.loads(data)
project_list = []
for i in projects:
project_list.append(i['id'])
return project_list
If you want to add a new element to the first dictionary in the list instead of appending a new dictionary to the list, try using assignment instead of append.
commit[0]['project_id'] = str(i)

Categories

Resources