POST JSON generated from C# to be received by Python - json

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)

Related

pytest - accessing flask response parameters [duplicate]

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.

How to connect FastAPI to frontend HTML

I am developing this project of a simple meme posting website where I take the UserName, caption, Image URL from the user and want to show all the memes on the home page of the website.
I am new to being a full stack developer, I am using FastAPI as backend and went through its documentation. So far I have been able to get the response from the HTML to the server via a Post request, but now I want to store the data in some database and send that data back to the Home page of the website. I tried finding tutorial videos but wasn't able to get the ones which could help me.
Any kind of help is appreciated.
Below is some code about how I am performing the current requests.
from fastapi import Request, status, BackgroundTasks
from fastapi.responses import JSONResponse
from tutorial import app,templates
import time
from datetime import datetime
from pydantic import BaseModel
from typing import Optional
class Record(BaseModel):
name:str
caption:str
meme_type: Optional[str] = None
img_meme:str
#app.post("/")
async def create_record(record: Record):
background_tasks.add_task(_run_task,record)
return record
def _run_task(name: str,caption: str,meme_type:str,img_meme: str):
time.sleep(3)
with open("memes.txt",mode="a") as file:
now=datetime.now()
content=f""" "Name":{name} \nCaption:{caption} \nURL:{img_meme} : now}\n"""
file.write(content)
FastAPI documentation has all the answers you need.
I want to store the data in some database
SQL Databases - You can use any relational database you want. The documentation has example codes using SQLAlchemy.
Async SQL Databases - You can connect to your relational databases using async/await using a third-party package called databases.
NoSQL Databases - FastAPI can also be integrated with any NoSQL. The documentation has example codes using Couchbase.
send that data back to the Home page of the website
HTMLResponse - If your app is simple and straightforward.
Templates - If you need template rendering. The documentation has example codes for Jinja2.

How can I receive JSON data from a API in same django project without using other module or library?

I have a API defined in my project which returns JSON data in response.
url(r'^api/report/(?P<report_id>\w+)/generate/', staff_member_required(api_views.GenerateReport.as_view()), name="generate_report"),
In another app of same project, I want to receive this data in views.py
How do I make a request to this url using some django functions.
I think there might be some way to make this GET request without using requests or any other 3rd party module.
Any help would be appreciated.

How to get JSON data in an Odoo controller?

I am trying to send some JSON data to an Odoo controller, but when I send the request, I always get 404 as response.
This is the code of my controller:
import openerp.http as http
import logging
_logger = logging.getLogger(__name__)
class Controller(http.Controller):
#http.route('/test/result', type='json', auth='public')
def index(self, **args):
_logger.info('The controller is called.')
return '{"response": "OK"}'
Now, I type the URL (http://localhost:8069/test/result) on the browser to check if it is available, and I get function index at 0x7f04a28>, /test/result: Function declared as capable of handling request of type 'json' but called with a request of type 'http'. This way I know that the controller is listening at that URL and is expecting JSON data.
So I open a Python console and type:
import json
import requests
data = {'test': 'Hello'}
data_json = json.dumps(data)
r = requests.get('http://localhost:8069/test/result', data=data_json)
When I print r in the console, it returns <Response [404]>, and I cannot see any message in the log (I was expecting The controller is called.).
There is a similar question here, but it is not exactly the same case:
OpenERP #http.route('demo_json', type="json") URL not displaying JSON Data
Can anyone help me? What am I doing wrong?
I have just solved the problem.
Firstly, as #techsavvy told, I had to modify the decorator, to write type='http' instead of type='json'.
And after that, the request from the console returned a 404 error because it did not know which database it was sending data to. In localhost:8069 I had more than one database. So I tried to have only one at that port. And that is, now it works great!
To manage that without removing any of the other databases, I have just modified the config file to change the parameter db_filter and put there a regular expression which only included my current database.
I have just gone through your issue and I noticed that you have written JSON route which is call from javascript. if you want to call it from browser url hit then you have to define router with type="http" and auth="public" argument in route:
#http.route('/', type='http', auth="public", website=True)

DRF testing: instead of JSON an OrderedDict is returned

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]}}}