簡體   English   中英

如何在python中驗證POST請求的json / xml主體

[英]How to validate json/xml body of a POST request in python

我正在嘗試為具有GET,POST,PUT功能的API編寫Web控制器。 1.在處理請求的方法中,尤其是POST和PUT,我想驗證請求正文中是否存在必需的鍵/字段。 2.我還想檢查請求標頭中存在的授權密鑰,並拋出未授權的錯誤等作為響應。

在python中是否有一種優雅的方式來執行此操作, if...else看起來不那么優雅,請編寫多個。

我有以下代碼可以處理請求正文:

from werkzeug.wrappers import BaseResponse as Response
.
.
.
    root = ET.fromstring(data)
            for child in root:
                order_completed_date = child.find('Order_Completed_Date')
                if order_completed_date is None:
                    #return json.loads({"status":"400", "message":"Order_Completed_Date is missing"})
                    return Response('Bad Request, Order_Complete_At missing', status=400)
                else:
                    order_completed_date = order_completed_date.text
                order_id = child.find('Order_Number')
                if order_id is None:
                    return Response('Bad Request, Order_Number missing', status=400) 
                else:
                    order_id = order_id.text
                product_id =child.find('SKU')
                if product_id is None:
                    return Response("Bad request, SKU is missing", status=400)
                else:
                    product_id = product_id.text
                .
                .
                .

依此類推,我正在為每個領域寫

我們有一些代碼,因此我們可以看看如何重構它。

基本上,您在此代碼上會有一些細微的變化:

order_completed_date = child.find('Order_Completed_Date')
if order_completed_date is None:
    #return json.loads({"status":"400", "message":"Order_Completed_Date is missing"})
    return Response('Bad Request, Order_Complete_At missing', status=400)
else:
    order_completed_date = order_completed_date.text

那么,我們如何將其轉換為功能呢?

首先,只需將其轉換為函數,然后看看有什么問題:

def find_key():
    order_completed_date = child.find('Order_Completed_Date')
    if order_completed_date is None:
        return Response('Bad Request, Order_Complete_At missing', status=400)
    else:
        order_completed_date = order_completed_date.text

因此,第一個問題是child價值。 這不是一個常數。 每次循環都不同,因此我們需要將其作為參數。*

*好吧,我們可以在本地定義find_key ,並將child作為閉包變量,但現在讓我們保持簡單。

同樣,雖然'Order_Completed_Date'在整個循環中每次都不相同,但對於每個不同的鍵來說都是不同的,因此我們也需要考慮這一點。*

*還有一個'Order_Complete_At'字符串,但這似乎是'Order_Completed_Date'的錯字。 如果不是,則需要添加另一個參數,例如key_error_name

變量名order_completed_date 沒有改變,因為如果我們把它作為“為每個鍵的值”的通用名稱局部變量名稱不意味着什么Python的,但它顯然誤導人的讀者。

最后,最大的問題是我們的回報 我們可以返回兩種不同的東西-節點的文本或錯誤響應。 我們可以return前者,而對后者raise例外。 或返回一對東西,一個文本或錯誤和一個標志,告訴我們哪個是哪個。 或者我們可以返回一個文本和一個錯誤,其中一個是None 異常似乎是最復雜的,但是它會自動為我們提供“非本地返回”,這是一種無需使用一個函數就檢查每個返回值的其他函數的方法。

所以:

def find_key(child, key):
    value = child.find(key)
    if value is None:
        raise KeyError(key)
    else:
        return value.text

現在:

try:
    for child in root:
        order_completed_date = find_key(child, 'Order_Completed_Date')
        order_id = find_key(child, 'Order_Number')
        product_id = find_key(child, 'SKU')
        # ...
except KeyError as e:
    return Response("Bad request, {} is missing".format(e.args[0]), status=400)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM