Flask-RESTful擴展
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擴展