So I'm trying to use python requests to make a PUT request to Azure (to create/update notification hub - https://learn.microsoft.com/en-us/rest/api/notificationhubs/notificationhubs/createorupdate#mpnscredential .
My code:
url = "https://management.azure.com/subscriptions/mysub/resourceGroups/Default-NotificationHubs-WestEurope/providers/Microsoft.NotificationHubs/namespaces/myNamespace/notificationHubs/notificationHubName?api-version=2016-03-01"
bearer_token = "my very long token"
headers = {
"dataType": "json",
"accept":"application/json",
"contentType":"application/json",
"Authorization": "Bearer " + bearer_token }
filepath = "/Users/..../pathTo.p12"
with open(filepath) as fh:
byte_array_p12 = fh.read()
data = {
'location': "West Europe",
'properties.apnsCredential': {
'properties.apnsCertificate': byte_array_p12,
'properties.certificateKey': "some nice pass"
}
}
r = requests.put(url, data, headers = headers)
But running r gives me 415 error.
r.text
u'{"error":{"code":"UnsupportedMediaType","message":"The content media type \'application/x-www-form-urlencoded\' is not supported. Only \'application/json\' is supported."}}'
Where did that \'application/x-www-form-urlencoded\' come from? I am explicitly setting headers for that request, and that one is not included... I am clueless.
I have tried the "Try" functionality on the afformentioned Azure page, where you can try constructing the body yourself, but it is buggy...
Thanks for any help!
The HTTP header should Content-Type and not contentType.
headers = {
"dataType": "json",
"accept":"application/json",
"Content-Type":"application/json",
"Authorization": "Bearer " + bearer_token }
Also, parameter data should be JSON encoded.
r = requests.put(url, json=data, headers=headers)
Related
I'm trying to get accessToken from Xero
This is their instruction:
https://developer.xero.com/documentation/guides/oauth2/auth-flow/#3-exchange-the-code
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
This is how I do it:
tokenb4 = "{0}:{1}".format(CLIENT_ID, CLIENT_SECRET)
basic_token = base64.urlsafe_b64encode(tokenb4.encode()).decode()
response = requests.post(
"https://identity.xero.com/connect/token",
headers={
"Authorization": "Basic {0}".format(basic_token),
"Content-Type": "application/x-www-form-urlencoded"
},
params="grant_type=authorization_code \
&code=MYCODE \
&redirect_uri=https://developer.xero.com/"
)
Now I keep getting error 400
{"error":"unsupported_grant_type"}
redirect_uri is the same with the one I leave in the App in Xero demo company.
I've googled some, seems like it's a format issue but I can't see what's wrong with my code.
Much appreciation if anyone could help
ref:Python requests module sends JSON string instead of x-www-form-urlencoded param string
I changed the params to
data={
"grant_type": "authorization_code",
"code": "MYCODE",
"redirect_uri": "https://developer.xero.com/"
}
And it works! Hooray!
It's been a while since I've worked with the Google Drive API. And I want to replace files using Google Drive API. I want to do that only using the Python HTTP requests module. Unfortunately, I always encounter an error. Could you please respond to this? It would be greatly appreciated.
CODE:
filedirectory = './Test.txt'
filename = 'Test.txt'
folderid = 'XXXXX'
updateFileId = 'XXXX'
headers = {
"Authorization": "Bearer " + str(Acesstoken),
}
metadataF= {
'id':updateFileId,
'fileId': updateFileId,
'name': filename,
'parents':[folderid]
}
files = {
'data':('metadata', json.dumps(metadataF), 'application/json; charset=UTF-8'),
'file': open("./Test.txt", "rb"),
}
r2= requests.post(
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
headers= headers,
files= files,
)
Error:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "fileIdInUse",
"message": "A file already exists with the provided ID."
}
],
"code": 409,
"message": "A file already exists with the provided ID."
}
}
<Response [409]>
It would be extremely helpful if you could assist me with this issue.
You are using the wrong end point and the wrong HTTP type.
You are using the Files.create end point.
requests.post(
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
headers= headers,
files= files,
To update an existing file you use Files.update
Which is a HTTP PATCH call and requires that you send the file id.
PATCH https://www.googleapis.com/upload/drive/v3/files/fileId
You need to remember to pass the id in the request. note the fileId part in the request above.
filedirectory = './Test.txt'
filename = 'Test.txt'
folderid = 'XXXXX'
updateFileId = 'XXXX'
headers = {
"Authorization": "Bearer " + str(Acesstoken),
}
metadataF= {
'name': filename,
'parents':[folderid]
}
files = {
'data':('metadata', json.dumps(metadataF), 'application/json; charset=UTF-8'),
'file': open("./Test.txt", "rb"),
}
r2= requests.patch(
"https://www.googleapis.com/upload/drive/v3/files/" + updateFileId + "?uploadType=multipart",
headers= headers,
files= files,
)
I am trying to send a JSON payload with session request in python to a PHP server.
The session itself is established and cookies are accepted by the server but when I print out the $_POST, it returns an empty array.
It looks like the payload is not being sent with the request or maybe PHP doesn't recognize it.
Client Side - Python:
import json
import requests
url = 'https://prov.is.st.com/eventpost.php'
payload = {
'script': 'pyt.sh',
'status': 'Success'
}
s = requests.Session()
s.cookies.set('provisioning', cookie, domain='prov.is.st.com')
headers = {
'Content-Type': 'application/json'
}
s.headers.update(headers)
response = s.post(url, data=payload, verify=False)
print(response.text)
Server Side - PHP:
<?php
print_r($_POST);
if(isset($_POST['status'])){
$status = $_POST['status'];
}
else{
$status=0;
}
if (isset($_POST['script'])) {
$script=$_POST['script'];
} else {
$script="unknown";
}
if (isset($_COOKIE['provisioning'])) {
$cookie=$_COOKIE['provisioning'];
print "OK: Message accepted: [$status][$script]\n";
}
else {
print "ERROR: NO cookie provided.\n";
}
Output
Array
(
)
OK: Message accepted: [0][unknown]
As per the documentation here: https://2.python-requests.org/en/master/user/quickstart/#more-complicated-post-requests, in order to post JSON data, you should use either of the following ways:
import json
...
response = s.post(url, data = json.dumps(payload), verify = False)
or
...
response = s.post(url, json = payload, verify = False)
Note, the json parameter is ignored if either data or files is passed.
Using the json parameter in the request will change the Content-Type in the header to application/json.
I started a translator project on azure.
I copy the simple test code.
import os, requests, uuid, json
subscription_key = 'KEY_IN_PORTAL_AZURE'
endpoint = 'URL_IN_PORTAL_AZURE'
path = '/translate?api-version=3.0'
params = '&from=fr&to=en'
constructed_url = endpoint + path + params
headers = {
'Ocp-Apim-Subscription-Key': subscription_key,
'Content-type': 'application/json',
'X-ClientTraceId': str(uuid.uuid4())
}
body = [{
'text' : 'Bonjour'
}]
request = requests.post(constructed_url, headers=headers, json=body)
response = request.json()
print(json.dumps(response, sort_keys=True, indent=4,
ensure_ascii=False, separators=(',', ': ')))
I change the key and the endpoint but the program return
{
"error": {
"code": "404",
"message": "Resource not found"
}
}
I delete the service and i retry same thing
There're 2 errors in the sample code.
Error 1: for the endpoint, use this one instead of copying the one from azure portal:
endpoint = 'https://api.cognitive.microsofttranslator.com/'
Error 2: in headers, please add Ocp-Apim-Subscription-Region, and it's value is the region of the Cognitive Services resource. Like below:
'Ocp-Apim-Subscription-Region':'EastUS'
You can get the region from azure portal, the screenshot is as below:
And I tested it at my side, it worked. The result as below:
I am trying to use Google's QPX Express API from python. I keep running into a pair of issues in sending the request. At first what I tried is this:
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=MY_KEY_HERE"
values = {"request": {"passengers": {"kind": "qpxexpress#passengerCounts", "adultCount": 1}, "slice": [{"kind": "qpxexpress#sliceInput", "origin": "RDU", "destination": location, "date": dateGo}]}}
data = json.dumps(values)
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
print(response)
based upon the code from: urllib2 and json
When I run the above code I get the following error message:
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.
I searched for a solution and adapted my code based upon the following question: TypeError: POST data should be bytes or an iterable of bytes. It cannot be str
I changed my code to this:
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=AIzaSyCMp2ZnKI3J91sog7a7m7-Hzcn402FyUZo"
values = {"request": {"passengers": {"kind": "qpxexpress#passengerCounts", "adultCount": 1}, "slice": [{"kind": "qpxexpress#sliceInput", "origin": "RDU", "destination": location, "date": dateGo}]}}
data = json.dumps(values)
data = data.encode("utf-8")
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
response = f.read()
f.close()
print(response)
However, when I run this code I get the following error message:
urllib.error.HTTPError: HTTP Error 400: Bad Request
I also tried changing utf-8 to ascii but I was unsuccessful. How can I get this working properly?
Here is a solution using the excelent requests library.
import json
import requests
api_key = "YOUR API KEY HERE"
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=" + api_key
headers = {'content-type': 'application/json'}
params = {
"request": {
"slice": [
{
"origin": "TXL",
"destination": "LIM",
"date": "2015-01-19"
}
],
"passengers": {
"adultCount": 1
},
"solutions": 2,
"refundable": False
}
}
response = requests.post(url, data=json.dumps(params), headers=headers)
data = response.json()
print data
I am not sure why you request is not working. Maybe it is really the request parameters that were wrong. The date definitely needs to be in the future!
False needs to be in lowercase in JSON, so you need to quote it in Python, like this "refundable" : "false". Otherwise, your query looks good (obviously you'll need to update the date). By the way, it isn't good practice to include your API key in a public forum.