備忘錄_20160105(定位)
修改
回首頁
程式 2025-04-15 11:13:05 1744686785 100
在 raspberry pi5 底下,初探 fastapi
在 raspberry pi5 底下,初探 fastapi
在 terminal 底下
sudo apt install python3-fastapi
sudo apt install python3-uvicorn
或在虛擬環境的 terminal 底下
pip install fastapi
pip install uvicorn
撰寫一程式,存成 fastapi01.py
------------------------
from fastapi import FastAPI
myapp = FastAPI()
@myapp.get("/hello")
def read_root(name: str, age: int):
return \
{
"message1": f"哈囉, {name}!",
"message2": f"您已經 {age} 歲了."
}
@myapp.get("/money")
def read_root(amount: float):
return \
{
"message3": f"您有 {amount} 元."
}
------------------------
然後執行它
python3 -m uvicorn fastapi01:myapp --reload
或在虛擬環境底下
uvicorn fastapi01:myapp --reload
這時候到瀏覽器去測試
http://127.0.0.1:8000/hello?name=小明&age=38
會得到JSON字串
{"message1":"哈囉, 小明!","message2":"您已經 38 歲了."}
若是輸入
http://127.0.0.1:8000/money?amount=99.87
會得到JSON字串
{"message3":"您有 99.87 元."}
若想要用 https 的話,請先產生憑證
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
這樣可以得到 cert.pem 以及 key.pem
然後執行
python3 -m uvicorn fastapi01:myapp \
--host 0.0.0.0 \
--port 8443 \
--ssl-keyfile=key.pem \
--ssl-certfile=cert.pem
並測試
https://127.0.0.1:8443/hello?name=小王&age=70
https://127.0.0.1:8443/money?amount=99.87
當然,用 apache 的反向代理,那也是一個策略方案。
若要佈署,可以先安裝 pyinstaller
在虛擬環境底下
pip install pyinstaller
然後執行
pyinstaller fastapi01.py --onefile
那麼,執行檔會在 dist/fastapi01
但是,因為 fastapi01 是用 uvicorn 執行的,所以這樣封裝出來的執行檔不能用。
要改成自己用 uvicorn 執行,請參考 fastapi02.py
-------------------------------------
from fastapi import FastAPI
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
myapp = FastAPI()
# 這個可以通過 CORS 政策
myapp.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
@myapp.get("/hello")
def read_root(name: str, age: int):
return \
{
"message1": f"哈囉, {name}!",
"message2": f"您已經 {age} 歲了."
}
@myapp.get("/money")
def read_root(amount: float):
return \
{
"message3": f"您有 {amount} 元."
}
if __name__ == "__main__":
uvicorn.run(
myapp,
host="0.0.0.0",
port=8000)
-------------------------------------
這個時候,就可以用 python fastapi02.py 執行。
若用 pyinstaller fastapi02.py --onefile 封裝
則 dist/fastapi02 就可以常駐執行。
您可以寫一個 html 來測試
<!DOCTYPE html>
<html>
<head>
<title>Test Fetch</title>
</head>
<body>
<script>
fetch('http://127.0.0.1:8000/money?amount=3838')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
</script>
</body>
</html>
當你在 windows 7 底下進行編譯
pyinstaller fastapi02.py --onefile
結果在執行 dist/fastapi02.exe 時
會遇到錯誤訊息 "ImportError: DLL load failed while importing _pydantic_core: 找不到指定的程序。"
原來 FastAPI 依賴 pydantic,而 pydantic v2.x 對 win7 的支援度很差,所以可以用降版處理。
pip uninstall pydantic
pip install pydantic==1.10.13
(目前的 FastAPI 仍支援 pydantic v1.x)
pyinstaller fastapi02.py --onefile
這樣編出來的 dist/fastapi02.exe 就可以在 win7 執行了!
假如要用 POST 方法,則撰寫 fastapi03.py
------------------------------------
from fastapi import FastAPI
import uvicorn
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
class MyItem(BaseModel):
name: str
price: float
myapp = FastAPI()
# 這個可以通過 CORS 政策
myapp.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
@myapp.post("/items")
def create_item(myitem: MyItem):
return \
{
"myname": myitem.name,
"myprice": myitem.price
}
@myapp.get("/hello")
def read_root(name: str, age: int):
# 需要的參數若使用者提供不齊全,會產生錯誤訊息!
return \
{
"message1": f"哈囉, {name}!",
"message2": f"您已經 {age} 歲了."
}
@myapp.get("/money")
def read_root(amount: float):
return \
{
"message3": f"您有 {amount} 元."
}
if __name__ == "__main__":
uvicorn.run(
myapp,
host="0.0.0.0",
port=8000)
------------------------------------
然後用 python fastapi03.py 執行
再來是在 javascript 的部分,用下面方法測試。
------------------------------------
fetch(
'http://127.0.0.1:8000/items',
{
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ name: "John", price: 500})
}
)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
------------------------------------
注意,用 fastapi 的 get 或 post 方法,
使用者提供的參數一定要足夠,可以多,不能少,
若是在 python 端需要 5 個參數,
結果使用者端只提供 4 個參數,
那麼程式不會往後執行,只會跳出參數不足的錯誤訊息。
另外,用 http://127.0.0.1:8000/docs
竟然會列出所有的 get/post 方法與參數,
這真是太神奇了!