Requests for Instagram Access token - json

I am working on Instagram API in Django(python)
I am getting code from
'https://api.instagram.com/oauth/authorize/?client_id=%s&response_type=code&redirect_uri=%s' % (INSTAGRAM_APP_CONSUMER_KEY, redirect_uri)
but when i am exchanging code for access token code is failing
# All arguments are valid
def execute(self, code, redirect_uri, app_id, app_secret):
exchange_url = 'https://api.instagram.com/oauth/access_token'
try:
#Update : get request to post
r = requests.post(exchange_url, params={
'client_id': app_id,
'redirect_uri': redirect_uri,
'client_secret': app_secret,
'code': code,
'grant_type': 'authorization_code'
})
#print(r)
#print(json.loads(r))
print(r.json())
return r.json()
except Exception as e:
print(e)
r.json() gives simplejson.scanner.JSONDecodeError: Expecting value: line 1 column 1
Update 1 : r.json() works after request changed from get to post but error
message comming 'You must provide a client_id'
Please let me know what i am doing wrong

I think it requires data in post data, not in query params.
Try this :
your_post_data = {'client_id': '', ... }
r = requests.post('your_url', data=your_post_data)
Ref: Python Requests Docs

Related

809: unexpected token at '' (JSON parser error ruby3.0.4 mac os catalina

I have just started learning ruby and trying to learn extracting web data. I am using samplewebapp code given in a sites API documentation
On executing the test.rb file as given below it generates a token.
The token.json file contains the following
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIzY2U1NjFhMC01ZmE5LTQ5NjUtYTQ2Mi01NmI2MzEzNjRlZGMiLCJqdGkiOiJmMjc0ZTgwM2FmZjVlMTFiMTAzNzIwMzAwNzRlNDRhZDE3ODg3ZjAzOGQ2ODk0OWIwNzVkMmQ5N2E2MjAwYzc5ZWRhNzU4MmQ3MTg1MTc1YiIsImlhdCI6MTY1NDU2OTc0MS41MjgxNTUsIm5iZiI6MTY1NDU2OTc0MS41MjgxNTcsImV4cCI6MTY1NDU3MzM0MS41MjgwMzksInN1YiI6IjE5NGFlNTU5LTU5OWMtNDQ2ZC1hOTRhLWM2MTIyYjZkMTA2ZiIsInNjb3BlcyI6W10sImNyZWRpdHNfcmVtYWluaW5nIjo0NzAwLCJyYXRlX2xpbWl0cyI6W3sicmF0ZSI6NSwiaW50ZXJ2YWwiOjYwfV19.XoN5A-H8Z7d8p_0e2rCcyV4yWO9MAF3TZlHk5VP5NjUEqtTXTVYKfKuzidYDs7K8ZzAtWzyt3aR5VSUG0_nw-uPd7Z3_Y75alQMqa2b5rHGn5JFWH7nuAriskr26WSCqAdj4cNjccPORryRr5sYKwpE4Y4kTG0IX_8frvwYxwp-8wFpLLj98K3axwN7CCpWdnPDSzuMqmH6tSpF0XhdYxB5LTVH0AyH7lN0S0_Lftq0b3sOLIvEaTfNkuRGNqwLkBYFkHFuPqwrKd8RJhC2W1QZhrmUw3eYnh-0iQABGk2V0skIqDlb6BbQ5GFX6MXgiXAc-h5Ndda7pZ5N5UCQU3g","expires_at":1654573341}
However it also generates a JSON parser error as under
/Users/mm/.rbenv/versions/3.0.4/lib/ruby/3.0.0/json/common.rb:216:in `parse': 809: unexpected token at '' (JSON::ParserError)
from /Users/mm/.rbenv/versions/3.0.4/lib/ruby/3.0.0/json/common.rb:216:in `parse'
from /Users/mm/Desktop/prokerala/client.rb:21:in `parseResponse'
from /Users/mm/Desktop/prokerala/client.rb:99:in `get'
I googled around for a while and some of the responses talk about the issues between double and single quotes.. I tried changing those also but it doesn't work.
I have also tried running it with system ruby - which gives a different error
Would appreciate very much if someone could explain what the error is / logic behind this.. Also I am not clear about the error message itself. The message talks about parse error 809:"unexpected token" on column no 809 of the token there is nothing.. Am i reading it wrong?
code used in test.rb file
client = ApiClient.new('YOUR CLIENT_ID', 'YOUR CLIENT_SECRET');
result = client.get('v2/astrology/thirumana-porutham/advanced', {
:girl_nakshatra => 4,
:girl_nakshatra_pada => 2,
:boy_nakshatra => 26,
:boy_nakshatra_pada => 3
})
puts JSON.pretty_generate(result)
code used in client.rb file
require 'net/http'
require 'json'
class ApiError < StandardError
end
class ApiClient
BASE_URL = "https://api.prokerala.com/"
# Make sure that the following file path is set to a location that is not publicly accessible
TOKEN_FILE = "./token.json"
def initialize(clientId, clientSecret)
# Instance variables
#clientId = clientId
#clientSecret = clientSecret
end
def parseResponse(response)
content = response.body
res = JSON.parse(content)
if res.key?('access_token')
return res
end
if res['status'] == "error"
raise ApiError, res['errors'].map {|e| e['detail']}.join("\n")
end
if res['status'] != "ok"
raise "HTTP request failed"
end
return res
end
def saveToken(token)
# Cache the token until it expires.
File.open(ApiClient::TOKEN_FILE,"w") do |f|
token = {
:access_token => token['access_token'],
:expires_at => Time.now.to_i + token['expires_in']
}
f.write(token.to_json)
end
end
def getTokenFromCache
if not File.file?(ApiClient::TOKEN_FILE)
return nil
end
begin
# Fetch the cached token, and return if not expired
text = File.read(ApiClient::TOKEN_FILE)
token = JSON.parse(text)
if token['expires_at'] < Time.now.to_i
return nil
end
return token['access_token']
rescue JSON::ParserError
return nil
end
end
def fetchNewToken
params = {
:grant_type => 'client_credentials',
:client_id => #clientId,
:client_secret => #clientSecret
}
res = Net::HTTP.post_form(URI(ApiClient::BASE_URL + 'token'), params)
token = parseResponse(res)
saveToken(token)
return token['access_token']
end
def get(endpoint, params)
# Try to fetch the access token from cache
token = getTokenFromCache
# If failed, request new token
token ||= fetchNewToken
uri = URI(ApiClient::BASE_URL + endpoint)
uri.query = URI.encode_www_form(params)
req = Net::HTTP::Get.new(uri.to_s, {'Authorization' => 'Bearer ' + token})
res = Net::HTTP.start(uri.hostname) do |http|
http.request(req)
end
return parseResponse(res)
end
end
running the test file using ruby 3.0.4 gives the a JSON parse error. Full error reproduced as below
/Users/mm/.rbenv/versions/3.0.4/lib/ruby/3.0.0/json/common.rb:216:in `parse': 809: unexpected token at '' (JSON::ParserError)
from /Users/mm/.rbenv/versions/3.0.4/lib/ruby/3.0.0/json/common.rb:216:in `parse'
from /Users/mm/Desktop/prokerala/client.rb:21:in `parseResponse'
from /Users/mm/Desktop/prokerala/client.rb:99:in `get'
from test.rb:11:in `<main>'
I executed the above code and from this, we are getting
#<Net::HTTPMovedPermanently 301 Moved Permanently readbody=true> as response
and response body as empty string '', which results in error in parsing the body.
Since, API endpoint is secure with https, we need set use_ssl: true before starting the session. Try below code and it will fix the issue.
res = Net::HTTP.start(uri.hostname, use_ssl: true) do |http|
http.request(req)
end

Pass variable into Step Function start_execution() input parameter

I am using boto3 with Python 3.6 to start a Step Function execution. The Step Function is designed to share my base AMI across all my accounts. I have 4 variables I need to pass to the input parameter to kick off the execution. These are the AMI ID, the account list of accounts I own, the source account, and the KMS key. The AMI ID and the account list are constructed in my code and are the variables that need to get passed dynamically. According to the documentation, input is a string that contains the JSON input data for the execution and gives the following example: "input": "{\"ami_id\" : \"ami_id\"}". My question is how do I pass the variables in question to this parameter as the value? My code is below with the traceback:
CODE:
import boto3
import json
# Get an STS token to assume roles into AWS accounts
def get_sts_token(**kwargs):
role_arn = kwargs['RoleArn']
region_name = kwargs['RegionName']
sts = boto3.client(
'sts',
region_name=region_name,
)
token = sts.assume_role(
RoleArn=role_arn,
RoleSessionName='GetInstances',
DurationSeconds=900,
)
return token["Credentials"]
def get_accounts():
role_arn = "arn:aws:iam::xxxxxxxxxx:role/list-accounts-role"
region_name = "us-east-1"
token = get_sts_token(RoleArn=role_arn, RegionName=region_name)
access_key = token['AccessKeyId']
secret_key = token['SecretAccessKey']
session_token = token['SessionToken']
client = boto3.client('organizations',
aws_access_key_id=access_key,
aws_secret_access_key=secret_key,
aws_session_token=session_token)
moreAccounts=True
nexttoken=''
global accountList
accountList =[]
while moreAccounts:
if (len(nexttoken)>0):
accounts=client.list_accounts(NextToken=nexttoken)
else:
accounts=client.list_accounts()
if 'NextToken' in accounts:
nexttoken=accounts['NextToken']
else:
moreAccounts=False
for account in accounts['Accounts']:
if account['Status'] != 'SUSPENDED' and account['Status'] != 'CLOSED' :
account_id = account['Id']
accountList.append(account_id)
print(accountList)
def trigger_sfn():
ssm = boto3.client('ssm')
role_arn = "arn:aws:iam::xxxxxxxx:role/execute-sfn"
region_name = "us-east-1"
ami_id = ssm.get_parameter(Name='/BaseAMI/newest')['Parameter']['Value']
print(ami_id)
token = get_sts_token(RoleArn=role_arn, RegionName=region_name)
print(token)
access_key = token['AccessKeyId']
secret_key = token['SecretAccessKey']
session_token = token['SessionToken']
sfn = boto3.client('stepfunctions',
aws_access_key_id=access_key,
aws_secret_access_key=secret_key,
aws_session_token=session_token)
response = sfn.start_execution(
stateMachineArn='arn:aws:states:us-east-1:xxxxxxxx:stateMachine:ami-share',
input="{\"ami_id\": ami_id, \"source_account_id\": \"112233445566\", \"accountList\": accountList, \"kms_key_arn\": \"alias/aws/ebs\"}"
)
print(response)
TRACE:
An error occurred (InvalidExecutionInput) when calling the
StartExecution operation: Invalid State Machine Execution Input:
'com.fasterxml.jackson.core.JsonParseException: Unrecognized token
'ami_id': was expecting ('true', 'false' or 'null')
at [Source: (String)"{"ami_id": ami_id, "source_account_id":
"112233445566", "accountList": accountList, "kms_key_arn":
"alias/aws/ebs"}"; line: 1, column: 18]': InvalidExecutionInput
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 6, in lambda_handler
trigger_sfn()
File "/var/task/lambda_function.py", line 96, in trigger_sfn
input="{\"ami_id\": ami_id, \"source_account_id\": \"112233445566\",
\"accountList\": accountList, \"kms_key_arn\": \"alias/aws/ebs\"}"
File "/var/runtime/botocore/client.py", line 314, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 612, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.errorfactory.InvalidExecutionInput: An error occurred
(InvalidExecutionInput) when calling the StartExecution operation:
Invalid State Machine Execution Input:
'com.fasterxml.jackson.core.JsonParseException: Unrecognized token
'ami_id': was expecting ('true', 'false' or 'null')
at [Source: (String)"{"ami_id": ami_id, "source_account_id":
"112233445566", "accountList": accountList, "kms_key_arn":
"alias/aws/ebs"}"; line: 1, column: 18]'
You can add the value of the variable to the string like this:
input="{\"ami_id\": \"" + ami_id + "\", \"source_account_id\": \"112233445566\", \"accountList\": accountList, \"kms_key_arn\": \"alias/aws/ebs\"}"
Your code currently sends the literal string "ami_id", instead of the variable value of ami_id

Passing arguments as json object

I am trying to link my django web app to Azure ML API. I do have Django form with all the required inputs for my Azure API.
def post(self,request):
form = CommentForm(request.POST)
url = 'https://ussouthcentral.services.azureml.net/workspaces/7061a4b24ea64942a19f74ed36e4b438/services/ae2c257d6e164dca8d433ad1a1f9feb4/execute?api-version=2.0&format=swagger'
api_key = # Replace this with the API key for the web service
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}
if form.is_valid():
age = form.cleaned_data['age']
bmi = form.cleaned_data['bmi']
args = {"age":age,"bmi":bmi}
json_data = str.encode(json.dumps(args))
print(type(json_data))
r= urllib.request.Request(url,json_data,headers)
try:
response = urllib.request.urlopen(r)
result = response.read()
print(result)
except urllib.request.HTTPError as error:
print("The request failed with status code: " + str(error.code))
print(json_data)
# Print the headers - they include the requert ID and the timestamp, which are useful for debugging the failure
print(error.info())
print(json.loads(error.read()))
return render(request,self.template_name)
When i try to submit the form i am getting type error -
TypeError('POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.',)
Getting status code - 400 and below error
{'error': {'code': 'BadArgument', 'message': 'Invalid argument provided.', 'details': [{'code': 'RequestBodyInvalid', 'message': 'No request body provided or error in deserializing the request body.'}]}}
Arguments are using print(json_data) -
b'{"age": 0, "bmi": 22.0}'
Can someone help me on this?
Try to use JsonResponse:
https://docs.djangoproject.com/en/2.1/ref/request-response/#jsonresponse-objects
Also, I don't think you need a template for API response.
return JsonResponse({'foo': 'bar'})
Thanks all. I found the error it was the data which was not in proper order.

Azure Cognitive Services: Face Find Similar 'BadArgument', 'Argument faceListId and faceIds cannot be provided at the same time.'.'

I am new to Azure Cognitive Services. I am using python 3.5 and the Azure Face service, specifically the "Face - Find Similar" API. I am getting an error formatting the Post JSON body. The documentation says that I should either provide a single faceId or a list of faces in a face list, e.g., 'extended_family'. In my case, I want to use the face list. I do not know how to format the faceID parameter in the JSON so that call processes the face list. I have tried different alternatives to setting faceId to '{}' or 'Null', '', 'False', and this results in errors.
Below is my JSON body for my POST:
{'faceId': '97522b8b-02b6-4115-99e0-6dc1f5d45f51', 'faceIds': ['97522b8b- 02b6-4115-99e0-6dc1f5d45f51', '0ca8f3e4-edf1-4c14-b926-3b47eae7e29c', '2fadbb12-b10b-4761-aaaa-c50f1dc765c3', '56f464d5-b388-4fc7-9051-6991cf5f1d0d', '29931480-632e-40b6-aa0c-9e03e36e95f9', '7a8085b2-2013-4742-a51a-a5543a0347e8'], 'faceListId': 'extended_family', 'maxNumOfCandidatesReturned': 20, 'mode': 'matchPerson'}
Since faceId is populated, I get:
error: 'code': 'BadArgument', 'message': 'Argument faceListId and faceIds cannot be provided at the same time.'
If I leave faceId blank, such as:
{'faceId': '', 'faceIds': ['824e3d83-a94f-4ef2-949e-55a55b2ef256', '51f3c1a5-4e16-4b14-89fa-f1342a2c46ec', '0480d2e0-ff05-44de-b3d8-94408277b1c5', 'c7d767fb-0fbe-46c8-b7af-2c8f675bfd8d', 'ca7e82a7-cd3f-417b-bffa-77c9d47c1439', 'f7130e90-9e1f-428a-a773-93c87932a420'], 'faceListId': 'extended_family', 'maxNumOfCandidatesReturned': 20, 'mode': 'matchPerson'}
I get the following:
{'error': {'code': 'BadArgument', 'message': 'Request body is invalid.'}}
If I remove the faceId term from the JSON:
{'faceIds': ['690feffd-5c86-47d7-ac3c-224b0eafa90f', '936564e0-31aa-43e3-916e-c7b236bea8e0', '614c04cb-4375-44c8-b393-89d64b4c1ebd', 'a29f8e5c-50ba-4bb8-8bf8-98e356a9125a', '073d7865-2aaf-4806-9bef-ddca478137ea', '7e416e83-5973-4aa1-b1fc-3a25b5174bb3'], 'faceListId': 'andersen_extended_family', 'maxNumOfCandidatesReturned': 20, 'mode': 'matchPerson'}
{'error': {'code': 'BadArgument', 'message': 'Face ID is invalid.'}}
My code is as follows:
facelist = list() #This is populated upstream using the Face Detect API
facelistid = 'extended_family'
faceid = ''
payload = {'faceId': faceid, 'faceIds':facelist,'faceListId':facelistid, 'maxNumOfCandidatesReturned':20,'mode': "matchPerson"}
req = requests.post(serviceurlpersongroup, data = json.dumps(payload) , headers = {'Ocp-Apim-Subscription-Key': key})
jinfo = req.json()
Just as the error message explained, faceListId and faceIds (not faceId) should not be provided at the same time. So the payload you use should be
payload = {'faceId': faceid, 'faceListId': facelistid, 'maxNumOfCandidatesReturned': 20, 'mode': "matchPerson"}
or
payload = {'faceId': faceid, 'faceIds': facelist, 'maxNumOfCandidatesReturned': 20, 'mode': "matchPerson"}
Feel free to update if you have any further questions.

Ruby on sinatra, JSON::parserError issue and 757: unexpected token

I use rest API on Ruby with sinatra.
I got payment information from IAMPORT,,,
def get_authrestapi()
#key = IMP_KEY
#secret = IMP_SECRET
response = RestClient.post 'https://api.iamport.kr/users/getToken', {'imp_key' => #key, 'imp_secret' => #secret}, :accept => :json
json = JSON.parse(response.to_json, symbolize_names: true)
return json['response']['access_token']
end
but, I got error message... like below
JSON::ParserError at /payments 757: unexpected token at '"{\"code\":0,\"message\":null,\"response\":{\"access_token\":\"9898....", "..."}}"'
How can I solve this problem?? I think,, there is problem that variable 'json' is not HASH..
Thanks.
Don't convert the response to json. It's already json.
Replace the following line:
json = JSON.parse(response.to_json, symbolize_names: true)
with:
json = JSON.parse(response, symbolize_names: true)