- Python Falcon 教程
- Python Falcon - 首頁
- Python Falcon - 簡介
- Python Falcon - 環境搭建
- Python Falcon - WSGI vs ASGI
- Python Falcon - Hello World(WSGI)
- Python Falcon - Waitress
- Python Falcon - ASGI
- Python Falcon - Uvicorn
- Python Falcon - API 測試工具
- 請求 & 響應
- Python Falcon - 資源類
- Python Falcon - 應用類
- Python Falcon - 路由
- Falcon - 字尾響應器
- Python Falcon - Inspect 模組
- Python Falcon - Jinja2 模板
- Python Falcon - Cookies
- Python Falcon - 狀態碼
- Python Falcon - 錯誤處理
- Python Falcon - 鉤子
- Python Falcon - 中介軟體
- Python Falcon - CORS
- Python Falcon - Websocket
- Python Falcon - Sqlalchemy 模型
- Python Falcon - 測試
- Python Falcon - 部署
- Python Falcon 有用資源
- Python Falcon - 快速指南
- Python Falcon - 有用資源
- Python Falcon - 討論
Python Falcon - 字尾響應器
為了理解字尾響應器的概念和必要性,讓我們定義一個StudentResource類。它包含一個on_get()響應器,該響應器將學生列表(dict物件)轉換為JSON並作為響應返回。
讓我們再新增一個on_post()響應器,它讀取來自傳入請求的資料,並在列表中新增一個新的dict物件。
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
使用Falcon的App物件的add_route()函式,我們添加了/students路由。
app = falcon.App()
app.add_route("/students", StudentResource())
啟動伺服器後,我們可以從HTTPie命令列測試GET和POST請求。
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.
再次呼叫on_get()確認了新學生資源的新增。
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"
}
]
在此階段,我們希望在StudentResource類中有一個GET響應器方法,該方法從URL中讀取id引數並檢索列表中相應的dict物件。
換句話說,格式為/student/{id}的URL應該與資源類中的GET方法關聯。但顯然,一個類不能有兩個同名的方法。因此,我們定義使用add_route()方法的suffix引數來區分on_get()響應器的兩個定義。
透過指定suffix ='student',將帶有id引數的路由新增到Application物件。
app.add_route("/students/{id:int}", StudentResource(), suffix='student')
現在,我們可以使用此後綴新增另一個on_get()方法的定義,以便此響應器的名稱為on_get_student(),如下所示:
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
新增新路由和on_get_student()響應器後,啟動Waitress伺服器並測試以下URL:
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
}
請注意,當客戶端使用適當的請求頭請求URL路由/students/{id:int}時,on_put()響應器(更新資源)和on_delete()響應器(刪除資源)也將被呼叫。
我們已經使用student作為字尾添加了此路由。因此,on_put_student()方法將路徑引數解析為一個整型變數。獲取給定id的專案的JSON表示形式,並使用PUT請求中提供的資料進行更新。
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
on_delete_student()響應器僅刪除DELETE請求中指定的id對應的專案。返回剩餘資源的列表。
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
我們可以使用HTTPie命令測試API的PUT和DELETE操作:
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
}
]
此API(studentapi.py)的完整程式碼如下:
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)