首頁>技術>

天下武功,唯快不破。在軟體開發中更是如此,“快”能從多方面提升使用者體驗。談到Python,它似乎天生就和速度無關,你可能很熟悉Django、Flask這些框架,雖然開發效率的確不錯,但是速度就一言難盡。那麼在前後端分離開發的時代,有沒有能拿得出手的Python Web框架呢?當然是有的,FastApi它來了。

一、為什麼是FastApi?

人們在介紹FastApi的時候通常會說“FastApi”是一個高效能的非同步WEB框架。我相信沒有哪個程式設計師會跟“高效能”過不去,這往往也是我們所追求的東西。fastapi具有併發效能強、能夠快速上手、容錯能力強、自動生成互動式文件的特點,這些都是我們選擇它的理由。

二、到底有多快?

很多人介紹FastApi框架時,經常說其併發效能能夠和NodeJS以及Go媲美,其實言過其實。在Go語言中文社群中夢想做小猿分別對Go、Flask、FastApi做了效能測試,迫於篇幅限制,我這裡直接放結果:

FastAPI:500併發 30秒:Speed=955466 pages/min, 238685 bytes/sec

Flask:500併發 30秒:Speed=33706 pages/min, 96457 bytes/sec

Go:500併發 30秒:Speed=116962 pages/min, 278740 bytes/sec

可見Go還是很強大的,但是fastapi已經遠遠超過了同為python框架的 flask。

與PHP7對比:

分別用PHP7、FastAPI從mongodb資料庫中取出相同的資料做成介面,相同引數得到相同的資料結果,速度如下:

FastApi用時43.06ms:

PHP7 用時43.73ms:

經過多次測試,成績較為穩定,無需取平均值,由此看來,FastApi速度上相比於其他Python框架,是佔有絕對優勢的!

三、安裝相關模組

FaseApi這麼快,想必你已經迫不及待想要了解如何使用了。接下來我們講講如何開始第一個FastApi專案。

安裝FastApi執行 pip install fastapi

由於FastApi還需要一個ASGI服務框架 uvicorn,需要執行pip install uvicorn來安裝uvicorn。

注意Linux下一般會報錯如下:

Centos 執行yum install python3-devel,Ubuntu 執行sudo apt-get install python3-dev,即可解決問題,非常簡單!

四、Hello, API

現在就來快速上手吧:

第一個api:

建立檔案zhiliao.py,碼程式碼:

# -*- coding:utf-8 -*-from fastapi import FastAPI #建立一個FastApi例項app = FastAPI()#建立訪問路徑,下面的函式用來處理"/"的GET請求@app.get("/")def read_root(): return {"Hello": "Api"}

然後在zhiliao.py檔案所在目錄,執行uvicorn zhiliao:app --reload

其中,zhiliao是py檔名,冒號後面的app是我們在程式碼中建立的FastAPI例項,這一點類似Flask,其他引數等下會詳細說到。

執行之後,得到反饋資訊。

