POST parameters formatted as JSON - python

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"))

Related

How to deal with JSON response which is in the form of list of JSON's in Locust (Python)

I get a response (using postman) in the following format when I make a POST request (and I am passing the payload when i make this POST request).
[{"id":22,"name":tom,"age":10}]
Now, when I try resp.json(), I am getting either a JSON decode error or Unable to Parse JSON error. Is there a way to deal with this using the FastHTTPuser library for locust or using the requests library and retrieve the response from the API call as json?
Seems the API you are using to generate that JSON has an error - tom should be under quotes ("tom") as well.
import json
json.loads('{"id":22,"name":tom,"age":10}') # fails with JSONDecodeError
json.loads('{"id":22,"name":"tom","age":10}') # works as expected

Pass JSON response of REST API as input data into APACHE SOLR

I have a REST API built using Flask. It has GET and POST methods. The API returns a JSON response. I want SOLR to use the REST API's URL to perform a search on this response based on the query and return relevant search results.
How can I achieve this? Does SOLR only take a JSON file as input, in which case I would need to write endpoint's response to a JSON file, place it in the example folder and pass it into SOLR?
I want SOLR to use the REST API's URL to perform search on the data(JSON response) based on the query and return relevant search results
You will have to invoke the REST API, get back the JSON response and add it to Solr Index. Then you can use Solr to search that data.
Could you please let me know how to achieve this? Is it possible?
Please take a look at this documentation. It will help you indexing JSON documents.
https://lucene.apache.org/solr/guide/7_1/uploading-data-with-index-handlers.html#solr-style-json
Or does SOLR only take JSON file as input placed in the example folder, in which case, I would need to write the response received from my RESTAPI to a json file, place it in the example folder and pass it into SOLR
This is partially correct understanding, however you do not have to place it in example folder. You need to post that JSON (or format JSON in the form required by Solr) as shown in the reference provided above.
Hope this helps.
Thanks Amit! In the link you shared, it had curl commands. But I was trying to do this with Python. I found out a solution for this! Works like a charm. I have also embedded comments for further explanation.
#app.route('/solrInput', methods = ['POST'])
def solr_input():
"""Get response data from MongoDB RESTAPI and feed into SOLR for indexing"""
#get mongoDB data from rest api
input_data = requests.get('http://127.0.0.1:5000/getAllRecords')
json_data = input_data.json()
#loop through response to fetch the values
for key, val in json_data.items():
payload = str(val)
response = requests.post("http://localhost:8983/solr/techs/update/json/docs?commit=true", data=payload)
if __name__ == "__main__":
app.run(debug=True)

Using python, Is it possible to directly send form data to a website server and receive response without using a browser?

I took a programming class in python so I know the basics of the language. A project I'm currently attempting involves submiting a form repeatedly untill the request is successful. In order to achieve a faster success using the program, I thought cutting the browser out of the program by directly sending and recieving data from the server would be faster. Also the website I'm creating the program for has a tendency to crash but I'm pretty sure i could still receive and send response to the server. Currently, im just researching different resources I could use to complete the task. I understand mechanize is easy to fill forms and submit them, but it requires a browser. So my question is what would be the best resource to use within python to communicate directly with the server without a browser.
I apologize if any of my knowledge is flawed. I did take the class but I'm still relatively new to the language.
Yes, there are plenty of ways to do this, but the easiest is the third party library called requests.
With that installed, you can do for example:
requests.post("https://mywebsite/path", {"key: "value"})
You can try this below.
from urllib.parse import urlencode
from urllib.request import Request, urlopen
url = 'https://httpbin.org/post' # Set destination URL here
post_fields = {'foo': 'bar'} # Set POST fields here
request = Request(url, urlencode(post_fields).encode())
json = urlopen(request).read().decode()
print(json)
I see from your tags that you've already decided to use requests.
Here's how to perform a basic POST request using requests:
Typically, you want to send some form-encoded data — much like an HTML
form. To do this, simply pass a dictionary to the data argument. Your
dictionary of data will automatically be form-encoded when the request
is made
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
response = requests.post("http://httpbin.org/post", data=payload)
print(response.text)
I took this example from requests official documentation
I suggest you to read it and try also other examples available in order to become more confident and decide what approach suits your task best.

Django Rest API POST issues

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.

Send nested dict or list from a Python script to Rails app via HTTP

I need to send a nested list or dict from a Python script to Ruby on Rails 3 app via HTTP. Ideally, I want to be able to retrieve the object just by using Rails params[] in the controller.
I'm new to all this. Could you please tell me how to do this? I've read that formatting the nested list or dict to JSON might be the best way, but I don't know how to send JSON data via HTTP, let alone make the sent data be easily accessible using Rails params[].
It just depends on what kind of request you make. If you do a get request then a simple string formatted like so would work:
example.com/controller/action?param1=value&param2=other%20value
In Rails this would set params[:param1]='value' and params[:param2]='other value'`.
If you want to send json just send it as an HTTP post with the content type 'text/json', and make sure the url you post to ends in .json, like so:
example.com/controller/action.json
That will set the params hash with the same keys and values as your json.

Categories

Resources