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)
Related
I have a working curl command:
ip_address='<my ip address>'
sessionID='<got from post request metadata>'
curl --insecure --request PUT 'https://'$ip_address'/eds/api/context/records' -H 'Csrf-Token: nocheck' -H 'AuthToken:<token>' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"sessionId": "'$session_ID'", "replace":false}'
The python script looks like below:
headers_put = {
'Csrf-Token': 'nocheck',
'AuthToken': '<my token here>',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
url_put = "https://" + ip_address + "/eds/api/context/records"
data = {
"sessionId":"<session id got from POST request metadata>",
"replace":"false"
}
response = requests.put(url_put, headers=headers_put, data=data, verify=False)
print(response)
Error message I get is:
<Response [400]>
b'Bad Request: Invalid Json'
Any idea on what I am doing wrong here? Any help is appreciated!
EDIT:
Can this error cause because of data:
print(data)
{'sessionId': '<session id received from post metadata>', 'replace': 'false'}
Http status 400 means ‘bad request’ as outlined here. You have omitted 1 request header (Csrf-token) in pyScript that was contained in your curl statement. Consider including that and retry the script.
If you still receive an error - you could try and extract (in your script) the actual text or.body of the 4xx response. It may be accessible from the text property of the python response object (you can confirm content-type) using response.apparent_encoding. Best wishes.
I found the solution:
response = requests.put(url_put, headers=headers_put, json=data, verify=False)
instead of data= we have to use json=
REST API document
---------------------------------------------------------------
curl --location --request POST 'https://zaya.io/api/v1/links' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Bearer {api_key}' \
--data-urlencode 'url={url}'
-----------------------------------------------------------------
My Code
import requests
api="https://zaya.io/api/v1/links"
API_KEY = "################################################"
data = "https://en.wikipedia.org/wiki/Python_(programming_language)"
headers = {'Authorization': 'Bearer ' + API_KEY}
r = requests.get(api, data=data, headers=headers)
print(response.text)
The error I face:
{"message":"You are not logged in.","status":403}
Mistake 1 You are doing a GET where the document asks you to send a POST.
Mistake 2 The data must be form URL encoded, must be key-value pairs
Mistake 3 You must set the proper Content-Type header
Bigger mistake Do not post your API key on public forums.
The code below works fine, with the above corrections.
import requests
api = "https://zaya.io/api/v1/links"
# Never reveal your API key
API_KEY = "##########################################################"
# Data is URL Form encoded, so it must be key-value pair
data = {"url": "https://en.wikipedia.org/wiki/Python_(programming_language)"}
# Add proper headers
headers = {'Authorization': 'Bearer ' + API_KEY, 'Content-Type': 'application/x-www-form-urlencoded'}
# Most important. CURL says POST, you did GET
r = requests.post(api, data=data, headers=headers)
print(r.text)
# Gives proper response
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}
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
I am trying to hit an endpoint with the raw request (CURL) as stated below :
!curl -i -X 'POST' "END_POINT" \
--form "api_key=xxxxx" \
--form "image= LOCAL_PATH_TO_IMAGE"
I tried using requests library of Python but I do not know how to construct the JSON request for the above.
def fetch_details(API_KEY, IMAGE_PATH, SERVICE_URL):
form = {
"api_key": API_KEY ,
"image": open(IMAGE_PATH,'rb')
}
header = {'content-type': 'application/json'}
url = SERVICE_URL
#response = requests.post(url, json = json.dumps(form), headers=header)
response = requests.post(url, json = json.dumps(json.loads(jsonpickle.encode(form))), headers=header)
if response.status_code != 200:
print('There is an error and the error is : ', response.text)
else:
attributes = response.json()
print(attributes)
I expect a JSON response for the above request but the output is "There is an error and the error : Server Error (500)"
The --form "image" parameter should contain the binary representation of the image.