I'm trying to create new order on PayU, via their REST api. I'm sending "get access token", and i have correct answer. Then i send 'create new order', aaaaand i ve got 103 error, error syntax.
I was trying on https://webhook.site/ , and realized why syntax is bad - i have no values in list.
Code of sending POST, when creating new order:
data = {
"notifyUrl": "https://your.eshop.com/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "00000",
"description": "RTV market",
"currencyCode": "PLN",
"totalAmount": "15000",
"products": [{
"name": "Wireless mouse",
"unitPrice": "15000",
"quantity": "1"}]}
headers = {
"Content-Type": "application/json",
"Authorization": str('Bearer ' + access_token).encode()}
r = requests.post('https://webhook.site/9046f3b6-87c4-4be3-8544-8a3454412a55',
data=payload,
headers=headers)
return JsonResponse(r.json())
Webhooc show what i have posted:
customerIp=127.0.0.1¬ifyUrl=https%3A%2F%2Fyour.eshop.com%2Fnotify¤cyCode=PLN&products=name&products=unitPrice&products=quantity&description=RTV+market&merchantPosId=00000&totalAmount=15000
There is no values of 'name', 'unitprice' and 'quantity'. PayU confirmed thats the only problem.
Why? What is wrong?
Sending simple POST request to get a token is always successful.
If you want to send JSON, use the json argument of post():
r = requests.post('https://webhook.site/9046f3b6-87c4-4be3-8544-8a3454412a55',
json=payload, # Use the json argument
headers=headers)
Otherwise the data will be sent as form-encoded data, which I guess isn't what you want, given you're expecting to send the nested products list.
When you use the json argument, the content type is automatically set to application/json so you don't have to set it yourself.
headers = {
# Content-Type not required
"Authorization": str('Bearer ' + access_token).encode()
}
Further info on using requests to send JSON here
Related
I want to parse 'statusCode' and 'body' values from API Gateway integration response using VTL and return those as a method response like this:
Request status: 201
Response body: {"firstName":"He","lastName":"Man","email":"he.man#eternia.com"}
My API Gateway Step Function integration is returning the following integration response body (this is before transformation, non-relevant attributes are removed from output):
{
"output": "{\"statusCode\":201,\"body\":{\"firstName\":\"He\",\"lastName\":\"Man\",\"email\":\"he.man#eternia.com\"}}"
}
I would assume this to work:
#set ($output = $util.parseJson($input.json('$.output')))
#set ($statusCode = $output.statusCode)
#set ($context.responseOverride.status = $statusCode)
$output.body
But status is not updated and body is empty
Request status: 200
Response body: <empty>
With this approach I can parse the body:
#set ($bodyObj = $util.parseJson($input.body))
#set ($output = $util.parseJson($bodyObj.output))
#set ($context.responseOverride.status = $output.statusCode)
$output.body
statusCode is updated but body is returned as object representation i.e. not JSON.
Request status: 201
Response body: {firstName=He, lastName=Man, email=he.man#eternia.com}
How to serialize $output.body correctly to JSON in above case? API Gateway doesn't seem to have $util.toJson function like AppSync does (https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html)
I've confirmed parsing output-variable works correctly:
#set ($output = $util.parseJson($input.json('$.output')))
$output
Request status: 200
Response body: {"statusCode":201,"body":{"firstName":"He","lastName":"Man","email":"he.man#eternia.com"}}
Relevant reference documentation:
https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartSyncExecution.html#API_StartSyncExecution_ResponseSyntax
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
I ran into this exact issue. There indeed does not seem to be a way to convert to JSON directly, so I devised a way to write JSON to the API Gateway response using Apache VTL:
#set ($outputObj = $util.parseJson($input.path('$.output')))
#foreach ( $key in $outputObj.body.keySet() )
"$key": $outputObj.body[$key] #if ($foreach.hasNext),#end
#end
Hope this helps!
(This works for a simple use case like the one you described, but doesn't generalize to nested objects, etc.)
I ran into this same issue. This is how I solved it in the end. The solution provided by #noahtk7 was good for simple object, I have large nested object I needed.
For this to work you need to have your body returned as a base64 encoded string. This is easy to do in a step function. E.G:
"Pass": {
"Type": "Pass",
"Next": "Success",
"Parameters": {
"Base64.$": "States.Base64Encode(States.JsonToString($.Response.Body))"
},
"ResultPath": "$.Response.Body"
}
Then in the api response mapper:
#set($output = $util.parseJson($input.path('$.output')))
#set($context.responseOverride.status = $output.Response.Status)
$util.base64Decode($output.Response.Body.Base64)
Would give me a result of:
{
"foo": "bar",
"Id": "c2b2220c-00e3-4499-87c0-d06ea5e5f1f4"
}
I am trying to get data about a song playing on one of my devices from the spotify API. I have created a view that fetches data from the API and part of it looks like this:
class Song(viewsets.ModelViewSets):
....
room_code = request.data['room_code']
room = Room.objects.filter(code=room_code)[0]
host = room.host
endpoint = 'player/currently-playing'
response = execute_spotify_api_request(host, endpoint)
item = response.get('item')
duration = item.get('duration_ms')
progress = response.get('progress_ms')
album_cover = item.get('album').get('images')[0].get('url')
return Response(response, status=status.HTTP_200_OK)
The execute_spotify_api_request(host, endpoint) is a utility function and it looks like this:
def execute_spotify_api_request(session_id, endpoint, post_=False, put_=False):
tokens = get_user_tokens(session_id)
headers = {'Content-Type': 'application/json',
'Authorization': "Bearer " + tokens.access_token}
if post_:
post(BASE_URL + endpoint, headers=headers)
if put_:
post(BASE_URL + endpoint, headers=headers)
response = get(BASE_URL, {}, headers=headers)
try:
return response.json()
except:
return {'error': 'Could not retrieve a response'}
The full url from which im fetching is ""https://api.spotify.com/v1/me/player/currently-playing"
The problem is with the response that im getting from the API, the response is not an error but data that im not expecting to get. Im getting a response that looks like this:
response = {
"display_name": "Tanatswamanyakara",
"external_urls": {
"spotify": "https://open.spotify.com/user/dlnsysel6bndktbvduz6cl79w"
},
"followers": {
"href": null,
"total": 0
},
"href": "https://api.spotify.com/v1/users/dlnsysel6bndktbvduz6cl79w",
"id": "dlnsysel6bndktbvduz6cl79w",
"images": [],
"type": "user",
"uri": "spotify:user:dlnsysel6bndktbvduz6cl79w"
}
I was hoping to get data (the progress, title, duration, album, artist etc) about the song I am playing on my spotify account but instead I get that response, how do I fix that?
N.B
My access tokens and refresh tokens are working as they should. (so I think)
If the data is not what you are expecting then there's going to be something wrong with your API endpoint. You can use the Spotify developer console to generate the endpoint link, it would be worth debugging your execute_spotify_api_request code and the url it generates against the value in the console.
Having just re-read your code half way through answering, I've noticed that you aren't appending your endpoint variable to your GET url:
response = get(BASE_URL, {}, headers=headers)
This means that the get doesn't have 'player/currently-playing' and just returns the base URL which is probably 'https://api.spotify.com/v1/me/' - hence the response you receive is just your profile data.
I'm using Postman app to interact with a Telegram bot api. I've sent photos using the sendPhoto() method, like this:
https://api.telegram.org/botToken/sendPhoto?chat_id=00000000&photo=AgAC***rgehrehrhrn
But I don't understand the sendMediaGroup() method. Can someone post an example how to compose the https string to send two photos?
Thanks
You need to send a POST request at the url https://api.telegram.org/botToken/sendPhoto with a JSON body. You are using the url to specify all the parameters of the request but urls are only 2000 characters long. The body of a POST request, instead, has no limits in terms of size. The JSON body should look something like this:
{
"chat_id": 777000,
"media": [
{
"type": "photo",
"media": "https://example.com/first_photo_url.png",
"caption": "an optional description of the first photo",
"parse_mode": "optional (you can delete this parameter) the parse mode of the caption"
},
{
"type": "photo",
"media": "https://example.com/fsecond_photo_url.png",
"caption": "an optional description of the second photo",
"parse_mode": "optional (you can delete this parameter) the parse mode of the caption"
}
],
}
For more info see:
how to send JSON (raw) data with Postman
and
sendMediaGroup Telegram API's method.
You must send JSON as a string, or serialized JSON, to Telegram API. The format is as same as #GioIacca9's answer.
Note: only the caption in the first image will be showen.
Have a try this Python code.
def send_photos(api_key, chat_id, photo_paths):
params = {
'chat_id': chat_id,
'media': [],
}
for path in photo_paths:
params['media'].append({'type': 'photo', 'media': path})
params['media'] = json.dumps(params['media'])
url = f'https://api.telegram.org/bot{api_key}/sendMediaGroup'
return requests.post(url, data=params)
if __name__ == '__main__':
send_photos('your_key', '#yourchannel', ['http://your.image.one', 'http://your.image.two'])
i am using an api to do a post method and i used Requests library to perform the post.
data_post = requests.post(url='https://proxy.vox-cpaas.in/api/user',
data={'authtoken': '945e5f0f_ssss_408e_pppp_ellll234122',
'projectid': "pid_a44444fae2_454542_41d4_8630_6454545cdafff12",
'username': "username",
'password': "user.username"})
the above data post worked successfully.
but
data_post = requests.post(url='https://proxy.vox-cpaas.in/api/user',
data=json.dumps({'authtoken': '945e5f0f_ssss_408e_pppp_ellll234122',
'projectid': "pid_a44444fae2_454542_41d4_8630_6454545cdafff12",
'username': "username",
'password': "user.username"}))
the 2nd code didnt worked for me
please someone explain me the difference.
Recommended way of postng data as json with requests - use json parameter:
r = requests.post(url, json=my_dictionary)
this way requests will encode dictionary for you (no need for json.dumps()) and will set correct Content-Type header.
In first example, when you pass python dictionary directly to requests data - result is form-encoded data with "Content-Type": "application/x-www-form-urlencoded".
In the second one - you pass string which contains serialized json to requests data. However, as data is just a string - requests may not identfy that it is json, and not set Content-Type or set it Content-Type: "text/plain", and receiving side may not recognise it.
For correct request with json body you need "Content-Type": "application/json".
You may want to explicitly set content-type in headers:
r = requests.post(
url,
data=json.dumps(my_dictionary),
headers={'content-type': 'application/json'}
)
But requests contains json parameter to simplify these things.
I've gotten the built in read action to work in the past but now it is not working. I also created a custom action which will not work.
When I try to post the action to this url:
https://graph.facebook.com/me/teamtutorials:complete?access_token=AAACOYImsskcBAGlF33o6awIqxmQ078BVdHUY72CF7GUqTHUhEcpKLdH8ZCKeyQbBqBDlnHwUMwt5aLOzpBmiWQqpvWsNAeHDMPSo2OQZDZD&tutorial=http://teamtutorials.com/web-development-tutorials/why-zen-coding-is-an-awesome-time-saver?
all I get in response is:
{
"data": [
],
"paging": {
"next": "https://graph.facebook.com/me/teamtutorials:complete?access_token=AAACOYImsskcBAGlF33o6awIqxmQ078BVdHUY72CF7GUqTHUhEcpKLdH8ZCKeyQbBqBDlnHwUMwt5aLOzpBmiWQqpvWsNAeHDMPSo2OQZDZD&tutorial=http\u00253A\u00252F\u00252Fteamtutorials.com\u00252Fweb-development-tutorials\u00252Fwhy-zen-coding-is-an-awesome-time-saver\u00253F&offset=25&limit=25"
}
}
What causes this type of response?
That looks like the response you'd get to a HTTP GET request; you need to make a HTTP POST request to create a new action
if your code/proxy can't make POST request outbound or you can fake it by making a GET request and including an extra parameter &method=post