Học Falcon – Suffixed Responders Làm dự án nhận lương – Trung tâm đào tạo Toidayhoc

Học Falcon – Suffixed Responders Làm dự án nhận lương

Python Falcon – Suffixed Responders



Để hiểu khái niệm và nhu cầu về các bộ phản hồi có hậu tố, chúng ta hãy định nghĩa một lớp StudentResource. Nó bao gồm một bộ phản hồi on_get() chuyển đổi danh sách các đối tượng dict thành JSON cho học sinh và trả về dưới dạng phản hồi của nó. Chúng ta cũng hãy thêm bộ phản hồi on_post() đọc dữ liệu từ yêu cầu đến và thêm một đối tượng dict mới vào danh sách.

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 line −

http GET localhost:8000/students
HTTP/1.1 200 OK
Content-Length: 187
Content-Type: application/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: application/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 like 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 list.

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 Application 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: application/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 client 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 list 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: application/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: application/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)

Vừa học vừa làm vừa nhận lương tại trung tâm Toidayhoc

Leave a Reply

Your email address will not be published. Required fields are marked *

Translate »