python put requests a file - python

i'm trying to interact with a website's APIs--specifically how to requests.put() a file (JPEG) to it. the Swagger API has a "try it out" function where I successfully can push a file from its "try it out" but when I try to run it in python it throws a 500 internal server error.
this is the successful curl put request from the Swagger "try it out":
curl -X PUT "https://some_website.com/api/v2/documents" -H "accept: /" -H "Content-Type: multipart/form-data" -H "Authorization: Bearer auth tokenp089u098u08j98jasdfsadgfasdg" -d {"file":{},"metadata":"{ "docType":"BILL_OF_LADING", "docTypeNamespace":"platform", "fileType":"IMAGE", "docReferences":{ "name":"bill o lading pal" }, "identifiers":{ "consignment":{ "carrierBookingNumber":"9876smg", "billOfLadingNumber":"1234smg" } } }"}
url = "https://some_website.com"
auth_token = "Bearer auth tokenp089u098u08j98jasdfsadgfasdg"
headers = {"Content-Type": "multipart/form-data",
"Accept": "*/*",
"Authorization": sa_token}
file_loc = "C:/location/of/file/I/want/to/put/Capture.JPG"
metadata = {
"docType":"doc_file",
"docTypeNamespace": "platform",
"fileType":"IMAGE",
"docReferences": {
"name": "this is the form to confirm receipt"
},
"identifiers": {
"consignment": {
"carrierBookingNumber":"9876smg",
"billOfLadingNumber":"1234smg"
}
}
}
body = {
"file": {},
"metadata": metadata
}
resp = requests.put(url=url, headers=headers, data=body)

You should probably send it via json as thats very easy...
import requets
file = "C:\somedir\somedir\somefile.somext"
with open(file, "rb") as f:
fileData = f.read()
putFile(fileD, site, port=3000):
requets.post(site, json='{"file": "' + str(fileD) + '"}'
But you'll need to convert it back to a file.

Related

Post method returns 422 using Requests but working fine with CURL and Postman

I am using Python with Requests module to connect to an EasyRedmine API. I'm having trouble creating a project using the post method in order to post a JSON. It returns "[Unprocessable Entity
<Response [422]>]". I have tried the same request using Postman and Curl and it works perfectly. Does anyone know what could be causing this problem? The following curl command works fine.
curl -X 'POST'
'https://cafte.easyredmine.com/projects.json?key=0224b4238XXXX'
-H 'accept: application/json'
-H 'X-Redmine-API-Key: 0224b4238XXX'
-H 'Content-Type: application/json'
-d '{
"project": {
"easy_external_id": "external-system-1",
"name": "Blue 2",
"homepage": "blue-7",
"description": "I can’t abide these Jawas. Disgusting creatures.",
"author_id": 0,
"is_planned": true,
"easy_is_easy_template": true,
"easy_currency_code": "EUR"
}
This is the methode code:
def create_project(self, name: str, description="", external_id="", homepage="", parent_id="", author_id="",
is_planned= 'false', is_easy_template= "true", start_date="", due_date="", custom_fields=[],
tag_list=[], currency='EUR'):
print(name)
data = {"project": {
"easy_external_id": external_id,
"name":name,
"homepage": homepage,
"description": description,
"parent_id": parent_id,
"author_id": author_id,
"is_planned": is_planned,
"easy_is_easy_template": is_easy_template,
"easy_start_date": start_date,
"easy_due_date": due_date,
"custom_fields": custom_fields,
"tag_list": tag_list,
"easy_currency_code": currency
}
}
endpoint_path = "/projects"
endpoint = f'{self.base_url}{endpoint_path}'
headers = {'X-Redmine-API-Key': f'{self.api_key}',
'accept': 'application/json',
'Content-Type': 'application/json'
}
r = requests.post(endpoint, headers=headers, json= data)

How to send a text message with Whatsapp Cloud API

