How to get temporary AWS credentials via Cognito Identity Pool - python

I am looking to get temporary AWS credentials through a Cognito Identity Pool to send data to a Kinesis stream through API Gateway. One thing to note is that I am trying to do this without an AWS SDK because the language it will be written in eventually does not have a compatible SDK. I am testing the solution in Python and seem to be missing something as I keep getting a 400 error. Any ideas of what I am doing wrong here?
import requests
url = 'https://cognito-identity.us-east-1.amazonaws.com' #cognito regional endpoint
headers = {
'X-AMZ-TARGET': 'com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetCredentialsForIdentity',
'X-AMZ-DATE': '20151020T232759Z'
}
body = {
'IdentityId': 'us-east-1:123456789' #identity id
}
response = requests.post(url = url, data = body, headers = headers)
print(response)

I was able to resolve the issue by adding a content type header, converting the single quotes in the body to double quotes, and wrapping the body dictionary in quotes as well.
import requests
url = 'https://cognito-identity.us-east-1.amazonaws.com' #cognito regional endpoint
headers = {
"CONTENT-TYPE": "application/x-amz-json-1.1",
"X-AMZ-TARGET": "com.amazonaws.cognito.identity.model.AWSCognitoIdentityService.GetCredentialsForIdentity",
"X-AMZ-DATE": "20151020T232759Z"
}
body = '''{
"IdentityId": "123456789"
}'''
response = requests.post(url = url, data = body, headers = headers)
print(response.text)

Related

Python / Binance API - How to scrape Binance Leaderboard futures position from API?

I would like to know how to scrape data (position, name of the trader, symbol,..)from the Binance leaderboard with Python and Binance API.
Thanks for your answers !
This is my actual code wiche doesn't work.
from binance.client import Client, AsyncClient
api_key = 'xxx'
api_secret = 'xxx'
client = Client(api_key, api_secret)
leaderboard = client.futures_leaderboard()['positions']
I tried the code juste above, but there is no results.
You can use this third party API. Remember to check its documentation.
Here is an example of code to achieve what I think you want:
Getting traders:
import requests
# API URL with its endpoint to use
url = "https://binance-futures-leaderboard1.p.rapidapi.com/v2/searchLeaderboard"
# Parameters to use
querystring = {
"isShared": True, # Set to true if you want to get traders sharing their positions
"limit": 10 # Total traders to get
}
# Headers to use
headers = {
"X-RapidAPI-Key": "YOUR-API-KEY",
"X-RapidAPI-Host": "binance-futures-leaderboard1.p.rapidapi.com"
}
# Get response
response = requests.get(url, headers=headers, params=querystring)
# Print response to JSON
print(response.json())
Getting trader positions:
import requests
# Now we use the endpoint to get the positions shared by a trader
url = "https://binance-futures-leaderboard1.p.rapidapi.com/v2/getTraderPositions"
# Parameters to use
querystring = {
"encryptedUid": "<REQUIRED>", # Trader UUID
"tradeType": "PERPETUAL" # Set to PERPETUAL to get USDⓈ-M positions
}
# Parameters to use
headers = {
"X-RapidAPI-Key": "YOUR-API-KEY",
"X-RapidAPI-Host": "binance-futures-leaderboard1.p.rapidapi.com"
}
# Get response
response = requests.get(url, headers=headers, params=querystring)
# Print response to JSON
print(response.json())
You have to fill in the api key and secret
How to Create API
Creating an API allows you to connect to Binance’s servers via several
programming languages.

Send image in request from python

I am trying to upload an image using POST request. From Postman, it is giving success but when I try same code from python, I am getting an error (payload validation failed). Following is my code in python:
import requests
url = "http://10....."
payload = {}
files=[('pdf_file',('passport.jpg', open('/D:/passport.jpg','rb'), 'image/jpeg'))]
headers = {
'accept':'application/json',
'Content-Type':'multipart/form-data',
'Authorization':'<token_here>',
}
response = requests.request("POST", url, headers = headers, data = payload, files = files)
print(response.text)
While invoking request from postman, headers are same as above code. Select form-data in body section and upload image for key "pdf_file".
Is there any difference in both approaches?
You should omit content type from headers
headers = {
'accept':'application/json',
'Authorization':'<token_here>'
}

Swagger API and interaction with python requests

