Django Rest API POST issues - python

I'm trying to build a very simple REST API in Django 1.8 with Django REST Framework in Visual Studio, in which I want to have a single service method to process a JSON, but I can't seem to make a POST:
I'm trying to send this simple JSON through Postman, just as a test:
{
"foo":"bar"
}
with the header:
Content-Type: application/json
Here's my method:
#csrf_exempt
#api_view(['POST'])
def test(request):
data = request.data
return HttpResponse(status=200)
But my problem is that request.data is empty. And if instead I try to access request.body, I get
You cannot access body after reading from request's data stream.
Any ideas what could be the issue here?

Figured this out somewhat, it seems to be an issue with Visual Studio while in debug mode. If I try to access the request while debugging before calling any Python function on it (such as a simple print, or passing in to a function to parse it), it shows up as an empty QueryDict, otherwise it shows up fine.

Just a guess: maybe the issue is in Postman?
Try to send POST-request without headers, but with raw JSON (not form-data):

This may help Where's my JSON data in my incoming Django request?
Outside of this, make sure the content-type and accept-type are set properly. What is the raw response in Postman? Is the security setup properly?

I have the same problem when using POSTMAN.
Solved and Credit goes to https://stackoverflow.com/a/31977373/764592
Quoted Answer:
Request payload is not converted into JSON format.
I am passing my data in Body as x-www-form-urlencoded
You can fix it by using Content-Type as application/x-www-form-urlencoded in request header.

Related

Python request send post request with params not as dictionary

So this seems like it would be a simple thing to do but I can't seem to get it to work. I want to send a post request to a local flask server running on my computer. So I use the following line of code to do it
r = requests.post(end_url + '/upload/flash', cookies=cookie, params='title=asdfg&description=asdfg&front1=f&back1=b&number=1&edu_level=&school=&course=&grade=&unit=&chapter=&section=&tag=')
The problem is not with the params I'm passing into the function as they are formatted correctly. The problem is that the flask server is trying to access the "title" arg from the request but can't find it. All of the examples I have seen format the params in a dictionary (ex.
{"title": "asdfg"}
I would imagine that it is possible to send a request the way I am trying but am not sure what I have done wrong.
The problem was actually not with the params. I was mixing up "params" and "data". I also needed to include the headers
headers={"Content-Type": "application/x-www-form-urlencoded"}
Thanks to everyone who help me troubleshoot my code.

What error to raise with wrong post request body?

I am new to Django and have an endpoint that accepts post requests. The endpoint expects a specific set of keys in the post request body. What type of Exception should I raise if they don't provide the right keys? ValueError? Thanks!
You should return a HttpResponseBadRequest response and include a helpful message with the invalid data. This returns a 400 response which is used to indicate issues with request data
If you are creating rest endpoints with Django it is worth using a library like https://www.django-rest-framework.org/ as it can simplify their creation and handle a lot of the leg work around validation, serialisation and reponses

POST parameters formatted as JSON

I am writing a web service using Django that will be consumed from a MS SharePoint workflow. In the SP workflow, I created a dictionary with 2 items (id:1, text:'foo'), and used this dictionary as the request content. However, instead of using the dictionary to format a traditional POST parameter list, it sends it as a JSON object in the body of the POST request, so instead of the expected:
id=1&text=foo
in the body of the request, there is this:
{"id":1,"text":"foo"}
which of course, in turn, does not get parsed correctly by Python/Django (I am not sure who exactly does the parsing). How can I either get it to parse JSON, or get SharePoint to send traditionally encoded POST parameters?
EDIT
I saw other posts that explain how to get the raw body and parse the JSON. I was looking for a solution that would either:
Make SharePoint send normal data, or
Get Django to respect the Content-type header that states the data is JSON
There is no need for any parsing at the framework level. The body of the post request is always available in request.body, so you can access it directly:
result = json.loads(request.body)
May be it will help you bit more to handle.
import json
import urlparse
json.dumps(urlparse.parse_qs("id=1&text=foo"))

HTTP PUT works in RESTClient but not in Postman or Python httplib

When I do a PUT request in RESTClient it works, but it fails in the Postman Chrome extension.
I need to call the Hadoop REST API. When I use curl all is okay, as with RESTClient. It fails when I use Python httplib, as with Postman.
Here is it working in RESTClient:
Here is it failing in Postman:
It returns a java.lang.UnsupportedOperationException with the message op=NULL is not supported.
How can I send this PUT request correctly with Python's httplib? For some reason curl is not suitable here.
It looks like the endpoint you're hitting requires an op argument to be provided in the query string. You have ?op=CREATE in your RESTClient screenshot, but it doesn't appear in your Postman screenshot.
I notice also that in your RESTClient screenshot the server is responding with a redirect to add an additional parameter overwrite=false; you may need to add this parameter to your request in order for the operation to actually be carried out.

Flask: Getting request parameters based on Content-Type header

What is the proper way to deal with the request body depending on the Content-Type header of the request?
I need to implement a RESTful service that supports XML, JSON and form encoded request parameters, but I can't seem to find a clean way of extracting the request parameters.
Is this something that I should use a middleware for? Do I need to extend the Request object?
I haven't found any packages that do this, and it seems like a pretty common task for creating RESTful services in flask.
You probably meant Accept header, as Content-Type is used for response. There are three choices here:
Build it youself as described in Handling Accept Headers snippet.
Use Flask-RESTful extension (consult Content Negotiation part in the docs).
Use Flask-Pushrod extension which is specifically built to handle this case.
You could use #app.before_request as illustrated here. Once you've done your thing normalizing the request params, you can save them to g, something like this:
from flask import g
from flask import request
...
#app.before_request
def before_request():
# normalize params based on Content-Type
g.params = normalized_params

Categories

Resources