How to extract an attribute from a json response using python - python

I am using the face++ API, I need to get an attribute from the first request(json_resp) to add it in the second one (json_resp2)
import requests
json_resp = requests.post( 'https://api- us.faceplusplus.com/facepp/v3/detect',
data = { 'api_key' : 'api key' ,
'api_secret' : 'api secret',
'image_url' : 'http://www.pick-health.com/wp-content/uploads/2013/08/happy-person.jpg' } )
print("Response : ", json_resp.text)
This request outputs:
Response : {"image_id": "0UqxdZ6b58TaAFxBiujyMA==", "request_id": "1523139597,9f47c376-481b-446f-9fa3-fb49e404437c", "time_used": 327, "faces": [{"face_rectangle": {"width": 126, "top": 130, "left": 261, "height": 126}, "face_token": "2da210ada488fb10b58cdd2cd9eb3801"}]}
I need to access the face_token to pass it to the second request:
json_resp2 = requests.post( 'https://api-us.faceplusplus.com/facepp/v3/face/analyze',
data = { 'api_key' : 'api key' ,
'api_secret' : 'api secret',
'face_tokens' : 'json_resp.face_tokens',
'return_landmark':0,
'return_attributes':'emotion'} )
print("Response2 : ", json_resp2.text)
how can I do this please ?

To get the text string from the response object, you can use json_resp.text. You can then use the json library to convert this into a dict, and then extract the field you want:
json_resp = requests.post(...) ## Your post request, as written above
node = json.loads(json_resp.text)
face_token = node['faces'][0]['face_token']
Here is the full code (using your snippets above):
import requests
import json
api_key = 'your api key'
api_secret = 'your api secret'
json_resp = requests.post(
'https://api-us.faceplusplus.com/facepp/v3/detect',
data = {
'api_key' : api_key,
'api_secret' : api_secret,
'image_url' : 'http://www.pick-health.com/wp-content/uploads/2013/08/happy-person.jpg'
}
)
node = json.loads(json_resp.text)
face_token = node['faces'][0]['face_token']
json_resp2 = requests.post(
'https://api-us.faceplusplus.com/facepp/v3/face/analyze',
data = {
'api_key' : api_key,
'api_secret' : api_secret,
'face_tokens' : face_token,
'return_landmark' : 0,
'return_attributes' : 'emotion'
}
)
print("Response2 : ", json_resp2.text)
PS: It's a bad idea to post API keys online, since people can run your bill up by using your services.

Related

How to export offer file from Bol Retailer API using Python