A product was purchased to enable our users to send/receive SMS over HTTP. Now it's my job to build it into our current CMS platform & database. It's got a swagger API.
Here is the documentation for the specific POST request I am trying to send:
POST: Send an SMS Message
Here is my simple python program to test the functionality. I get a generic 500 internal server error response. What am I doing incorrectly?
import requests
API_URL = "https://api.kenect.com/v1/conversations/messages"
headers = {
'x-api-token': '****************',
'x-api-key': '*******************',
'Content-Type': 'application/json',
}
params = {
'contactPhone': '158572968**',
'locationId': '2045',
'messageBody': 'test sms',
'outgoing': 'true',
}
r=requests.post(url = API_URL, headers = headers, params = params)
print(r)
There seems to be 2 issues:
Content type and payload encoding.
You are using params parameter in the post method. params is used with get method for passing data in the URL's query string.
In the post method, depending on the required content type, you need to use either data parameter to send form-encoded data:
r=requests.post(url = API_URL, headers = headers, data = params)
or json parameter to send application/json payload:
r=requests.post(url = API_URL, headers = headers, json = params)
Remove the 'Content-Type' key from your headers dictionary. data and json parameters will set up correct content type automatically.
outgoing is not a valid request parameter for the /v1/conversations/messages resource. This field is from the response object, not the request one. Remove it from your payload.
So to sum up, for form-encoded payload the code should look like this:
import requests
API_URL = "https://api.kenect.com/v1/conversations/messages"
headers = {
'x-api-token': '****************',
'x-api-key': '*******************',
}
params = {
'contactPhone': '158572968**',
'locationId': '2045',
'messageBody': 'test sms',
}
r=requests.post(url = API_URL, headers = headers, data = params)

Trying to query an API from AWS Lambda

I'm trying to query an open source API that returns IP geolocation information by sending a GET request with the IP.
I'm testing the code with a key that contains an IP address (located in key1). I'm trying to fetch the information after the request is sent but I'm not sure what I'm doing wrong.
I have tried appending the IP to the end of the url (as the geoip API instructs) but I keep getting syntax errors.
import json
from botocore.vendored import requests
def lambda_handler(resp, requests, event):
event = event.key1
url = "https://freegeoip.app/json/" +event
headers = {
'accept': "application/json",
'content-type': "application/json"
}
response = requests.request("GET", url, headers=headers)
print(response.text)
I have the code working in regular python syntax below, just don't know how to get it working with lambda
import requests
userIP = '54.81.183.174'
def theFunction():
url = "https://freegeoip.app/json/" + userIP
headers = {
'accept': "application/json",
'content-type': "application/json"
}
response = requests.request("GET", url, headers=headers)
print(response.text)
theFunction()
Your code is using the requests module, which is not installed with AWS Lambda.
You can package it for use with an AWS Lambda function (see python - Cannot use Requests-Module on AWS Lambda - Stack Overflow), but it is simpler to use urllib, which is part of standard Python3.
Here is some code that works:
import urllib.request
import json
def lambda_handler(event, context):
ip = event['ip']
with urllib.request.urlopen("https://freegeoip.app/json/" + ip) as f:
data = json.loads(f.read())
print(data)
print(data['city'])
You can trigger it with test data:
{
"ip": "54.81.183.174"
}

Starting a conversation with a chat bot hosted on Microsoft Azure through HTTP request in Python

A Microsoft tutorial shows that in order to set up a conversation with a bot I should issue the following HTTP request:
POST https://directline.botframework.com/api/conversations
Authorization: Bearer SECRET_OR_TOKEN
My question is if I can achieve this with the following Python code:
import requests
r = requests.post('https://directline.botframework.com/api/conversations',
params = {'Authorization':'Bearer ftmhNAqZ2tw.cwA.qIA.Xz2ZWfYJzxd8vJjcK9VmINWNLxlvKiM5jC8F_cbaf0s'})
If I print the response with print(r.content) it says:
{ "error": {
"code": "BadArgument",
"message": "Missing token or secret" } }
HTTP requests have three areas where content can be sent:
URL parameters
Body
Headers
To set these in python's requests package the following can be used (POST method assumed, but all are the same):
URL Parameters:
requests.post('https://myurl.com', params = {'MyParam':'MyValue'})
# equivilient to http://myurl.com?MyParam=MyValue
Body:
requests.post('https://myurl.com', data={"key":"value"})
# or if sending json data
requests.post('https://myurl.com', data=json.dumps(myData))
Headers:
requests.post('https://myurl.com', headers={"headername":"value"})
In your specific case, while the API is not well documented - we can assume they expect the "Authorization" data to be sent in a header, as this is standard. In this case, you need to assign headers as follows:
requests.post('https://directline.botframework.com/api/conversations', headers={'Authorization':'Bearer ftmhNAqZ2tw.cwA.qIA.Xz2ZWfYJzxd8vJjcK9VmINWNLxlvKiM5jC8F_cbaf0s'})
The bearer token needs to be sent as a header, not as a payload or query parameter.
You need to use the headers argument:
auth = {'Authorization': 'Bearer xxxYourBearerTokenHerexxx'}
r = requests.post('https://directline.botframework.com/api/conversations', headers=auth)
print(r) # <Response [200]>

Categories

Resources