I'm having troubles using Whatsapp Cloud API (which was released to the public on May 22). I did everything in the getting started in "Set up Developer Assets and Platform Access" section, that way I was able to send the template hello world in Ubuntu 20.04.4 LTS with:
curl -i -X POST \
https://graph.facebook.com/v14.0/my_number/messages \
-H 'Authorization: Bearer my_token' \
-H 'Content-Type: application/json' \
-d '{ "messaging_product": "whatsapp",
"to": "my_reciever",
"type": "template",
"template": { "name": "hello_world", "language": { "code": "en_US" } }
}'
or with Python 3.10 and requests 2.27.1 with:
from requests import Session
import json
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
BASE_URL = "https://graph.facebook.com/"
API_VERSION = "v13.0/"
SENDER = "my_number/"
ENDPOINT = "messages"
URL = BASE_URL + API_VERSION + SENDER + ENDPOINT
API_TOKEN = "my_token"
TO = "my_reciever"
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
parameters = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": TO,
"type": "template",
"template": {"name": "hello_world", "language": {"code": "en_US"}}
}
session = Session()
session.headers.update(headers)
try:
response = session.post(URL, json=parameters)
data = json.loads(response.text)
print(f"data: {data}")
except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)
Then, I tried to send a text message with this:
from requests import Session
import json
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
BASE_URL = "https://graph.facebook.com/"
API_VERSION = "v13.0/"
SENDER = "my_number/"
ENDPOINT = "messages"
URL = BASE_URL + API_VERSION + SENDER + ENDPOINT
API_TOKEN = "my_token"
TO = "my_reciever"
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
parameters = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": TO,
"type": "text",
"text": {
"preview_url": "false",
"body": "MESSAGE_CONTENT"
}
}
session = Session()
session.headers.update(headers)
try:
response = session.post(URL, json=parameters)
data = json.loads(response.text)
print(f"data: {data}")
except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)
And, even though the response is correct, something like this:
{'messaging_product': 'whatsapp', 'contacts': [{'input': 'my_reciever', 'wa_id': 'my_reciever'}], 'messages': [{'id': 'wamid.HBgMNTchangingMDYyM0I2AA=='}]}
I don't recieve any message in my_reciver. I don't know what I'm doing wrong, I might have to configure the webhook for this to work? Do I need to opt-in before recieve the message (this can be read in get-started page)?
I even tried using some unofficial wrappers in python like heyoo, but I got the same result.
Hope someone can help me with this, thanks.
Note: this is a similar post, but that one is with node, not Python or Curl, so I guess this does not count as repost.
I have written a brief article on WhatsApp Cloud API like how to send and receive WhatsApp messages and also set up a never expiry access token. Please have a look WhatsApp Cloud API
You need to send the WhatsApp message from your personal number to your WhatsApp business number after that you can send the message from your business number to your personal number. Basically, WhatsApp has a template message concept within 24h session and according to your question, I think you are trying to send a normal unsession message from a business number to your personal number. So, to avoid this case you need to first message from your personal to your business number then you can receive the message to your personal number. Full details in the article regarding template message.
Here is the CURL request for normal message
curl --location --request POST 'https://graph.facebook.com/v13.0/<Your Phone number ID>/messages' \
--header 'Authorization: Bearer <Your Temporary access token>' \
--header 'Content-Type: application/json' \
--data-raw '{"messaging_product":"whatsapp","recipient_type":"individual",
"to":"918587808915","type":"text","text": {"body":"Hello Rishabh!"}
}'
The official META-whatsapp documentation indicates that in order to send such messages, the conversation must be initiated by the user. https://developers.facebook.com/docs/whatsapp/conversation-types

Forming a request.post from a curl on python

