備忘錄_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 方法與參數, 這真是太神奇了!