This question already exists:
Flask response - TypeError: 'NoneType' object is not callable [duplicate]
Closed 1 year ago.
I am writing code, in order to test a flask REST server.
One of the responses of the server is:
return make_response(json.dumps({'myName': userName}), 200)
I can have access to the response's status code with:
response.status_code
But how do i have access to the myName parameter of the server's response?
This question has very little to do with Pytest. All you're doing is parsing a JSON body into a dictionary and accessing its properties. That's all doable with requests library and Python itself.
I recommend reading requests documentation here, the first code block is enough in your example.
So a solution for your problem is:
import requests
my_name_property = requests.get("server_url").json()["myName"]
or in more steps:
import requests
response = requests.get("server_url")
response_body = response.json()
my_name_property = response_body["myName"]
You can't use response.myName, that's not how you access properties of a dictionary in Python. This would work with e.g. namedtuple in Python, or in Javascript. But not in Python when using dictionaries, which is what json() method returns in the examples above.
If something doesn't work, I recommend using Postman or any other such client to figure out what's going on on the API, how to call it, what response you get, in what structure, and once you understand it, write some tests in Python.
Related
As mentioned in the title, I attempt to
POST JSON file from C# (which is a WinForms accepting user input, then converted into a json), then to be received by python. I am quite clueless as to how to start at the C# side of the coding as I am still new to this. Would appreciate any kind help from here. Thanks
I use httpclient to communicate between the two languages, and now I would like to send the json file to the python side.
In short, the working principle of my project is:
User input parameters at WinForms that I have designed using C#, then these parameters are transferred over to Python by the flask and HTTPclient architecture.
Python process the parameters and a result is obtained, where I now wish to transfer this result back to C#, to be displayed on WinForms.
Flask is easy to use and set up for a simple POST request like this. The flask docs are excellent: https://flask.palletsprojects.com/en/2.0.x/quickstart/#a-minimal-application
Assuming you have pip installed Flask >= v2.0, a simple flask application to receive a POST request would look like:
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.post('/submit_input')
def submit_input():
# check that your data is json
if request.json:
data = request.json
# do something with the data here and create a new var...
new_var = 'this is some new data'
return jsonify(message=new_var)
Recently, Iv'e been using the Joi validation library in-order to validate the data which comes in from a request (building a RESTful API).
I was using the .label() method to generate a string response and send it back to the user, but I couldn't find any way to send a JSON response back to the user?
Tried sending a premade JSON inside the string, searching the documentation and the internet of course - couldn't find any mention of it.
Current code example:
textField: Joi.string().required().max(4).label("This example field didn't pass the testing phase, please try again)"),
Any ideas?
If you need to send data in case of error,try .error() method. you can pass error in it.
I have a http request I am trying to make on an afterSave method in my Cloud Code. I have been able to create my request, and when I console.log(response) it outputs a block that contains the information that I am after. I am aware that response.text is a string so I am trying to run JSON.parse(response.text) so I can access my API response.
I can print out what appears to be an object after running JSON.parse, but much of the data within my response is stripped out. I know it is not the fault of the API because I have another function that runs on the client with the same query and it works correctly.
What is the correct way to parse the response.text from a Parse.Cloud.httpRequest to maintain my data.
Try var result = JSON.parse(response['text']).
I'm trying to implement tests for the Django Rest Framework.
Most of my tests pass and setting them up went smooth, but i'm having an issue now where an assertEqual never succeeds because it keeps comparing JSON with an OrderedDict.
I have no idea where the OrderedDict comes from since DRF should only return JSON (right?).
Might it be possible that the testing environment is parsing the JSON before comparison? That would suck.
I'm doing an integrated test that only tests the data in the response of a GET request to a certain resource, I do this based on JSON fixtures. I'm not testing a specific component of the REST framework since my implementations of the components are so simple they're already tested by the tests in the DRF project.
Anyways, I hope someone can help me!
As explained here, this is because the default format for requests during tests is multipart instead of json. You can specify the format by providing it to your api call like so:
response = self.client.get('/something/1', format='json')
Or you can set the default test request format in your settings.py like so:
REST_FRAMEWORK = {
'TEST_REQUEST_DEFAULT_FORMAT': 'json', # Use application/json instead of multipart/form-data requests in tests.
}
To fix it for all your tests automagically.
It sounds like you're using response.data (which returns the parsed json objects) instead of response.content (which gives the raw json string).
See http://www.django-rest-framework.org/api-guide/testing/#testing-responses
If your tests look something like this:
class SomeTests(APITestCase):
def test_something(self):
response = self.client.get('/something/1')
# assertions with response
Then response will certainly be an OrderedDict rather than a JSON document. Luckily Django 1.9 has introduced the response.json() method (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#django.test.Response.json) so you can easily convert the response into JSON. Note that you could also use python's json library.
The catch here is that Django's test client (that DRF extends) is a "dummy browser" (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#the-test-client) and doesn't work exactly like an in-browser framework such as Selenium would. Thus, HTTP calls are actually just simulated HTTP calls that focus on testing your logic and that correct routing/views/serializers/etc. are being used.
You can dump your data into json format :
import json
return HttpResponse(json.dumps(data))
I solved the problem by using SerializerMethodField.
Simply, within the serializer class copy next last 3 lines and replace result with the json member that cause the problem
class ConfigSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Config
fields = ('id', 'url', 'email', "result",)
# COPY NEXT 3 LINES AND CHANGE 'result' WITH THE JSON MEMBER THAT CAUSE THE PROBLEM
result = serializers.SerializerMethodField()
def get_result(self, obj):
return obj.result
Before the result shows as:
{result: "OrderedDict([('key1', 1), ('key2', OrderedDict([('key3', [1, 2, 3])]))])"}
After solution, result become:
{"result": {"key1":1,"key2":{"key3":[1,2,3]}}}
I'm building an application that communicates with a django backend using json-rpc. So far all has been working well. However I've found an anomaly in sending " ". As far as I know the request works fine, however django interprets the response badly. I've reproduced a simplified request and response below:
Request:
{"jsonrpc":"2.0","id":"1","method":"test","params":
{"id":"80","name":"tests","introduction":"hello there"}}
Django receives:
<QueryDict:u'{"jsonrpc":"2.0","id":"1","method":"test","params":
{"id":"80","name":"tests","introduction":"hello ': [u''], u'nbsp': [u''], u'there"}}': [u'']}>
Expected response:
<QueryDict: {u'{"jsonrpc":"2.0","id":"1","method":"test","params":
{"id":"80","name":"tests","introduction":"hello there"}}': [u'']}>
It seems like django interprets the & and the ; as special characters and so creates an unexpected dictionary in its request.POST variable.
What do I need to do to make sure that the json string doesn't get malformed? I have tried encoding it using the php htmlspecialchars() method, but since that doesn't remove the '&' the problem persists.
Any help will be much appreciated.
Django is handling the (POST?) request by decoding the body (your json string) as if it were a query string, and not a json.
Within a query string, & and ; denote the end of a key:value pair. Splitting up your request body on those two characters yields the key:value pairs you see in the Django QueryDict.
You need to get hold of the POST request body and explicitly decode it to a dict yourself using either the standard lib json, or simplejson module.
I have little experience with Django specifically, but I imagine that somewhere in your view handler you would do something akin to:
try:
data = json.loads(requesst.raw_post_data)
## work with the data...
except ValueError:
## do something...
No doubt Django provides a way to move this json handling out of your views, and to somewhere more suitable.