可以看到Uvicorn running on [http://127.0.0.1:8000 [0m (Press CTRL+C to quit),開啟瀏覽器:

這樣就成功的建立了第一個介面服務,每次請求的同時我們也能能夠看到,請求日誌,方便除錯。

獲取路徑引數:

接著寫如下程式碼:

#程式會獲取路徑hello後面的引數,傳入函式hello作為引數@app.get("/hello/{name}")def hello(name): res = {} res['name'] = name return res

儲存之後可以看到:

專案自動重新載入了,我們無需再執行uvicorn……,原因是我們剛剛啟動例項時,加了--reload引數,這一點類似於Flask中的debug=True,不推薦在線上環境中開啟,僅為了線下除錯方便。

訪問瀏覽器:http://127.0.0.1:8000/hello/知了,可以看到:

我們不難發現,res在程式中是一個字典,而fastapi將其自動轉為了json格式,無需再使用json模組進行編碼,這極大的便利了我們的開發。

問號傳參與資料型別限制:

為了防止使用者填寫表單時不按套路來,我們最好對引數型別進行限制,上程式碼:

@app.get("/zhiliao")def read_args(name:str, age:int): return {"name": name, "age":age }

瀏覽器訪問http://127.0.0.1:8000/zhiliao?name=張三&age=23:

如果改成http://127.0.0.1:8000/zhiliao?name=張三&age='23'也即是字元23,會報錯,提示資料型別錯誤。

{"detail":[{"loc":["query","age"],"msg":"value is not a valid integer","type":"type_error.integer"}]}

自動生成文件:

fastapi具有自動生成文件的能力:

互動文件:

訪問:http://127.0.0.1:8000/docs,可以看到,上面我們寫的三個介面都已經給出了文件。

可以看到,給出了非常詳細的反饋資訊:

API文件:

我們開啟http://127.0.0.1:8000/redoc

可以看到詳細的文件:

五、進階篇:1. 基礎引數配置:

我們使用uvicorn 配合fastapi,它是一個基於 asyncio 開發的一個輕量級高效的 Web 伺服器框架。

下面一條命令演示常用引數:

uvicorn zhiliao:app --host 127.0.0.1 --port 80

--host是繫結的地址,127.0.0.1為本地,如果是0.0.0.0,那麼意味著它將暴露在公網中,所有人都可以訪問,線上環境常用。

--port 80表示,使用80埠作為該服務的預設埠,無需在地址後加埠號,可以直接訪問 http://127.0.0.1

2. 開啟 HTTPS, 給你的網站加把小鎖:

鮮有人在講fastapi時提到開啟HTTPS,大人,時代變了,http早已經被谷歌瀏覽器標記為不安全。不過,你還別說,網站上了https 還真是好看呢。

另外,如果我們的應用不開啟https,那麼將意味著只能被未開啟ssl的網站呼叫,假設我們主站用的是https,那麼我們必須開啟HTTPS,否則會呼叫失敗。

說了這麼多,其實做起來很簡單,執行uvicorn --help可以看到詳細的配置文件,可以看到:

--ssl-keyfile TEXT              SSL key file  --ssl-certfile TEXT             SSL certificate file  --ssl-version INTEGER           SSL version to use (see stdlib ssl module's)                                  [default: 2]

有這麼三個引數,第一個是證書的key檔案,第二個是crt檔案,第三個不用管是預設的。

只需執行:

uvicorn zhiliao:app --host 0.0.0.0 --port 8080 --ssl-keyfile /ssl/private.key --ssl-certfile /ssl/certificate.crt

這意味著我們的應用將會在8080埠執行,並且暴露在公網中,人們都可以訪問,--ssl-keyfile引數後面跟key檔案目錄,--ssl-certfile,同理。可以看到,網站已經可以用https訪問。

3. 配置跨域傳參

既然是介面服務,那麼跨域傳參是必然要碰到的問題。

現有情景如下我們的Api服務是127.0.0.0:8000,而我們的網站主域名是127.0.0.1,

不同埠屬於不同域,下面的介紹也適合其他跨域場景比如主站是www.xx.com而api服務的域名是api.xx.com,同樣適合。

現在網站要呼叫api的介面,我們用jquery的 ajax試一下:

建立一個測試檔案zhiliao.html,寫入如下內容並訪問:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script><script> //引入CDN jquery$.get("http://127.0.0.1:8000/", function(data){ //get資料console.log(data);//控制檯列印資料});</script>

可以看到,由於是不同域,訪問失敗:

加上幾行程式碼,最終如下:

# -*- coding:utf-8 -*-from fastapi import FastAPI from starlette.middleware.cors import CORSMiddleware  #引入 CORS中介軟體模組#建立一個FastApi例項app = FastAPI()#設定允許訪問的域名origins = ["http://127.0.0.1"]  #也可以設定為"*",即為所有。#設定跨域傳參app.add_middleware(    CORSMiddleware,     allow_origins=origins,  #設定允許的origins來源    allow_credentials=True,    allow_methods=["*"],  # 設定允許跨域的http方法,比如 get、post、put等。    allow_headers=["*"])  #允許跨域的headers,可以用來鑑別來源等作用。#建立訪問路徑,下面的函式用來處理"/"的GET請求@app.get("/")def read_root():    return {"Hello": "Api"}@app.get("/hello/{name}")def hello(name):    res = {}    res['name'] = name    return res@app.get("/zhiliao")def read_args(name:str, age:int):    return {"name": name, "age":age }

我們重新整理瀏覽器:

跨域傳參成功,獲取資料成功。

那麼,介紹到這裡就結束了,相信有了python+fastapi的加持,python在web領域又多了一席之地。也希望,fastapi成為你的得力工具。

最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • vue 寫類似手風琴特效(展開——收起)——單一內容展示