日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

使用python的Flask实现一个RESTful API服务器端

發(fā)布時(shí)間:2025/5/22 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用python的Flask实现一个RESTful API服务器端 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用python的Flask實(shí)現(xiàn)一個(gè)RESTful API服務(wù)器端[翻譯]

最近這些年,REST已經(jīng)成為web services和APIs的標(biāo)準(zhǔn)架構(gòu),很多APP的架構(gòu)基本上是使用RESTful的形式了。

本文將會(huì)使用python的Flask框架輕松實(shí)現(xiàn)一個(gè)RESTful的服務(wù)。

REST的六個(gè)特性:

  • Client-Server:服務(wù)器端與客戶端分離。
  • Stateless(無(wú)狀態(tài)):每次客戶端請(qǐng)求必需包含完整的信息,換句話說(shuō),每一次請(qǐng)求都是獨(dú)立的。
  • Cacheable(可緩存):服務(wù)器端必需指定哪些請(qǐng)求是可以緩存的。
  • Layered System(分層結(jié)構(gòu)):服務(wù)器端與客戶端通訊必需標(biāo)準(zhǔn)化,服務(wù)器的變更并不會(huì)影響客戶端。
  • Uniform Interface(統(tǒng)一接口):客戶端與服務(wù)器端的通訊方法必需是統(tǒng)一的。
  • Code on demand(按需執(zhí)行代碼?):服務(wù)器端可以在上下文中執(zhí)行代碼或者腳本?

Servers can provide executable code or scripts for clients to execute in their context. This constraint is the only one that is optional.(沒(méi)看明白)

RESTful web service的樣子

REST架構(gòu)就是為了HTTP協(xié)議設(shè)計(jì)的。RESTful web services的核心概念是管理資源。資源是由URIs來(lái)表示,客戶端使用HTTP當(dāng)中的'POST, OPTIONS, GET, PUT, DELETE'等方法發(fā)送請(qǐng)求到服務(wù)器,改變相應(yīng)的資源狀態(tài)。

HTTP請(qǐng)求方法通常也十分合適去描述操作資源的動(dòng)作:

HTTP方法動(dòng)作例子
GET獲取資源信息

http://example.com/api/orders

(檢索訂單清單)

GET獲取資源信息

http://example.com/api/orders/123

