How to Do Http Put in Python

Is there any way to do HTTP PUT in python

I've used a variety of python HTTP libs in the past, and I've settled on requests as my favourite. Existing libs had pretty useable interfaces, but code can end up being a few lines too long for simple operations. A basic PUT in requests looks like:

payload = {'username': 'bob', 'email': 'bob@bob.com'}
>>> r = requests.put("http://somedomain.org/endpoint", data=payload)

You can then check the response status code with:

r.status_code

or the response with:

r.content

Requests has a lot synactic sugar and shortcuts that'll make your life easier.

HTTP PUT request in Python using JSON data

Your data is already a JSON-formatted string. You can pass it directly to requests.put instead of converting it with json.dumps again.

Change:

response = requests.put(url, data=json.dumps(data), headers=headers)

to:

response = requests.put(url, data=data, headers=headers)

Alternatively, your data can store a data structure instead, so that json.dumps can convert it to JSON.

Change:

data = '[{"$key": 8},{"$key": 7}]'

to:

data = [{"$key": 8},{"$key": 7}]

How to specify python requests http put body?

Quoting from the docs

data – (optional) Dictionary or bytes to send in the body of the Request.

So this should work (not tested):

 filepath = 'yourfilename.txt'
with open(filepath) as fh:
mydata = fh.read()
response = requests.put('https://api.elasticemail.com/attachments/upload',
data=mydata,
auth=('omer', 'b01ad0ce'),
headers={'content-type':'text/plain'},
params={'file': filepath}
)

How to correctly requests.put in Python 3.7

If you take a look at the API documentation, you will notice it requires you to send required data into the body of the requests.

Here is an example on how to send data into the body using the requests module:

data = {
"message": yourMessageInfo,
"name": yourNameInfo,
"object": yourObjectInfo,
"priority": yourPriorityInfo,
"query": yourQueryInfo,
"tags": yourTagsInfo,
"type": yourTypeInfo
}

response = requests.put(api_url, headers=headers, json=data)

You will of course need to fill in all the information.

Another example straight from the documentation:

data = {
"message": "string",
"name": "string",
"options": {
"enable_logs_sample": false,
"escalation_message": "string",
"evaluation_delay": "integer",
"include_tags": false,
"locked": false,
"min_failure_duration": "integer",
"min_location_failed": "integer",
"new_host_delay": "integer",
"no_data_timeframe": "integer",
"notify_audit": false,
"notify_no_data": false,
"renotify_interval": "integer",
"require_full_window": false,
"restricted_roles": [],
"silenced": {
"<any-key>": "integer"
},
"synthetics_check_id": "string",
"threshold_windows": {
"recovery_window": "string",
"trigger_window": "string"
},
"thresholds": {
"critical": "number",
"critical_recovery": "number",
"ok": "number",
"unknown": "number",
"warning": "number",
"warning_recovery": "number"
},
"timeout_h": "integer"
},
"priority": "integer",
"query": "string",
"tags": [],
"type": "string"
}

response = requests.put(api_url, headers=headers, json=data)

More information in the API documentation and the picture below:

required headers image

request.put() but it request using GET by PUT on my python

You are almost certainly being redirected. The PUT request is sent, but the server responded with a 3xx redirection response code, which requests then follows and issues a GET request for. I note that the path in your wireshark screenshot doesn't match the one used in your code (the /test prefix is missing), further adding evidence that a redirection has taken place.

You can check the redirection history by looking at r.history (each entry is another response object), or set allow_redirects=False to not respond to redirects (you get the first response, nothing else).

You are probably getting redirected because you are double-encoding your JSON payload. There is no need to use json.dumps on a string that is already a JSON document. You are sending a single JSON string, whose contents happen to be a JSON document. That is almost certainly the wrong thing to send.

Correct this by removing the json.dumps() call, or by replacing the payload string with a dictionary:

payload = {
"assignee": {
"district": "3",
"phone": "01010001000",
"carNum": "598865"
},
"deduction": {
"min": 1000,
"max": 2000
},
"meta": {
"unit-label": "1-1-1",
"year": "2017",
"quarter": "2"
}
}

Incidentally, you would be better off then using the json keyword argument; you get the Content-Type: application/json header as an added bonus:

headers = {"x-api-key": "test_api_dp" }    
r = requests.put(url, json=payload, headers=headers)

Again, this assumes that payload is a Python data structure, not a JSON document in a Python string.

PUT Request to REST API using Python

Syntax error in because of = sign in your headers dictionary:

headers = {'Authorization': 'Bearer ' + token, "Content-Type": "application/json", data=data}

It should be:

headers = {'Authorization': 'Bearer ' + token, "Content-Type": "application/json", 'data':data}

See data=data is changed with 'data':data. Colon and Single Quotes.

And are you sure you will be sending data in your headers? Or you should replace your payload with data in your put request?

Edit:

As you have edited the question and now you are sending data as PUT request's body requests.put(data=data) so there is no need of it in headers. Just change your headers to:

headers = {'Authorization': 'Bearer ' + token, "Content-Type": "application/json"}

But as you have set your Content-Type header to application/json so I think in your PUT request you should do

response = requests.put(url, data=json.dumps(data), headers=headers)

that is send your data as json.

python: HTTP PUT with binary data

It's because

data should be a buffer in the standard application/x-www-form-urlencoded format. The urllib.urlencode() function takes a mapping or sequence of 2-tuples and returns a string in this format.

from urllib2 doc

Handle the HTTP PUT method in Python WSGI

As I understand it, you will just want to read the stream environ['wsgi.input'], because a PUT request will send the entire contents of the PUT as the body of the request.

I am not aware of any encoding issues you will have to deal with (other than the fact that it is binary).

Some time ago, I wrote a simple set of PHP scripts to take and give huge files from another server on a LAN. We started with POST, but quickly ran out of memory on the larger files. So we switched to PUT, where the PHP script could take it's good time looping through php://input 4096 bytes at a time (or whatever)... It works great.

Here is the PHP code:

$f1 = fopen('php://input', 'rb');
$f2 = fopen($FilePath, 'wb');

while($data = fread($f1, 4096))
{
fwrite($f2, $data);
}

fclose($f1);
fclose($f2);

From my experience in handling multipart/form-data in WSGI with POST, I have little doubt that you can handle a PUT by just reading the input stream.

The python code should be like this:

  output = open('/tmp/input', 'wb')
while True:
buf = environ['wsgi.input'].read(4096)
if len(buf) == 0:
break
output.write(buf)


Related Topics



Leave a reply



Submit