I have been trying to export offer file using Python for Bol Retailer API
According to the official docs on request an offer file export
I have include all the headers and formats but it throws a 400 Bad Request
400
Bad Request
b'{\n "type" : "https://api.bol.com/problems",\n "title" : "Bad Request",\n "status" : 400,\n "detail" : "The supplied content-type media type is not supported.",\n "host" : "Instance-111",\n "instance" : "https://api.bol.com/retailer/offers/export"\n}'
Here is a minimal example from my code
import base64
import requests
import json
import time
class BolService:
def __init__(self, _id, secret):
self.host = "https://api.bol.com"
self.__header = {
"Accept": "application/vnd.retailer.v7+json",
"Content-Type": "N/A",
"Authorization": "Bearer " + self.__get_token(_id, secret)
}
def __get_token(self, _id, secret) -> str:
creds = (_id + ":" + secret).encode('ascii') #creds : ascii bytes
creds_b64_b = base64.b64encode(creds) #creds : base64 bytes
creds_b64 = creds_b64_b.decode('ascii') #creds : base64 string
header = {
"Authorization":"Basic " + creds_b64
}
link = "https://login.bol.com/token?grant_type=client_credentials"
response = requests.post(link, headers=header)
response_data = json.loads(response.content.decode())
return response_data['access_token']
def get_offer_file(self):
path = f"/retailer/offers/export"
new_header = self.__header.copy()
new_header["format"] = "CSV"
response = requests.post(self.host + path, headers=new_header)
return response
Note: I have also tried changing the "Content-Type" in self.__header to "application/vnd.retailer.v7+json", I have also changed the same to add csv using "application/vnd.retailer.v7+json+csv" or "application/vnd.retailer.v7+csv". I have also tried adding self.__header['Content-Type'] = 'text/csv' but nothing seems to work it keeps on throwing the same Bad Request. I have also tried using the v6 of the API instead of v7 but same issue.
I know this is something that should be dealt with the customer service of Bol but they their service is too pathetic to even give a simple reply. Also as of August 2022 their site which details API issues is down. Maybe if someone with experience can help here.
I don't think I am missing anything here. Please let me know.
So I was able to sucessfully make the POST request.
1st what I did was change the "Content-Type" in self.__header to "application/vnd.retailer.v7+json"
so the header now looks like this
self.__header = {
"Accept": "application/vnd.retailer.v7+json",
"Content-Type": "application/vnd.retailer.v7+json",
"Authorization": "Bearer " + self.__get_token(_id, secret)
}
Since we require the content type in JSON format so we have to include a JSON body by dumping our dictionary content using json.dumps
So the get_offer_file method now looks like with {"format":"CSV"} as the body
def get_offer_file(self):
path = f"/retailer/offers/export"
response = requests.post(self.host + path, headers=self.__header, data=json.dumps({"format":"CSV"}))
return response
Here is the full code:
import base64
import requests
import json
class BolService:
def __init__(self, _id, secret):
self.host = "https://api.bol.com"
self.__header = {
"Accept": "application/vnd.retailer.v7+json",
"Content-Type": "application/vnd.retailer.v7+json",
"Authorization": "Bearer " + self.__get_token(_id, secret)
}
def __get_token(self, _id, secret) -> str:
creds = (_id + ":" + secret).encode('ascii') #creds : ascii bytes
creds_b64_b = base64.b64encode(creds) #creds : base64 bytes
creds_b64 = creds_b64_b.decode('ascii') #creds : base64 string
header = {
"Authorization":"Basic " + creds_b64
}
link = "https://login.bol.com/token?grant_type=client_credentials"
response = requests.post(link, headers=header)
response_data = json.loads(response.content.decode())
return response_data['access_token']
def get_offer_file(self):
path = f"/retailer/offers/export"
response = requests.post(self.host + path, headers=self.__header, data=json.dumps({"format":"CSV"}))
return response

New Twitch API getting json data Python 3

I am trying to get a python script to say whether a twitch channel is live but haven't been able to do it, any and all help would be appreciated.
here are the docs I've been able to find
https://dev.twitch.tv/docs/api/guide
This is what I have atm but I keep on getting "'set' object has no attribute 'items'". This is modified code from "Is There Any Way To Check if a Twitch Stream Is Live Using Python?" however it is now outdated because of the new API.
import requests
def checkUser():
API_HEADERS = {
'Client-ID : [client id here from dev portal]',
'Accept : application/vnd.twitchtv.v5+json',
}
url = "https://api.twitch.tv/helix/streams/[streamer here]"
req = requests.Session().get(url, headers=API_HEADERS)
jsondata = req.json()
print(jsondata)
checkUser()
The answer to your problem of "'set' object has no attribute 'items'" is just a simple typo. It should be
API_HEADERS = {
'Client-ID' : '[client id here from dev portal]',
'Accept' : 'application/vnd.twitchtv.v5+json'
}
Notice how the Colon's aren't part of the text now
And to answer your overarching question of how to tell if a channel is online you can look at this sample code I made.
import requests
URL = 'https://api.twitch.tv/helix/streams?user_login=[Channel_Name_Here]'
authURL = 'https://id.twitch.tv/oauth2/token'
Client_ID = [Your_client_ID]
Secret = [Your Client_Secret]
AutParams = {'client_id': Client_ID,
'client_secret': Secret,
'grant_type': 'client_credentials'
}
def Check():
AutCall = requests.post(url=authURL, params=AutParams)
access_token = AutCall.json()['access_token']
head = {
'Client-ID' : Client_ID,
'Authorization' : "Bearer " + access_token
}
r = requests.get(URL, headers = head).json()['data']
if r:
r = r[0]
if r['type'] == 'live':
return True
else:
return False
else:
return False
print(Check())

