My problem:
I am writing a python3 program which uses a requests.post() call to the Autodesk Forge Reality Capture photo-to-3d API:
https://developer.api.autodesk.com/photo-to-3d/v1/photoscene/photo-to-3d/v1/file
However, I can't seem to get the API to accept my image file(s), which I pass as a publicly accessible URLs.
Can you show me how it should be done?
My (Non-working) PYTHON + requests code:
forge_url = "https://developer.api.autodesk.com/photo-to-3d/v1/photoscene/photo-to-3d/v1/file"
headers = {'Content-type': 'application/x-www-form-urlencoded'}
image_url_list = { 'http://siptea.net/wp-content/uploads/2017/02/Persimmon-Ceramic-Teapot-Sip-Tea-4786.jpg' }
for file_url in image_url_list:
file_parameters = {'photosceneid': photoscene_id, 'type': 'image', 'file[0]': file_url}
print("file_parameters = ", file_parameters)
response = requests.post(forge_url, auth=BearerAuth(access_token), headers=headers, data=file_parameters)
json_object = response.json()
json_string = json.dumps(json_object)
print("json_string = ", json_string)
My output (showing error response):
file_parameters = {'photosceneid': 'bkd3x48dSl5RpcwdfWYgVfGhD0cMQPgexpLkXLbPtUU', 'type': 'image', 'file[0]': 'http://siptea.net/wp-content/uploads/2017/02/Persimmon-Ceramic-Teapot-Sip-Tea-4786.jpg'}
json_string = {"developerMessage": "The requested resource does not exist.", "moreInfo": "https://forge.autodesk.com/en/docs/oauth/v2/developers_guide/error_handling/", "errorCode": "org.mozilla.javascript.Undefined#0"}
The following BASH script should be equivalent, but it works and the python request does not. What do I need to change in my python code?
My (working) BASH + curl code:
file_url="http://siptea.net/wp-content/uploads/2017/02/Persimmon-Ceramic-Teapot-Sip-Tea-4786.jpg"
json=`curl -s https://developer.api.autodesk.com/photo-to-3d/v1/file \
-H "Authorization: Bearer $access_token" \
-d "photosceneid=$photoscene_id" \
-d 'type=image' \
-d "file[0]=$file_url"
So what is the difference that makes the Python code fail and the Bash script work?
The correct URL to post photos should be: https://developer.api.autodesk.com/photo-to-3d/v1/file and not https://developer.api.autodesk.com/photo-to-3d/v1/photoscene/photo-to-3d/v1/file so hence the 404 error.
See details here
Related
I am trying to convert a Curl POST request into a python script, and i am not getting the desired output, please let me know what i am doing wrong here.
CURL request
curl -s -w '%{time_starttransfer}\n' --request POST \
--url http://localhost:81/kris/execute \
--header 'content-type: application/json' \
--data '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
This runs the uptime command in the node for which the ip is provided and returns a JSON output:
{"command":"uptime","output":["{\"body\":\" 17:30:06 up 60 days, 11:23, 1 user, load average: 0.00, 0.01, 0.05\\n\",\"host\":\"10.0.0.1\"}"]}0.668894
When i try to run the same with python, it fails and never gets the output
Code :
import urllib3
import json
http = urllib3.PoolManager()
payload = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
encoded_data = json.dumps(payload)
resp = http.request(
'POST',
'http://localhost:81/kris/execute ',
body=encoded_data,
headers={'Content-Type': 'application/json'})
print(resp)
I would recommend you use the requests library. It's higher level than urllib and simpler to use. (For a list of reasons why it's awesome, see this answer.)
Plus it requires only minor changes to your code to work:
import requests
payload = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
resp = requests.post(
'http://localhost:81/kris/execute',
data=payload,
headers={'Content-Type': 'application/json'})
print(resp.text)
Note that the method POST is the function instead of a parameter and that is uses the named param data instead of body. It also returns a Response object, so you have to access its text property to get the actual response content.
Also, you don't need to json.dumps your string. That function is used to convert Python objects to JSON strings. The string you're using is already valid JSON, so you should just send that directly.
Here is an online utility you can check out to convert curl requests to python code.
Curl to python converter
Another alternative is Postman application. There you will have the option to convert curls to code for various languages, in the code section.
It a very good practice to check if the api requests are working by running the curl in postman.
And for your case, here is the code using python requests library.
import requests
headers = {
'content-type': 'application/json',
}
data = '{"command":["uptime"], "iplist":["10.0.0.1"], "sudo":true}'
response = requests.post('http://localhost:81/kris/execute', headers=headers, data=data)
Hope that helps! Happy Coding!
what is python request equivalent of following curl put command.
curl --location --request PUT 'https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName Issuing CA1 - PoC/69108C91844E53258C646444E0FF0FB797349753/revoke?reason=KEY_COMPROMISE' \
--header 'Content-Type: application/json' \
--data-raw ''
Try:
import requests
headers = {
'Content-Type': 'application/json',
}
params = (
('reason', 'KEY_COMPROMISE'),
)
response = requests.get('https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName%20Issuing%20CA1%20-%20PoC/69108C91844E53258C646444E0FF0FB797349753/revoke', headers=headers, params=params)
#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.get('https://xxxx/ejbca/ejbca-rest-api/v1/certificate/CN=CompanyName Issuing CA1 - PoC/69108C91844E53258C646444E0FF0FB797349753/revoke?reason=KEY_COMPROMISE', headers=headers)
There is a library which supports these convertion.
pip install uncurl
I was not using correct url pattern, now I am using that I am able to do the needful.
import requests
url = f'https://someserver.dv.local/ejbca/ejbca-rest-api/v1/certificate/CN=SomeCompany%20Name%20Issuing%20CA1%20-%20PoC/8188/revoke?reason=KEY_COMPROMISE'
response = requests.put(
headers={
'content-type': 'application/json'
},
verify=('cacertstruststore.pem'),
cert=('restapi-cert.pem', 'restapi-key.key')
)
json_resp = response.json()
print(json_resp)
Response
{'issuer_dn': 'CN=SomeCompany Name CA1 - PoC', 'serial_number': '8188', 'revocation_reason': 'KEY_COMPROMISE', 'revocation_date': '2020-04-14T18:06:33Z', 'message': 'Successfully revoked', 'revoked': True}
I am trying to pull data from github api using specific search query and put it into a .txt file. I am able to do so by through curl and shell but I need to do it in python which I am very unfamiliar with. I have seen the requests library
I've tried using this website https://curl.trillworks.com/ and using requests library but I can't seem to wrap my head around how to format the request.
curl -H "Authorization: token xxx" 'https://api.github.com' "https://github.com/api/v3/search/repositories?q=Evidence+locker+Seed+in:readme" > evidencelockerevidence.txt
The above code does exactly what I need it to do (passes GHE token, calls api, stores it in a file) I just need help converting to python please.
EDIT: Solution was
import requests
headers = {
'Authorization': 'token xxx',
}
url = 'https://github.ibm.com/api/v3/search/repositories?q=Evidence+locker+Seed+in:readme'
response = requests.get(url, headers=headers)
print(response)
print(response.text)
All -H tags need to be specified in the headers key, and the url is the first positional argument.
import requests
headers = {
'Authorization': 'Bearer bearer_token',
}
url = 'https://github.com/api/v3/search/repositories?q=Evidence+locker+Seed+in:readme'
response = request.get(url, headers=headers)
print(response)
print(response.text)
That handles getting the data, now you have to worry about writing it to a file, which you can do with the open built-in function:
with open('path/to/evidencelockerevidence.txt', 'w') as file:
file.write(response.text)
The following curl command works as intended. Uses POST to send a bit of information to a web site.
curl 'https://...' \
-X PUT \
-d "submission[posted_grade]=65" \
-H "Authorization: Bearer 10~X"
What should be the equivalent python3 code, gives an Error 500: Internal Server Error
url_string = 'https://...'
data = "submission[posted_grade]=40"
data = data.encode('utf-8')
req = urllib.request.Request(url_string, data)
req.add_header("Authorization", "Bearer 10~X")
req.add_header("Content-Type", "application/json")
response = urllib.request.urlopen(req)
print(response.read())
Already tried
data = {'submission[posted_grade]': '40'}
data = json.dumps(data)
data = data.encode('utf-8')
Which gives "HTTP Error 422: Unprocessable Entity"
Any ideas on fixing it?
Thanks #cody
Lesson learned, PUT != POST
The following code works as expected:
url_string = 'https://...'
data = "submission[posted_grade]=40"
data = data.encode('utf-8')
req = urllib.request.Request(url=url_string, data=data, method='PUT')
req.add_header("Authorization", "Bearer 10~X")
response = urllib.request.urlopen(req)
The Ecobee API documentation shows this as a way to access their API:
#curl -s -H 'Content-Type: text/json' -H 'Authorization: Bearer AUTH_TOKEN' 'https://api.ecobee.com/1/thermostat?format=json&body=\{"selection":\{"selectionType":"registered","selectionMatch":"","includeRuntime":true\}\}'
I have used that code in curl and it seems to work.
However when I try what I think is the equivalent python code it doesn't work.
(I really don't know curl well at all. What I know I know from a few hours of internet research.)
the code I am using:
import requests
headers = {"Content-Type": "text/json", "Authorization": "Bearer AUTH_TOKEN"}
response = requests.get('https://api.ecobee.com/1/thermostat?format=json&body=\{"selection":\{"selectionType":"registered","selectionMatch":"","includeRuntime":"true"\}\}', headers=headers)
print(response.text)
When I send this I get:
{
"status": {
"code": 4,
"message": "Serialization error. Malformed json. Check your request and parameters are valid."
}
}
Not sure what could be wrong with my json formating. Any help is much appreciated.
You'll need to URL-escape the special characters in the parameters.
Doing this by hand can be messy and prone to mistakes. I'm not a Python expert but initial research suggests using the params option built into Python's request.get(). For example:
import requests
url = 'https://api.ecobee.com/1/thermostat'
TOKEN = 'ECOBEEAPIACCESSTOKEN'
header = {'Content-Type':'text/json', 'Authorization':'Bearer ' + TOKEN}
payload = {'json': '{"selection":{"selectionType":"registered","selectionMatch":"","includeRuntime":"true"}}'}
response = requests.get(url, params=payload, headers=header)
print(response.url)
print(response.text)