Python Falcon - 鉤子



鉤子是在響應客戶端請求時,當資源類中特定響應器方法被呼叫時,自動執行的使用者定義函式。Falcon 支援 **before** 和 **after** 鉤子。

用作鉤子的函式,除了任何可能需要的可選引數外,還以請求、響應和資源類作為引數進行定義。

def hookfunction(req, resp, resource):
   . . . . .
   . . . . .

透過應用以下裝飾器之一,將此類函式附加到單個響應器或整個資源類:-

  • @falcon.before(hookfunction)

  • @falcon.after(hookfunction)

將 before 鉤子應用於 **on_post()** 響應器 -

@falcon.before(hookfunction)
def on_post(self, req, resp):
   . . .
   . . .

應用 after 鉤子 -

@falcon.after(hookfunction)
def on_get(self, req, resp):
   . . .
   . . .

要裝飾整個資源類,請在類宣告的上方使用裝飾器 -

@falcon.after(hookfunction)
class SomeResource:
 def on_get(self, req, resp):
   . . .
   . . .
   def on_post(self, req, resp):
   . . .
   . . .

在以下示例中,我們有 **StudentResource** 類,其中定義了 **on_get()** 和 **on_post()** 響應器。當 POST 請求傳送一些資料時,會呼叫 **on_post()** 響應器,並使用它建立一個新的 **dict** 物件,並將其新增到 **Students** 列表中。

在處理之前需要驗證接收到的資料。為此,定義了以下函式。它檢查 percent 引數的值是否在 0 到 100 之間。只有當資料透過此條件時,才會將其傳遞給響應器。

def checkinput(req, resp, resource,params):
   student = json.load(req.bounded_stream)
   if "name" not in student:
      raise falcon.HTTPBadRequest(
         title="Bad request", description="Bad input, name must be provided."
      )

   per=int(student['percent'])
   if per<0 or per>100:
      raise falcon.HTTPBadRequest(
         title="Bad request", description="Bad input, invalid percentage"
      )
      req.context.data = student

此函式作為鉤子應用於 **StudentResource** 類的 **on_post()** 響應器。

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
   @falcon.before(checkinput)
   def on_post(self, req, resp):
      student = json.load(req.context.data)
      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
app = falcon.App()
app.add_route("/students", StudentResource())
if __name__ == '__main__':
   serve(app, host='0.0.0.0', port=8000)

讓我們執行 **Waitress** 伺服器並啟動 POST 請求。

http POST localhost:8000/students id=4 percent=50
HTTP/1.1 400 Bad Request
Content-Length: 76
Content-Type: application/json
Date: Tue, 26 Apr 2022 14:49:07 GMT
Server: waitress
Vary: Accept {
   "description": "Bad input, name must be provided.",
   "title": "Bad request"
}

由於資料不包含 name 引數的值,因此引發了異常。

在另一個 POST 請求中,如下所示,percent 引數的值未能滿足所需條件,因此引發了異常。

http POST localhost:8000/students id=4 name="aaa" percent=500
HTTP/1.1 400 Bad Request
Content-Length: 72
Content-Type: application/json
Date: Tue, 26 Apr 2022 15:01:20 GMT
Server: waitress
Vary: Accept {
   "description": "Bad input, invalid percentage",
   "title": "Bad request"
}
廣告

© . All rights reserved.