Signed request with python to binance future

I have been struggling to send a signed request to binance future using signature.
I found that example code on StackOverflow ("Binance API call with SHA56 and Python requests") and an answer has been given to it mentioning to use hmac
as below: but unfortunately i still don't see how to write this example. Could anyone show how the code of this example should look like? i am really uncomfortable with signed request. Thanks a lot for your understanding and your help advice given:
params = urlencode({
"signature" : hashedsig,
"timestamp" : servertimeint,
})
hashedsig = hmac.new(secret.encode('utf-8'), params.encode('utf-8'), hashlib.sha256).hexdigest()
Original example:
import requests, json, time, hashlib
apikey = "myactualapikey"
secret = "myrealsecret"
test = requests.get("https://api.binance.com/api/v1/ping")
servertime = requests.get("https://api.binance.com/api/v1/time")
servertimeobject = json.loads(servertime.text)
servertimeint = servertimeobject['serverTime']
hashedsig = hashlib.sha256(secret)
userdata = requests.get("https://api.binance.com/api/v3/account",
params = {
"signature" : hashedsig,
"timestamp" : servertimeint,
},
headers = {
"X-MBX-APIKEY" : apikey,
}
)
print(userdata)
The proper way would be:
apikey = "myKey"
secret = "mySecret"
servertime = requests.get("https://api.binance.com/api/v1/time")
servertimeobject = json.loads(servertime.text)
servertimeint = servertimeobject['serverTime']
params = urlencode({
"timestamp" : servertimeint,
})
hashedsig = hmac.new(secret.encode('utf-8'), params.encode('utf-8'),
hashlib.sha256).hexdigest()
userdata = requests.get("https://api.binance.com/api/v3/account",
params = {
"timestamp" : servertimeint,
"signature" : hashedsig,
},
headers = {
"X-MBX-APIKEY" : apikey,
}
)
print(userdata)
print(userdata.text)
Make sure to put the signature as the last parameter or the request will return [400]...
Incorrect:
params = {
"signature" : hashedsig,
"timestamp" : servertimeint,
}
Correct:
params = {
"timestamp" : servertimeint,
"signature" : hashedsig,
}
At the time of writing, Binance themselves are mainting a repo with some examples*, using the requests library. Here is a sample in case the link goes down or is moved:
import hmac
import time
import hashlib
import requests
from urllib.parse import urlencode
KEY = ''
SECRET = ''
# BASE_URL = 'https://fapi.binance.com' # production base url
BASE_URL = 'https://testnet.binancefuture.com' # testnet base url
''' ====== begin of functions, you don't need to touch ====== '''
def hashing(query_string):
return hmac.new(SECRET.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
def get_timestamp():
return int(time.time() * 1000)
def dispatch_request(http_method):
session = requests.Session()
session.headers.update({
'Content-Type': 'application/json;charset=utf-8',
'X-MBX-APIKEY': KEY
})
return {
'GET': session.get,
'DELETE': session.delete,
'PUT': session.put,
'POST': session.post,
}.get(http_method, 'GET')
# used for sending request requires the signature
def send_signed_request(http_method, url_path, payload={}):
query_string = urlencode(payload)
# replace single quote to double quote
query_string = query_string.replace('%27', '%22')
if query_string:
query_string = "{}&timestamp={}".format(query_string, get_timestamp())
else:
query_string = 'timestamp={}'.format(get_timestamp())
url = BASE_URL + url_path + '?' + query_string + '&signature=' + hashing(query_string)
print("{} {}".format(http_method, url))
params = {'url': url, 'params': {}}
response = dispatch_request(http_method)(**params)
return response.json()
# used for sending public data request
def send_public_request(url_path, payload={}):
query_string = urlencode(payload, True)
url = BASE_URL + url_path
if query_string:
url = url + '?' + query_string
print("{}".format(url))
response = dispatch_request('GET')(url=url)
return response.json()
response = send_signed_request('POST', '/fapi/v1/order', params)
print(response)
Some additional thoughts from myself:
You can also use a new library also from Binance called Binance connector. It is a bit new, it has some issues, but it can do the basic operations without you worrying about signed requests.
I wouldn't use serverTime because that means you need to make an additional request and networks can be slow, I'd follow this example and use the int(time.time() * 1000) you may not even need the function.
I purposedly used the POST example, because this is more complicated as you need to also encode and hash your custom parameters
At the time of writing, v3 is the latest version
Hope it helps.
* https://github.com/binance/binance-signature-examples/blob/master/python/futures.py

Convert a column of json strings into columns of data (API Result / Output)

I have the exact same request as below:
Convert a column of json strings into columns of data
Following the suggested solutions and getting the following error: What am I doing incorrectly? I'm learning to use python and make API requests.
***df['json'] = df['json'].map(address',': dict(eval(address)))***
^
`**SyntaxError: invalid syntax**
Below is my code
import requests
import json
import pandas as pd
import dictionary as dict
Base_url = 'MY_URL'
TOKEN_EndPoint = Base_url + 'token'
Account_EndPoint = Base_url + 'MY_URL'
data = {
'username': 'MY_USERNAME',
'password': 'MY_PASSWORD',
'grant_type': 'MY_GRANT_TYPE'
}
def main():
results = requests.post(url=TOKEN_EndPoint, data=data)
MyToken = results.json()['access_token']
print(MyToken)
MyInputs = GetSourceAddress()
callData = {
'ClientKey': 'MY_CLIENTKEY',
'StreetName': MyInputs['StreetName'],
'CityName' : MyInputs['CityName'],
# 'StateCode' : MyInputs['StateCode'],
'PostalCode' : MyInputs['PostalCode'],
'ManagerVersion': '2'
}
PostFields = json.dumps(callData)
MyHeader = {'Authorization': 'Bearer ' + MyToken,
'content-type': 'application/json'}
results = requests.post(url = Account_EndPoint, data = PostFields,
headers = MyHeader)
address = results.json()
# results.json() = pd.DataFrame(address)
df = pd.DataFrame(['address'], columns=['json'])
**df['json'] = df['json'].map(address',': dict(eval(address)))**
address = df['json'].apply(pd.Series)
for address in address:
print(address)
def GetSourceAddress():
MyInputs = {
'StreetName': 'MY_STREETNAME',
'CityName': 'MY_CITYNAME',
# 'StateCode': 'MY_STATE',
'PostalCode': 'MY_ZIPCODE',
# 'Unit': 'UNIT #'
}
return MyInputs
def GetAddressFrom****(result):
inputs = {
'StreetName': result['ShippingStreet'],
'CityName': result['BillingCity'],
'StateCode': result['BillingState'],
'PostalCode': result['BillingPostalCode'],
# 'Unit': ''
}
return inputs
main()
Thanks

How to send file through Mattermost incoming webhook?

I am able to send text to Mattermost channel through incoming webhooks
import requests, json
URL = 'http://chat.something.com/hooks/1pgrmsj88qf5jfjb4eotmgfh5e'
payload = {"channel": "general", "text": "some text"}
r = requests.post(URL, data=json.dumps(payload))
this code simplly post text. I could not find a way to post file to channel. Suppose I want to post file located at /home/alok/Downloads/Screenshot_20170217_221447.png. If anyone know please share.
You can't currently attach files using the Incoming Webhooks API. You would need to use the Mattermost Client API to make a post with files attached to it.
Here's an example of how you could achieve that (using Mattermost API v3 for Mattermost >= 3.5)
SERVER_URL = "http://chat.example.com/"
TEAM_ID = "team_id_goes_here"
CHANNEL_ID = "channel_id_goes_here"
USER_EMAIL = "you#example.com"
USER_PASS = "password123"
FILE_PATH = '/home/user/thing_to_upload.png'
import requests, json, os
# Login
s = requests.Session() # So that the auth cookie gets saved.
s.headers.update({"X-Requested-With": "XMLHttpRequest"}) # To stop Mattermost rejecting our requests as CSRF.
l = s.post(SERVER_URL + 'api/v3/users/login', data = json.dumps({'login_id': USER_EMAIL, 'password': USER_PASS}))
USER_ID = l.json()["id"]
# Upload the File.
form_data = {
"channel_id": ('', CHANNEL_ID),
"client_ids": ('', "id_for_the_file"),
"files": (os.path.basename(FILE_PATH), open(FILE_PATH, 'rb')),
}
r = s.post(SERVER_URL + 'api/v3/teams/' + TEAM_ID + '/files/upload', files=form_data)
FILE_ID = r.json()["file_infos"][0]["id"]
# Create a post and attach the uploaded file to it.
p = s.post(SERVER_URL + 'api/v3/teams/' + TEAM_ID + '/channels/' + CHANNEL_ID + '/posts/create', data = json.dumps({
'user_id': USER_ID,
'channel_id': CHANNEL_ID,
'message': 'Post message goes here',
'file_ids': [FILE_ID,],
'create_at': 0,
'pending_post_id': 'randomstuffogeshere',
}))
I have done a version for API v4, with the use of a personal access token. https://docs.mattermost.com/developer/personal-access-tokens.html
import os
import json
import requests
SERVER_URL = "YOUR_SERVER_URL"
CHANNEL_ID = "YOUR_CHANNEL_ID"
FILE_PATH = './test.jpg'
s = requests.Session()
s.headers.update({"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"})
form_data = {
"channel_id": ('', CHANNEL_ID),
"client_ids": ('', "id_for_the_file"),
"files": (os.path.basename(FILE_PATH), open(FILE_PATH, 'rb')),
}
r = s.post(SERVER_URL + '/api/v4/files', files=form_data)
FILE_ID = r.json()["file_infos"][0]["id"]
p = s.post(SERVER_URL + '/api/v4/posts', data=json.dumps({
"channel_id": CHANNEL_ID,
"message": "YOUR_MESSAGE",
"file_ids": [ FILE_ID ]
}))
EDIT:
I have created a simple CLI.
https://github.com/Tim-Schwalbe/python_mattermost
as per #George , you cann't sent the file to the incoming webhook directly.
below is code to send the file to the channel
from mattermostdriver import Driver
team_name = "<name of your team in mattermost>"
channel_name = "<channel name>" # name of channel which you want to upload document
file_path = "<file to uploaded >" # name of the file to upload
message = "<message to sent on channel>"
options = {
"url": "", # url of your mattermost acocunt https://<url>
"port": 8065, # port of the website
"password": "<account password>",
"login_id": "<login id>",
"token": None
}
x = Driver(options=options)
# loggin into the mattermost server
x.login()
# getting team id
team_id = x.teams.get_team_by_name(team_name)['id']
# getting channel id
channel_id = x.channels.get_channel_by_name(team_id, channel_name)['id'] # give channel id
#setting up the options
form_data = {
"channel_id": ('', channel_id),
"client_ids": ('', "id_for_the_file"),
"files": (file_path, open(file_path, 'rb'))
}
pp = x.files.upload_file(channel_id, form_data)
file_id = pp['file_infos'][0]['id']
# uploading the file
x.posts.create_post({'channel_id': channel_id, "message": message, "file_ids": [file_id]})
# logout from the server
x.logout()

Categories

Resources