I'm porting some automation scripts from bash to python, and they're almost ll curl commands of the following format:
curl -k -H "Content-Type: application/json" -X POST -d '{ "Request": {
"MessageID": "xxxx",
"MessageDateTime": "xxxxx",
"SourceSystem": "xxxx",
}
}' https://myUrl.xxx
What's the best way to structure this in Python accurately? So far I have:
import requests
headers = {'Content-Type': 'application/json'}
payload = {'All the data'}
conn = httplib.HTTPConnection("myUrl.xxx")
conn.request("POST", "", payload, headers)
response = conn.getresponse()
print response
I want to make sure the -k, -d, and -x bash options are being reflected in this script. Thank you!
You can use requests.post directly. -k corresponds to verify=False:
from datetime import datetime as DateTime
import requests
import json
URL = "https://myUrl.xxx"
message = {
"Request": {
"MessageID": "xxxx",
"MessageDateTime": DateTime.now().isoformat(),
"SourceSystem": "xxxx",
}
}
response = requests.post(URL, data=json.dumps(message), verify=False, headers={"Content-Type":"application/json"})
data = response.json()
Related
I have to send commands to an API using Python.
The API's documentation was written to send receive CURL commands.
I converted the curl string
curl -H "Authorization: Bearer accesstoken" https://www.website.com/feed.php?command=COMMAND
Into this:
import requests
headers = {
'Authorization': 'Bearer accesstoken',
}
params = {
'command': "COMMAND",
}
response = requests.get('https://www.website.com/feed.php', params=params, headers=headers)
The problem is if the command I want to send is a complex command like:
curl -H "Authorization: Bearer accesstoken" https://www.website.com/feed.php?command=COMMAND&wake=10
the conversion to Python won't work as this "&wake=10" isn't accepted.
Any ideas on how to circumvent this?
You can pass multiple query parameters in the params dictionary - requests will turn them into the required URL format.
import requests
headers = {
'Authorization': 'Bearer accesstoken',
}
params = {
'command': "COMMAND",
'wake': 10
}
response = requests.get('https://www.website.com/feed.php', params=params, headers=headers)
You need to split on the &, resulting in multiple key + value pairs in params.
params = {
"command": "COMMAND",
"wake": "10"
}
I have this request using a curl command and I want to translate it to python using the requests library
curl -X POST https://endpoint/prod/api/Translations/start \
-H 'Authorization: Bearer <accessToken>' \
-H 'Content-Type: application/json' \
-d '{ "text": ["first segment to translate.", "second segment to translate."], "sourceLanguageCode": "en", "targetLanguageCode": "de", "model": "general", "useCase": "testing"}'
You can use requests library.
The following curl:
curl -X POST "https://www.magical-website.com/api/v2/token/refresh/" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"refresh": "$REFRESH_TOKEN"
}'
I wrote in python the following way:
import requests
def get_new_token():
url = 'https://www.magical-website.com/api/v2/token/refresh/'
token = constants.THE_TOKEN
payload = f'{{ "refresh": "{token}" }}'
headers = {"accept": "application/json", "Content-Type": "application/json"}
print("Token handling ....")
r = requests.post(url, data=payload, headers=headers)
print(f"Token status: {r.status_code}")
return r.json()['access']
You can try this one.
import requests
url = "https://endpoint/prod/api/Translations/start"
payload = {
"text": ...,
"sourceLanguageCode": ...,
...
}
headers = { "Authorization": "Bearer ...", "Content-Type": "application/json" }
res = requests.post(url, data = payload, headers = headers)
print(res.status_code)
print(res.text)
I can access JWT secured Restful API using curl command as follows
#Get the access Token in a variable ID
export ID=`curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ "password": "admin", "rememberMe": true, "username": "admin" }' 'http://localhost:8080/api/authenticate' | jq -r .id_token`
#Use this token to access endpoint
curl 'http://localhost:8080/api/downloads' --header 'Content-Type: application/json' --header 'Accept: application/json' --header "Authorization: Bearer $ID"
My python script for authentication part and get bearer token is as follows:
import requests
LOGIN_URL = "http://localhost:8080/api/authenticate"
ENDPOINT_URL = 'http://localhost:8080/api/downloads'
PARAMS = {'password': 'admin','rememberMe': True, 'username': 'admin' }
r1 = requests.post(LOGIN_URL, data =PARAMS, headers={"Content-Type": "application/json","Accept": "application/json"})
print(r1)
When i am trying to do the same through python script,Authentication request fails with message <Response [400]>
Help needed !
You are passing a dictionary where you should be passing JSON.
Try using json not data and pass the dictionary:
import requests
LOGIN_URL = "https://httpbin.org/post"
PARAMS = {'password': 'admin','rememberMe': True, 'username': 'admin' }
r1 = requests.post(LOGIN_URL, json=PARAMS, headers={"Content-Type": "application/json","Accept": "application/json"})
print(r1.text)
or pass a string and use data:
import requests
LOGIN_URL = "https://httpbin.org/post"
PARAMS = '{"password": "admin", "rememberMe": true, "username": "admin"}'
r1 = requests.post(LOGIN_URL, data=PARAMS, headers={"Content-Type": "application/json", "Accept": "application/json"})
print(r1.text)
[newbie question]
I'm trying to create a new record in my Airtable base using python 3.
The curl commands in the documentation are as follows:
$ curl -v -XPOST https://api.airtable.com/v0/restoftheurl \
-H "Authorization: Bearer My_API_Key" \
-H "Content-type: application/json" \
-d '{
"fields": {
"Item": "Headphone",
"Quantity": "1",
"Customer_ID": [
"My_API_Key"
]
}
}'
The python code I tried to use is:
import requests
API_URL = "https://api.airtable.com/v0/restoftheurl"
data = {"Authorization": "Bearer My_API_Key","Content-type":
"application/json","fields": {"Item": "randomitem","Quantity":
"5","Customer_ID": ["randomrecord"]}}
r = requests.post(API_URL, data)
print(r.json())
Where the response is the error:
{'error': {'type': 'AUTHENTICATION_REQUIRED', 'message': 'Authentication required'}}
How am I supposed to properly authenticate this, or am I way of?
You need to distinguish the body (data) from the headers. Using the json named argument automatically set the content type to application/json :
import requests
API_URL = "https://api.airtable.com/v0/restoftheurl"
headers = {
"Authorization": "Bearer My_API_Key"
}
data = {
"fields": {
"Item": "randomitem",
"Quantity": "5",
"Customer_ID": ["randomrecord"]
}
}
r = requests.post(API_URL, headers=headers, json=data)
print(r.json())
I`m trying to make those 2 requests in python:
Request 1:
curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth1", "widget": "id1", "title": "Something1", "text": "Some text", "moreinfo": "Subtitle" }' serverip
Request 2:
vsphere_dict = {}
vsphere_dict['server_name'] = "servername"
vsphere_dict['api_version'] = apiVersion
vsphere_dict['guest_count'] = guestCount
vsphere_dict['guest_on'] = guestOnLen
vsphere_dict['guest_off'] = guestOffLen
#Convert output to Json to be sent
data = json.dumps(vsphere_dict)
curl -X POST -H "Content-Type: application/json" -d 'data' serverip
Neither of them seems to work. Is there any way I can send them in Python?
Update:
The part that I cannot handle is the pass auth and widget. I have tried the following without success:
import urllib2
import urllib
vsphere_dict = dict(
server_name="servername",
api_version="apiVersion",
guest_count="guestCount",
guest_on="guestOnLen",
guest_off="guestOffLen",
)
url = "http://ip:port"
auth = "authid89"
widget = "widgetid1"
# create request object, set url and post data
req = urllib2.Request(auth,url, data=urllib.urlencode(vsphere_dict))
# set header
req.add_header('Content-Type', 'application/json')
# send request
response = urllib2.urlopen(req)**
Resulting in "urllib2.HTTPError: HTTP Error 500: Internal Server Error"
Any ideas how I can pass the auth and widget correctly?
UPDATE:
To see what is different I have started a nc server locally. Here are the results:
Correct curl request using this code:
curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" }' http://localhost:8123
sends this which does work:
POST / HTTP/1.1
User-Agent: curl/7.21.0 (i386-redhat-linux-gnu) libcurl/7.21.0 NSS/3.12.10.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.4
Host: localhst:8123
Accept: */*
Content-Type: application/json
Content-Length: 165
{ "auth_token": "token", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" }
And request using this code
import requests
import simplejson as json
url = "http://localhost:8123"
data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some text', 'moreinfo': 'Subtitle'}
headers = {'Content-type': 'application/json'}
r = requests.post(url, data=json.dumps(data), headers=headers)
sends this which does not work:
POST / HTTP/1.1
Host: localhst:8123
Content-Length: 108
Content-type: application/json
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/2.0.1 CPython/2.7.0 Linux/2.6.35.14-106.fc14.i686
{"text": "Some text", "auth_token": "auth1", "moreinfo": "Subtitle", "widget": "id1", "title": "Something1"}
Requests provides you with the simplest and yet (very) powerful way to deal with HTTP requests in Python.
Maybe try something like this:
import requests
import simplejson as json
url = "http://ip:port"
data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some text', 'moreinfo': 'Subtitle'}
headers = {'Content-type': 'application/json'}
r = requests.post(url, data=json.dumps(data), headers=headers)
If the API requests authentication:
r = requests.post(url, data=json.dumps(data), headers=headers, auth=('user', 'pass'))
See [Requests auth] for details.
Well sure, using Python-Requests which is a Python library for sending requests like Curl. You can take a look at the Complicated Post Requests section.
Or, if you'd like to use curl inside of Python, you can use pyCurl.
In the example from the Dashing website, they use:
curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "current": 100 }' http://localhost:3030/widgets/karma
From the cURL man page, maybe you need to post it as form-urlencoded?
-d, --data
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.
-d, --data is the same as --data-ascii. To post data purely binary, you should instead use the --data-binary option. To URL-encode the value of a form field you may use --data-urlencode.
If any of these options is used more than once on the same command line, the data pieces specified will be merged together with a separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would generate a post chunk that looks like 'name=daniel&skill=lousy'.
If you start the data with the letter #, the rest should be a file name to read the data from, or - if you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a file named 'foobar' would thus be done with --data #foobar. When --data is told to read from a file like that, carriage returns and newlines will be stripped out.
You might also want to try python-requests http://requests.readthedocs.org/en/latest/user/quickstart/#more-complicated-post-requests
Update: I got it to work
import requests
import json
payload = {'auth_token': 'YOUR_AUTH_TOKEN', 'title': "pythontest"}
r = requests.post("http://localhost:3030/widgets/welcome", data=json.dumps(payload))
print r.text
You need to post the json like a form.
why not use urllib2?
import urllib2
import urllib
vsphere_dict = dict(
server_name="servername",
api_version=apiVersion,
guest_count=guestCount,
guest_on=guestOnLen,
guest_off=guestOffLen,
)
# create request object, set url and post data
req = urllib2.Request(some_url, data=urllib.urlencode(vsphere_dict))
# set header
req.add_header('Content-Type', 'application/json')
# send request
response = urllib2.urlopen(req)
UPD:
sorry, by i not understand that is auth and widget. Maybe this is also POST data?
HTTP Error 500 - can mean that server received not all POST parameters.