- Python Falcon - Discussion
- Python Falcon - Useful Resources
- Python Falcon - Quick Guide
- Python Falcon - Deployment
- Python Falcon - Testing
- Python Falcon - Sqlalchemy Models
- Python Falcon - Websocket
- Python Falcon - CORS
- Python Falcon - Middleware
- Python Falcon - Hooks
- Python Falcon - Error Handling
- Python Falcon - Status Codes
- Python Falcon - Cookies
- Python Falcon - Jinja2 Template
- Python Falcon - Inspect Module
- Falcon - Suffixed Responders
- Python Falcon - Routing
- Python Falcon - App Class
- Python Falcon - Resource Class
- Request & Response
- Python Falcon - API Testing Tools
- Python Falcon - Uvicorn
- Python Falcon - ASGI
- Python Falcon - Waitress
- Python Falcon - Hello World(WSGI)
- Python Falcon - WSGI vs ASGI
- Python Falcon - Environment Setup
- Python Falcon - Introduction
- Python Falcon - Home
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Python Falcon - Suffixed Responders
To understand the concept and the need of suffixed responders, let us define a StudentResource class. It consists of an on_get() responder that converts the students a pst of dict objects to JSON and returns as its response.
Let us also add on_post() responder that reads the data from the incoming request and adds a new dict object in the pst.
import falcon import json from waitress import serve students = [ {"id": 1, "name": "Ravi", "percent": 75.50}, {"id": 2, "name": "Mona", "percent": 80.00}, {"id": 3, "name": "Mathews", "percent": 65.25}, ] class StudentResource: def on_get(self, req, resp): resp.text = json.dumps(students) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON def on_post(self, req, resp): student = json.load(req.bounded_stream) students.append(student) resp.text = "Student added successfully." resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_TEXT
Using add_route() function of the Falcon s App object, we add /students route.
app = falcon.App() app.add_route("/students", StudentResource())
After starting the server, we can test the GET and POST requests from HTTPie command pne −
http GET localhost:8000/students HTTP/1.1 200 OK Content-Length: 187 Content-Type: apppcation/json Date: Mon, 18 Apr 2022 06:21:02 GMT Server: waitress [ { "id": 1, "name": "Ravi", "percent": 75.5 }, { "id": 2, "name": "Mona", "percent": 80.0 }, { "id": 3, "name": "Mathews", "percent": 65.25 } ] http POST localhost:8000/students id=4 name="Prachi" percent=59.90 HTTP/1.1 200 OK Content-Length: 27 Content-Type: text/plain; charset=utf-8 Date: Mon, 18 Apr 2022 06:20:51 GMT Server: waitress Student added successfully.
Invoking on_get() again confirms the addition of new students resource.
http GET localhost:8000/students HTTP/1.1 200 OK Content-Length: 187 Content-Type: apppcation/json Date: Mon, 18 Apr 2022 06:21:02 GMT Server: waitress [ { "id": 1, "name": "Ravi", "percent": 75.5 }, { "id": 2, "name": "Mona", "percent": 80.0 }, { "id": 3, "name": "Mathews", "percent": 65.25 }, { "id": "4", "name": "Prachi", "percent": "59.90" } ]
At this stage, we would pke to have a GET responder method in StudentResource class that reads the id parameter from the URL and retrieves a corresponding dict object of from the pst.
In other words, the URL of the format /student/{id} should be associated to the GET method in the resource class. But obviously, a class cannot have two methods of same name. Hence, we define to use suffix parameter for the add_route() method to distinguish between the two definitions of on_get() responders.
A route with id parameter is added to the Apppcation object by specifying suffix = student .
app.add_route("/students/{id:int}", StudentResource(), suffix= student )
We can now add another definition of on_get() method with this suffix, so that the name of this responder is on_get_student(), as follows −
def on_get_student(self, req, resp, id): resp.text = json.dumps(students[id-1]) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON
Start the Waitress server after adding the new route and on_get_student() responder and test this URL as follows −
http GET localhost:8000/students/2 HTTP/1.1 200 OK Content-Length: 42 Content-Type: apppcation/json Date: Mon, 18 Apr 2022 06:21:05 GMTy Server: waitress { "id": 2, "name": "Mona", "percent": 80.0 }
Note that the on_put() responder (to update a resource) and on_delete() responder (to delete a resource) will also get invoked when the URL route /students/{id:int} is requested by the cpent with appropriate request header.
We have already added this route with student as the suffix. Hence, on_put_student() method parses the path parameter in an integer variable. The JSON representation of the item with given id is fetched and updated with the data provided in the PUT request.
def on_put_student(self, req, resp, id): student=students[id-1] data = json.load(req.bounded_stream) student.update(data) resp.text = json.dumps(student) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON
The on_delete_student() responder simply deletes the item with the id specified in the DELETE request. The pst of remaining resources is returned.
def on_delete_student(self, req, resp, id): students.pop(id-1) resp.text = json.dumps(students) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON
We can test the PUT and DELETE operations of the API with HTTPie commands −
http PUT localhost:8000/students/2 id=3 name="Mathews" percent=55 HTTP/1.1 200 OK Content-Length: 46 Content-Type: apppcation/json Date: Sat, 18 Apr 2022 10:13:00 GMT Server: waitress { "id": "3", "name": "Mathews", "percent": "55" } http DELETE localhost:8000/students/2 HTTP/1.1 200 OK Content-Length: 92 Content-Type: apppcation/json Date: Sat, 18 Apr 2022 10:18:00 GMT Server: waitress [ { "id": 1, "name": "Ravi", "percent": 75.5 }, { "id": 3, "name": "Mathews", "percent": 65.25 } ]
The complete code of this API (studentapi.py) is as under −
import falcon import json from waitress import serve students = [ {"id": 1, "name": "Ravi", "percent": 75.50}, {"id": 2, "name": "Mona", "percent": 80.00}, {"id": 3, "name": "Mathews", "percent": 65.25}, ] class StudentResource: def on_get(self, req, resp): resp.text = json.dumps(students) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON def on_post(self, req, resp): student = json.load(req.bounded_stream) students.append(student) resp.text = "Student added successfully." resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_TEXT def on_get_student(self, req, resp, id): resp.text = json.dumps(students[id-1]) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON def on_put_student(self, req, resp, id): student=students[id-1] data = json.load(req.bounded_stream) student.update(data) resp.text = json.dumps(student) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON def on_delete_student(self, req, resp, id): students.pop(id-1) print (students) resp.text = json.dumps(students) resp.status = falcon.HTTP_OK resp.content_type = falcon.MEDIA_JSON app = falcon.App() app.add_route("/students", StudentResource()) app.add_route("/students/{id:int}", StudentResource(), suffix= student ) if __name__ == __main__ : serve(app, host= 0.0.0.0 , port=8000)Advertisements