1. 程式人生 > >Flask-RESTful擴展

Flask-RESTful擴展

put請求 成員函數 錯誤 stp req request imp 返回 簡單

Flask路由可以指定HTTP請求方法,並在請求函數中根據不同的請求方法,執行不同的邏輯。這樣實現一個Restful的請求已經相當簡單了

Flask還有更簡便的方法,就是其Flask-RESTful擴展。首先,我們來安裝這個擴展:

pip install Flask-RESTful

安裝完後,你就可以在代碼中導入該擴展包

from flask import Flask, request
from flask_restful import Api, Resource
 
app = Flask(__name__)
api = Api(app)
 
USER_LIST = {
    1
: {name:Michael}, 2: {name:Tom}, } class UserList(Resource): def get(self): return USER_LIST def post(self): user_id = int(max(USER_LIST.keys())) + 1 user_id = %i % user_id USER_LIST[user_id] = {name: request.form[name]} return USER_LIST[user_id] api.add_resource(UserList,
/users) if __name__ == __main__: app.run(host=0.0.0.0, debug=True)

這個例子很容易理解,Restful擴展通過”api.add_resource()”方法來添加路由,方法的第一個參數是一個類名,該類繼承”Resource”基類,其成員函數定義了不同的HTTP請求方法的邏輯;第二個參數定義了URL路徑。運行上面的例子並訪問”http://localhost:5000/users”,GET請求時會列出全局變量”USER_LIST”中的內容,POST請求時會在”USER_LIST”中添加一項,並返回剛添加的項。如果在POST請求中找不到”name”字段,則返回”400 Bad Request”錯誤。由於類”UserList”沒有定義”put”和”delete”函數,所以在PUT或DELETE請求時會返回”405 Method Not Allowed”錯誤。

另外,路由支持多路徑,比如:

api.add_resource(UserList, /userlist, /users)

這樣訪問”http://localhost:5000/userlist”和”http://localhost:5000/users”的效果完全一樣。

帶參數的請求

上面的例子請求是針對user列表的,如果我們要對某個具體的user做操作,就需要傳遞具體的”user_id”了。這時候,我們需要路由支持帶參數。Flask-RESTful的實現同Flask一樣,就是在路由中加上參數變量即可。我們看下例子:

class User(Resource):
    def get(self, user_id):
        return USER_LIST[user_id]
 
    def delete(self, user_id):
        del USER_LIST[user_id]
        return ‘‘
 
    def put(self, user_id):
        USER_LIST[user_id] = {name: request.form[name]}
        return USER_LIST[user_id]
 
api.add_resource(User, /users/<user_id>)

在”api.add_resource()”的第二個參數路徑中加上URL參數變量即可,格式Flask路由中完全一樣,也支持轉換器來轉換變量類型。此外,在User類的GET,POST,PUT等成員函數中,記得加上參數”user_id”來獲取傳入的變量值。

參數解析

在POST或PUT請求中,直接訪問form表單並驗證的工作有些麻煩。Flask-RESTful提供了”reqparse”庫來簡化。我們來改進下上例中的PUT函數:

from flask_restful import reqparse
 
parser = reqparse.RequestParser()
parser.add_argument(name, type=str)
 
class User(Resource):
    def put(self, user_id):
        args = parser.parse_args()
        USER_LIST[user_id] = {name: args[name]}
        return USER_LIST[user_id]

可以通過”parser.add_argument()”方法來定義form表單字段,並指定其類型(本例中是字符型str)。然後在PUT函數中,就可以調用”parser.parse_args()”來獲取表單內容,並返回一個字典,該字典就包含了表單的內容。”parser.parse_args()”方法會自動驗證數據類型,並在類型不匹配時,返回400錯誤。你還可以添加”strict”參數,如”parser.parse_args(strict=True)”,此時如果請求中出現未定義的參數,也會返回400錯誤。

示例代碼

from flask import Flask
from flask_restful import Api, Resource, reqparse, abort
 
app = Flask(__name__)
api = Api(app)
 
USER_LIST = {
    1: {name:Michael},
    2: {name:Tom},
}
 
parser = reqparse.RequestParser()
parser.add_argument(name, type=str)
 
def abort_if_not_exist(user_id):
    if user_id not in USER_LIST:
        abort(404, message="User {} doesn‘t exist".format(user_id))
 
class User(Resource):
    def get(self, user_id):
        abort_if_not_exist(user_id)
        return USER_LIST[user_id]
 
    def delete(self, user_id):
        abort_if_not_exist(user_id)
        del USER_LIST[user_id]
        return ‘‘, 204
 
    def put(self, user_id):
        args = parser.parse_args(strict=True)
        USER_LIST[user_id] = {name: args[name]}
        return USER_LIST[user_id], 201
 
class UserList(Resource):
    def get(self):
        return USER_LIST
 
    def post(self):
        args = parser.parse_args(strict=True)
        user_id = int(max(USER_LIST.keys())) + 1
        USER_LIST[user_id] = {name: args[name]}
        return USER_LIST[user_id], 201
 
api.add_resource(UserList, /users)
api.add_resource(User, /users/<int:user_id>)
 
if __name__ == __main__:
    app.run(host=0.0.0.0, debug=True)

Flask-RESTful擴展