I have a small project i need a tempmail for, so i found this site https://mail.tm/en, so i was trying to acess the post via the api and instructions given here https://api.mail.tm/.
As I am new at working with curl and so on I have a lot of problems authorizing into an account there.
First of all i got an CURL link on site like this one:
curl -X POST "https://api.mail.tm/accounts" -H "accept: application/ld+json" -H "Authorization: testing" -H "Content-Type: application/ld+json" -d "{\"address\":\"test\",\"password\":\"stackoverflow\"}"
I tried to form it all in a post request, so i did this
headers = {"accept": "application/ld+json", "Authorization": "header", "Content-Type": "application/ld+json"}
data = "{\"address\":\"zashyganii\",\"password\":\"chertila\"}"
mail = requests.post("https://api.mail.tm/accounts", data = data, headers = headers)
print(mail.status_code)
the error code is 400, noted on the api site like this.
400 Error:
Response body
Download
{
"#context": "/contexts/ConstraintViolationList",
"#type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "address: This value is not a valid email address.\naddress: The domain \"\" is not valid.",
"violations": [
{
"propertyPath": "address",
"message": "This value is not a valid email address."
},
{
"propertyPath": "address",
"message": "The domain \"\" is not valid."
}
]
}
Could you please turn this curl in to a request.post on python so it will work for this api
Seems like there are not any problem with the request. It's a validation fail.

Python equivalent for Curl giving 400 Response

Trying to re-write shell curl to python script with requests module...
My shell script :
#!/bin/bash
ip=$1
url=https://xxx.xx.xx.com
secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
expand=computerStatus
curl --silent -X POST "$url/api/computers/search?expand=$expand" -H "Content-Type: application/json" -H "api-secret-key: $secret" -H "api-version: v1" -d '{"maxItems": 10,"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": "'"$ip"'"}]}' -k > $file
above works fine in bash.
I am trying to convert to similar python equivalent
What I tried
import json
import requests
import sys
ip = sys.argv[1]
sys_info = []
url=https://xxx.xx.xx.com
secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
expand=computerStatus
headers = {
'Content-Type': 'application/json',
'api-secret-key': secret,
'api-version': 'v1',
}
params = (
('expand', 'expand'),
)
data = '{"maxItems": 10,"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": ip}]}'
response = requests.post('https://url/api/computers/search?expand=expand', headers=headers, params=params, data=data)
print(response)
<Response [400]>
I am getting 400 response.. not sure where i am missing in syntax...
data needs to be a dictionary, try this:
data = {
"maxItems": 10,
"searchCriteria": [{"fieldName": "hostName","stringTest": "equal", "stringValue": ip}]
}
Also convert params to a dictionary as well:
params = {"expand" : expand}
And when posting:
response = requests.post(f'https://{url}/api/computers/search', headers=headers, params=params, data=data)
### or alternatively you can
response = requests.post(f'https://{url}/api/computers/search?expand={expand}', headers=headers, data=data)

API requests using python

I am trying to do a request using python. The API uses:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
"$class": "org.acme.model.sensor", \
"sensorId": "1", \
"type": "Temperature", \
"value": "10", \
"timestamp": 1234123 \
}' 'http://localhost:3000/api/sensor'
to create a new sensor. I am trying to do it with python and I have created the proof of concept:
data = {
"$class": "org.acme.model.sensor",
"sensorId": "", #change in the loop with i
"type": "Temperature",
"value": "10",
"timestamp": 382453824
}
header = {
"Content-Type" : "application/json",
"Accept":"application/json"
}
url = "http://localhost:3000/api/sensor"
for i in range(2):
data["sensorId"]=str(i+1)
response = requests.post(url, data=data, headers=header)
#Now I modify the data
data["Temperature"]="50"
response = requests.put(url, data=data, headers=header)
Now, for erasing:
for i in range(2):
url="http://localhost:3000/api/sensor/"+str(i+1)
response = requests.delete(url)
With curl, it works properly but no with the python code. It fails even creating the object.
import requests
import json
header = {
"Content-Type" : "application/json",
"Accept":"application/json"
}
You need to convert your dictionary into a proper format using json.dumps and need to use request.post instead of delete
request_url = 'YOUR_END_POINT'
data = json.dumps(data)
response = requests.post(url=request_url,data=data,headers=headers)
I think that should solve it.

Categories