(檢索訂單 #123)

POST創(chuàng)建一個(gè)次的資源

http://example.com/api/orders

(使用帶數(shù)據(jù)的請(qǐng)求,創(chuàng)建一個(gè)新的訂單)

PUT更新一個(gè)資源

http://example.com/api/orders/123

(使用帶數(shù)據(jù)的請(qǐng)求,更新#123訂單)

DELETE刪除一個(gè)資源

http://example.com/api/orders/123

刪除訂單#123

REST請(qǐng)求并不需要特定的數(shù)據(jù)格式,通常使用JSON作為請(qǐng)求體,或者URL的查詢參數(shù)的一部份。

設(shè)計(jì)一個(gè)簡(jiǎn)單的web service

下面的任務(wù)將會(huì)練習(xí)設(shè)計(jì)以REST準(zhǔn)則為指引,通過(guò)不同的請(qǐng)求方法操作資源,標(biāo)識(shí)資源的例子。

我們將寫(xiě)一個(gè)To Do List 應(yīng)用,并且設(shè)計(jì)一個(gè)web service。第一步,規(guī)劃一個(gè)根URL,例如:

http://[hostname]/todo/api/v1.0/

上面的URL包括了應(yīng)用程序的名稱、API版本,這是十分有用的,既提供了命名空間的劃分,同時(shí)又與其它系統(tǒng)區(qū)分開(kāi)來(lái)。版本號(hào)在升級(jí)新特性時(shí)十分有用,當(dāng)一個(gè)新功能特性增加在新版本下面時(shí),并不影響舊版本。

第二步,規(guī)劃資源的URL,這個(gè)例子十分簡(jiǎn)單,只有任務(wù)清單。

規(guī)劃如下:

HTTP方法URI動(dòng)作
GEThttp://[hostname]/todo/api/v1.0/tasks檢索任務(wù)清單
GEThttp://[hostname]/todo/api/v1.0/tasks/[task_id]檢索一個(gè)任務(wù)
POSThttp://[hostname]/todo/api/v1.0/tasks創(chuàng)建一個(gè)新任務(wù)
PUThttp://[hostname]/todo/api/v1.0/tasks/[task_id]更新一個(gè)已存在的任務(wù)
DELETEhttp://[hostname]/todo/api/v1.0/tasks/[task_id]刪除一個(gè)任務(wù)

我們定義任務(wù)清單有以下字段:

  • id:唯一標(biāo)識(shí)。整型。
  • title:簡(jiǎn)短的任務(wù)描述。字符串型。
  • description:完整的任務(wù)描述。文本型。
  • done:任務(wù)完成狀態(tài)。布爾值型。

以上基本完成了設(shè)計(jì)部份,接下來(lái)我們將會(huì)實(shí)現(xiàn)它!

?簡(jiǎn)單了解Flask框架

Flask好簡(jiǎn)單,但是又很強(qiáng)大的Python web 框架。這里有一系列教程Flask Mega-Tutorial series。(注:Django\Tornado\web.py感覺(jué)好多框:()

在我們深入實(shí)現(xiàn)web service之前,讓我們來(lái)簡(jiǎn)單地看一個(gè)Flask web 應(yīng)用的結(jié)構(gòu)示例。

這里都是在Unix-like(Linux,Mac OS X)操作系統(tǒng)下面的演示,但是其它系統(tǒng)也可以跑,例如windows下的Cygwin。可能命令有些不同吧。(注:忽略Windows吧。)

先使用virtualenv安裝一個(gè)Flask的虛擬環(huán)境。如果沒(méi)有安裝virtualenv,開(kāi)發(fā)python必備,最好去下載安裝。https://pypi.python.org/pypi/virtualenv

$ mkdir todo-api $ cd todo-api $ virtualenv flask New python executable in flask/bin/python Installing setuptools............................done. Installing pip...................done. $ flask/bin/pip install flask

?這樣做好了一個(gè)Flask的開(kāi)發(fā)環(huán)境,開(kāi)始創(chuàng)建一個(gè)簡(jiǎn)單的web應(yīng)用,在當(dāng)前目錄里面創(chuàng)建一個(gè)app.py文件:

#!flask/bin/python from flask import Flaskapp = Flask(__name__)@app.route('/') def index():return "Hello, World!"if __name__ == '__main__':app.run(debug=True)

去執(zhí)行app.py:

$ chmod a+x app.py $ ./app.py* Running on http://127.0.0.1:5000/* Restarting with reloader

現(xiàn)在可以打開(kāi)瀏覽器,輸入http://localhost:5000去看看這個(gè)Hello,World!

好吧,十分簡(jiǎn)單吧。我們開(kāi)始轉(zhuǎn)換到RESTful service!

使用Python 和 Flask實(shí)現(xiàn)RESTful services

使用Flask建立web services超級(jí)簡(jiǎn)單。

當(dāng)然,也有很多Flask extensions可以幫助建立RESTful services,但是這個(gè)例實(shí)在太簡(jiǎn)單了,不需要使用任何擴(kuò)展。

這個(gè)web service提供增加,刪除、修改任務(wù)清單,所以我們需要將任務(wù)清單存儲(chǔ)起來(lái)。最簡(jiǎn)單的做法就是使用小型的數(shù)據(jù)庫(kù),但是數(shù)據(jù)庫(kù)并不是本文涉及太多的。可以參考原文作者的完整教程。Flask Mega-Tutorial series

在這里例子我們將任務(wù)清單存儲(chǔ)在內(nèi)存中,這樣只能運(yùn)行在單進(jìn)程和單線程中,這樣是不適合作為生產(chǎn)服務(wù)器的,若非就必需使用數(shù)據(jù)庫(kù)了。

現(xiàn)在我們準(zhǔn)備實(shí)現(xiàn)第一個(gè)web service的入口點(diǎn):

#!flask/bin/python from flask import Flask, jsonifyapp = Flask(__name__)tasks = [{'id': 1,'title': u'Buy groceries','description': u'Milk, Cheese, Pizza, Fruit, Tylenol', 'done': False},{'id': 2,'title': u'Learn Python','description': u'Need to find a good Python tutorial on the web', 'done': False} ]@app.route('/todo/api/v1.0/tasks', methods=['GET']) def get_tasks():return jsonify({'tasks': tasks})if __name__ == '__main__':app.run(debug=True)

正如您所見(jiàn),并沒(méi)有改變太多代碼。我們將任務(wù)清單存儲(chǔ)在list內(nèi)(內(nèi)存),list存放兩個(gè)非常簡(jiǎn)單的數(shù)組字典。每個(gè)實(shí)體就是我們上面定義的字段。

而 index 入口點(diǎn)有一個(gè)get_tasks函數(shù)與/todo/api/v1.0/tasks?URI關(guān)聯(lián),只接受http的GET方法。

這個(gè)響應(yīng)并非一般文本,是JSON格式的數(shù)據(jù),是經(jīng)過(guò)Flask框架的?jsonify模塊格式化過(guò)的數(shù)據(jù)。

使用瀏覽器去測(cè)試web service并不是一個(gè)好的辦法,因?yàn)橐獎(jiǎng)?chuàng)建不同類弄的HTTP請(qǐng)求,事實(shí)上,我們將使用curl命令行。如果沒(méi)有安裝curl,快點(diǎn)去安裝一個(gè)。

像剛才一樣運(yùn)行app.py。

打開(kāi)一個(gè)終端運(yùn)行以下命令:

$ curl -i http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 200 OK Content-Type: application/json Content-Length: 294 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 04:53:53 GMT{"tasks": [{"description": "Milk, Cheese, Pizza, Fruit, Tylenol","done": false,"id": 1,"title": "Buy groceries"},{"description": "Need to find a good Python tutorial on the web","done": false,"id": 2,"title": "Learn Python"}] }

這樣就調(diào)用了一個(gè)RESTful service方法!

現(xiàn)在,我們寫(xiě)第二個(gè)版本的GET方法獲取特定的任務(wù)。獲取單個(gè)任務(wù):

from flask import abort@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['GET']) def get_task(task_id):task = filter(lambda t: t['id'] == task_id, tasks)if len(task) == 0:abort(404)return jsonify({'task': task[0]})

?第二個(gè)函數(shù)稍稍復(fù)雜了一些。任務(wù)的id包含在URL內(nèi),Flask將task_id參數(shù)傳入了函數(shù)內(nèi)。

通過(guò)參數(shù),檢索tasks數(shù)組。如果參數(shù)傳過(guò)來(lái)的id不存在于數(shù)組內(nèi),我們需要返回錯(cuò)誤代碼404,按照HTTP的規(guī)定,404意味著是"Resource Not Found",資源未找到。

如果找到任務(wù)在內(nèi)存數(shù)組內(nèi),我們通過(guò)jsonify模塊將字典打包成JSON格式,并發(fā)送響應(yīng)到客戶端上。就像處理一個(gè)實(shí)體字典一樣。

試試使用curl調(diào)用:

$ curl -i http://localhost:5000/todo/api/v1.0/tasks/2 HTTP/1.0 200 OK Content-Type: application/json Content-Length: 151 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 05:21:50 GMT{"task": {"description": "Need to find a good Python tutorial on the web","done": false,"id": 2,"title": "Learn Python"} } $ curl -i http://localhost:5000/todo/api/v1.0/tasks/3 HTTP/1.0 404 NOT FOUND Content-Type: text/html Content-Length: 238 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 05:21:52 GMT<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server.</p><p>If you entered the URL manually please check your spelling and try again.</p>

當(dāng)我們請(qǐng)求#2 id的資源時(shí),可以獲取,但是當(dāng)我們請(qǐng)求#3的資源時(shí)返回了404錯(cuò)誤。并且返回了一段奇怪的HTML錯(cuò)誤,而不是我們期望的JSON,這是因?yàn)镕lask產(chǎn)生了默認(rèn)的404響應(yīng)。客戶端需要收到的都是JSON的響應(yīng),因此我們需要改進(jìn)404錯(cuò)誤處理:

from flask import make_response@app.errorhandler(404) def not_found(error):return make_response(jsonify({'error': 'Not found'}), 404)

這樣我們就得到了友好的API錯(cuò)誤響應(yīng):

$ curl -i http://localhost:5000/todo/api/v1.0/tasks/3 HTTP/1.0 404 NOT FOUND Content-Type: application/json Content-Length: 26 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 05:36:54 GMT{"error": "Not found" }

接下來(lái)我們實(shí)現(xiàn)?POST?方法,插入一個(gè)新的任務(wù)到數(shù)組中:

from flask import request@app.route('/todo/api/v1.0/tasks', methods=['POST']) def create_task():if not request.json or not 'title' in request.json:abort(400)task = {'id': tasks[-1]['id'] + 1,'title': request.json['title'],'description': request.json.get('description', ""),'done': False}tasks.append(task)return jsonify({'task': task}), 201

?request.json里面包含請(qǐng)求數(shù)據(jù),如果不是JSON或者里面沒(méi)有包括title字段,將會(huì)返回400的錯(cuò)誤代碼。

當(dāng)創(chuàng)建一個(gè)新的任務(wù)字典,使用最后一個(gè)任務(wù)id數(shù)值加1作為新的任務(wù)id(最簡(jiǎn)單的方法產(chǎn)生一個(gè)唯一字段)。這里允許不帶description字段,默認(rèn)將done字段值為False。

將新任務(wù)附加到tasks數(shù)組里面,并且返回客戶端201狀態(tài)碼和剛剛添加的任務(wù)內(nèi)容。HTTP定義了201狀態(tài)碼為“Created”。

測(cè)試上面的新功能:

$ curl -i -H "Content-Type: application/json" -X POST -d '{"title":"Read a book"}' http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 201 Created Content-Type: application/json Content-Length: 104 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 05:56:21 GMT{"task": {"description": "","done": false,"id": 3,"title": "Read a book"} }

注意:如果使用原生版本的curl命令行提示符,上面的命令會(huì)正確執(zhí)行。如果是在Windows下使用Cygwin bash版本的curl,需要將body部份添加雙引號(hào):

curl -i -H "Content-Type: application/json" -X POST -d "{"""title""":"""Read a book"""}" http://localhost:5000/todo/api/v1.0/tasks

基本上在Windows中需要使用雙引號(hào)包括body部份在內(nèi),而且需要三個(gè)雙引號(hào)轉(zhuǎn)義序列。

完成上面的事情,就可以看到更新之后的list數(shù)組內(nèi)容:

$ curl -i http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 200 OK Content-Type: application/json Content-Length: 423 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 05:57:44 GMT{"tasks": [{"description": "Milk, Cheese, Pizza, Fruit, Tylenol","done": false,"id": 1,"title": "Buy groceries"},{"description": "Need to find a good Python tutorial on the web","done": false,"id": 2,"title": "Learn Python"},{"description": "","done": false,"id": 3,"title": "Read a book"}] }

剩余的兩個(gè)函數(shù)如下:

@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['PUT']) def update_task(task_id):task = filter(lambda t: t['id'] == task_id, tasks)if len(task) == 0:abort(404)if not request.json:abort(400)if 'title' in request.json and type(request.json['title']) != unicode:abort(400)if 'description' in request.json and type(request.json['description']) is not unicode:abort(400)if 'done' in request.json and type(request.json['done']) is not bool:abort(400)task[0]['title'] = request.json.get('title', task[0]['title'])task[0]['description'] = request.json.get('description', task[0]['description'])task[0]['done'] = request.json.get('done', task[0]['done'])return jsonify({'task': task[0]})@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id):task = filter(lambda t: t['id'] == task_id, tasks)if len(task) == 0:abort(404)tasks.remove(task[0])return jsonify({'result': True})

delete_task函數(shù)沒(méi)什么太特別的。update_task函數(shù)需要檢查所輸入的參數(shù),防止產(chǎn)生錯(cuò)誤的bug。確保是預(yù)期的JSON格式寫(xiě)入數(shù)據(jù)庫(kù)里面。

測(cè)試將任務(wù)#2的done字段變更為done狀態(tài):

$ curl -i -H "Content-Type: application/json" -X PUT -d '{"done":true}' http://localhost:5000/todo/api/v1.0/tasks/2 HTTP/1.0 200 OK Content-Type: application/json Content-Length: 170 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 07:10:16 GMT{"task": [{"description": "Need to find a good Python tutorial on the web","done": true,"id": 2,"title": "Learn Python"}] }

改進(jìn)Web Service接口

當(dāng)前我們還有一個(gè)問(wèn)題,客戶端有可能需要從返回的JSON中重新構(gòu)造URI,如果將來(lái)加入新的特性時(shí),可能需要修改客戶端。(例如新增版本。)

我們可以返回整個(gè)URI的路徑給客戶端,而不是任務(wù)的id。為了這個(gè)功能,創(chuàng)建一個(gè)小函數(shù)生成一個(gè)“public”版本的任務(wù)URI返回:

from flask import url_fordef make_public_task(task):new_task = {}for field in task:if field == 'id':new_task['uri'] = url_for('get_task', task_id=task['id'], _external=True)else:new_task[field] = task[field]return new_task

通過(guò)Flask的url_for模塊,獲取任務(wù)時(shí),將任務(wù)中的id字段替換成uri字段,并且把值改為uri值。

當(dāng)我們返回包含任務(wù)的list時(shí),通過(guò)這個(gè)函數(shù)處理后,返回完整的uri給客戶端:

@app.route('/todo/api/v1.0/tasks', methods=['GET']) def get_tasks():return jsonify({'tasks': map(make_public_task, tasks)})

現(xiàn)在看到的檢索結(jié)果:

$ curl -i http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 200 OK Content-Type: application/json Content-Length: 406 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 18:16:28 GMT{"tasks": [{"title": "Buy groceries","done": false,"description": "Milk, Cheese, Pizza, Fruit, Tylenol","uri": "http://localhost:5000/todo/api/v1.0/tasks/1"},{"title": "Learn Python","done": false,"description": "Need to find a good Python tutorial on the web","uri": "http://localhost:5000/todo/api/v1.0/tasks/2"}] }

這種辦法避免了與其它功能的兼容,拿到的是完整uri而不是一個(gè)id。

RESTful web service的安全認(rèn)證

我們已經(jīng)完成了整個(gè)功能,但是我們還有一個(gè)問(wèn)題。web service任何人都可以訪問(wèn)的,這不是一個(gè)好主意。

當(dāng)前service是所有客戶端都可以連接的,如果有別人知道了這個(gè)API就可以寫(xiě)個(gè)客戶端隨意修改數(shù)據(jù)了。 大多數(shù)教程沒(méi)有與安全相關(guān)的內(nèi)容,這是個(gè)十分嚴(yán)重的問(wèn)題。

最簡(jiǎn)單的辦法是在web service中,只允許用戶名和密碼驗(yàn)證通過(guò)的客戶端連接。在一個(gè)常規(guī)的web應(yīng)用中,應(yīng)該有登錄表單提交去認(rèn)證,同時(shí)服務(wù)器會(huì)創(chuàng)建一個(gè)會(huì)話過(guò)程去進(jìn)行通訊。這個(gè)會(huì)話過(guò)程id會(huì)被存儲(chǔ)在客戶端的cookie里面。不過(guò)這樣就違返了我們REST中無(wú)狀態(tài)的規(guī)則,因此,我們需求客戶端每次都將他們的認(rèn)證信息發(fā)送到服務(wù)器。

?為此我們有兩種方法表單認(rèn)證方法去做,分別是 Basic 和 Digest。

這里有有個(gè)小Flask extension可以輕松做到。首先需要安裝?Flask-HTTPAuth?:

$ flask/bin/pip install flask-httpauth

假設(shè)web service只有用戶?ok?和密碼為?python?的用戶接入。下面就設(shè)置了一個(gè)Basic HTTP認(rèn)證:

from flask.ext.httpauth import HTTPBasicAuth auth = HTTPBasicAuth()@auth.get_password def get_password(username):if username == 'ok':return 'python'return None@auth.error_handler def unauthorized():return make_response(jsonify({'error': 'Unauthorized access'}), 401)

get_password函數(shù)是一個(gè)回調(diào)函數(shù),獲取一個(gè)已知用戶的密碼。在復(fù)雜的系統(tǒng)中,函數(shù)是需要到數(shù)據(jù)庫(kù)中檢查的,但是這里只是一個(gè)小示例。

當(dāng)發(fā)生認(rèn)證錯(cuò)誤之后,error_handler回調(diào)函數(shù)會(huì)發(fā)送錯(cuò)誤的代碼給客戶端。這里我們自定義一個(gè)錯(cuò)誤代碼401,返回JSON數(shù)據(jù),而不是HTML。

將@auth.login_required裝飾器添加到需要驗(yàn)證的函數(shù)上面:

@app.route('/todo/api/v1.0/tasks', methods=['GET']) @auth.login_required def get_tasks():return jsonify({'tasks': tasks})

現(xiàn)在,試試使用curl調(diào)用這個(gè)函數(shù):

$ curl -i http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 401 UNAUTHORIZED Content-Type: application/json Content-Length: 36 WWW-Authenticate: Basic realm="Authentication Required" Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 06:41:14 GMT{"error": "Unauthorized access" }

這里表示了沒(méi)通過(guò)驗(yàn)證,下面是帶用戶名與密碼的驗(yàn)證:

$ curl -u ok:python -i http://localhost:5000/todo/api/v1.0/tasks HTTP/1.0 200 OK Content-Type: application/json Content-Length: 316 Server: Werkzeug/0.8.3 Python/2.7.3 Date: Mon, 20 May 2013 06:46:45 GMT{"tasks": [{"title": "Buy groceries","done": false,"description": "Milk, Cheese, Pizza, Fruit, Tylenol","uri": "http://localhost:5000/todo/api/v1.0/tasks/1"},{"title": "Learn Python","done": false,"description": "Need to find a good Python tutorial on the web","uri": "http://localhost:5000/todo/api/v1.0/tasks/2"}] }

這個(gè)認(rèn)證extension十分靈活,可以隨指定需要驗(yàn)證的APIs。

為了確保登錄信息的安全,最好的辦法還是使用https加密的通訊方式,客戶端與服務(wù)器端傳輸認(rèn)證信息都是加密過(guò)的,防止第三方的人去看到。

當(dāng)使用瀏覽器去訪問(wèn)這個(gè)接口,會(huì)彈出一個(gè)丑丑的登錄對(duì)話框,如果密碼錯(cuò)誤就回返回401的錯(cuò)誤代碼。為了防止瀏覽器彈出驗(yàn)證對(duì)話框,客戶端應(yīng)該處理好這個(gè)登錄請(qǐng)求。

有一個(gè)小技巧可以避免這個(gè)問(wèn)題,就是修改返回的錯(cuò)誤代碼401。例如修改成403(”Forbidden“)就不會(huì)彈出驗(yàn)證對(duì)話框了。

@auth.error_handler def unauthorized():return make_response(jsonify({'error': 'Unauthorized access'}), 403)

當(dāng)然,同時(shí)也需要客戶端知道這個(gè)403錯(cuò)誤的意義。

最后

還有很多辦法去改進(jìn)這個(gè)web service。

事實(shí)上,一個(gè)真正的web service應(yīng)該使用真正的數(shù)據(jù)庫(kù)。使用內(nèi)存數(shù)據(jù)結(jié)構(gòu)有非常多的限制,不要用在實(shí)際應(yīng)用上面。

另外一方面,處理多用戶。如果系統(tǒng)支持多用戶認(rèn)證,則任務(wù)清單也是對(duì)應(yīng)多用戶的。同時(shí)我們需要有第二種資源,用戶資源。當(dāng)用戶注冊(cè)時(shí)使用POST請(qǐng)求。使用GET返回用戶信息到客戶端。使用PUT請(qǐng)求更新用戶資料,或者郵件地址。使用DELETE刪除用戶賬號(hào)等。

通過(guò)GET請(qǐng)求檢索任務(wù)清單時(shí),有很多辦法可以進(jìn)擴(kuò)展。第一,可以添加分頁(yè)參數(shù),使客戶端只請(qǐng)求一部份數(shù)據(jù)。第二,可以添加篩選關(guān)鍵字等。所有這些元素可以添加到URL上面的參數(shù)。

原文來(lái)自:http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask

?

轉(zhuǎn)載于:https://www.cnblogs.com/sea520/p/9993254.html

總結(jié)

以上是生活随笔為你收集整理的使用python的Flask实现一个RESTful API服务器端的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。