FastAPI快速入門

文章目錄

    • 了解FastAPI程序結構
      • 第一步,導入FastAPI
      • 第二步,創建一個app實例
      • 第三步,編寫一個 路徑操作裝飾器
      • 第五步、運行開發服務器uvicorn main:app --reload即可訪問api鏈接。
      • 符案例
    • 聲明路徑參數
    • 聲明路徑參數的類型
    • get請求查詢參數
    • 請求體
      • 如何實現請求體
    • 跨域配置
    • 數據庫連接
      • 1.配置
      • 2.定義實體
      • 3.應用
      • CRUD
      • 在main.py中聲明
      • 路由就已經注冊好了,可以正常訪問

了解FastAPI程序結構

編寫一個簡單的FastAPI程序需要五個小步驟,先看一個完整例子

from fastapi import FastAPIapp = FastAPI()@app.get("/")
def root():return {"message": "Hello World"}

第一步,導入FastAPI

from fastapi import FastAPI

第二步,創建一個app實例

app = FastAPI()

第三步,編寫一個 路徑操作裝飾器

@app.get("/")

需要注意的兩點是:
● 你可以將get操作方法更改成@app.post()、@app.put()、@app.delete()等方法
● 你可以更改相應的路徑(“/”)為自己想要的,例如我更改為(“/hello_word/”)
第四步,編寫一個路徑操作函數,例如下面代碼中的root函數。它位于路徑操作裝飾器下方(見上方例子)
def root():
return {“message”: “Hello World”}
這個函數的返回值可以是
dict,list,單獨的值,比如str,int,或者是Pydantic模型

第五步、運行開發服務器uvicorn main:app --reload即可訪問api鏈接。

也可以安裝uvicorn,啟動

pip install uvicornimport uvicorn
from fastapi import FastAPI
app=FastAPI()
if __name__ == '__main__':uvicorn.run(app)
  1. 例如我在終端運行uvicorn main:app --reload之后,在瀏覽器輸入127.0.0.1:8000,出現"message": "Hello World"這句話。
  2. 在這里可以自己指定要運行的服務器ip和端口號。
  3. 例如:uvicorn main:app --host 127.0.0.1 --port 8001 --reload表示指定本地電腦為服務器,端口號為8001。下面所有的代碼演示都默認這個本機ip地址和8001端口號。

符案例

from fastapi import FastAPI
import uvicorn
from service.knowledge_service import router as kno_router
from service.session_service import router as session_router
app = FastAPI()
# 聲明多應用
app.include_router(kno_router)
app.include_router(session_router)@app.get("/")
def root():return {"message": "Hello World"}if __name__ == '__main__':uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True)

聲明路徑參數

from fastapi import FastAPIapp = FastAPI()@app.get("/items/{item_id}") 
def read_item(item_id):return {"item_id": item_id}

聲明路徑參數的類型

from fastapi import FastAPIapp = FastAPI()@app.get1("/items/{item_id}")
async def read_item1(item_id: int):return {"item_id": item_id}@app.get2("/items/{item_name}")
def read_item2(item_name: str):return {"item_id": item_name}

get請求查詢參數

from fastapi import FastAPIapp = FastAPI()@app.get("/files/")
def add(num1: int=2, num2: int=8):return {"num1 + num2 = ": num1 + num2}

請求體

請求體是客戶端發送到您的API的數據。 響應體是您的API發送給客戶端的數據。
API幾乎總是必須發送一個響應體,但是客戶端并不需要一直發送請求體。
定義請求體,需要使用 Pydantic 模型。注意以下幾點
不能通過GET請求發送請求體
發送請求體數據,必須使用以下幾種方法之一:POST(最常見)、PUT、DELETE、PATCH

如何實現請求體

第一步,從pydantic中導入BaseModel

from pydantic import BaseModel

第二步,創建請求體數據模型
聲明請求體數據模型為一個類,且該類繼承 BaseModel。所有的屬性都用標準Python類。和查詢參數一樣:數據類型的屬性如果不是必須的話,可以擁有一個默認值或者是可選None。否則,該屬性就是必須的。

from pydantic import BaseModelclass Item(BaseModel):name: str description: str = Noneprice: float tax: float = None 

所以訪問鏈接的時候傳入的請求體可以是下面兩種

第一種
{"name": "Foo","description": "An optional description","price": 45.2,"tax": 3.5
}
第二種
{"name": "Foo","price": 45.2
}

第三步、將模型定義為參數
將上面定義的模型添加到你的路徑操作中,就和定義Path和Query參數一樣的方式:

from fastapi import FastAPI
from pydantic import BaseModelclass Item(BaseModel):name: strdescription: str = Noneprice: floattax: float = Noneapp = FastAPI()@app.post("/items/")
async def create_item(item: Item):return item

【注】
(1)

class Item(BaseModel):name: strdescription: str | None = Noneprice: floattax: float | None = None@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):results = {"item_id": item_id, "item": item}return results

async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
item: Annotated[Item, Body(embed=True)

item: Annotated[Item, Body(embed=True)]
● 這部分定義了請求體中的數據。它使用了 Annotated 和 Body 來為 item 參數指定詳細的信息。
● Annotated[Item, Body(embed=True)]:
○ Item 是一個 Pydantic 模型類,表示請求體的數據結構。Pydantic 會驗證請求體中的數據是否符合 Item 類的要求,自動進行類型檢查。
○ Item 類的字段包括:
■ name(字符串類型,必填)
■ description(可選的字符串)
■ price(浮動類型,必填)
■ tax(可選的浮動類型)
○ Body(embed=True) 是 FastAPI 提供的一個功能,表示請求體數據應該“嵌套”在一個對象內,而不是直接以屬性的形式存在。這意味著,客戶端請求的 JSON 數據結構應該像這樣:
{
“item”: {
“name”: “item_name”,
“description”: “item_description”,
“price”: 99.99,
“tax”: 5.0
}
}

(2)

from pydantic import BaseModel, Field
description: str | None = Field(default=None, title="The description of the item", max_length=300
)

= Field(…)
● 這里使用了 Pydantic 的 Field 函數來為 description 字段提供更多的元數據和驗證規則。
● Field 是 Pydantic 用來定義字段的函數,可以用來設置字段的默認值、驗證條件、描述信息等。

跨域配置

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()# 在這里換上前端的源請求
origins = ["http://localhost.tiangolo.com","https://localhost.tiangolo.com","http://localhost","http://localhost:8080",
]app.add_middleware(CORSMiddleware,allow_origins=origins,allow_credentials=True,allow_methods=["*"],allow_headers=["*"],
)@app.get("/")
async def main():return {"message": "Hello World"}

數據庫連接

1.配置

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from contextlib import contextmanager
# MySQL所在主機名
HOSTNAME = "127.0.0.1"
# MySQL監聽的端口號,默認3306
PORT = 3306
# 連接MySQL的用戶名,自己設置
USERNAME = "root"
# 連接MySQL的密碼,自己設置
PASSWORD = "root"
# MySQL上創建的數據庫名稱
DATABASE = "fadiantest"SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True
)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)@contextmanager
def get_db():db = SessionLocal()try:yield dbfinally:db.close()Base = declarative_base()

2.定義實體

from sqlalchemy import Column, String, Integer, Float ,DateTime
from config.mysql_config import Baseclass PowerPlant(Base):'''發電量'''__tablename__ = 'power_plant'id = Column(Integer, primary_key=True, autoincrement=True)power_plant_date = Column(String(128))month_power_generation = Column(Float)unit = Column(String(128))

3.應用

from config.mysql_config import get_db
from pojo.entities import PowerPlant@app.get("/hi")
async def say_hello():with get_db() as db:  # 確保會話被正確管理powerPlant = PowerPlant(power_plant_date="2024-11-11", month_power_generation=12.21, unit="機組")db.add(powerPlant)db.commit()return {"message": f"添加成功"}

CRUD

from fastapi import FastAPI,Query
import uvicorn
from sqlalchemy.orm import Session
from sqlalchemy import and_
app = FastAPI()@app.get("/")
async def root():return {"message": "Hello World"}@app.get("/hello/{name}")
async def say_hello(name: str):return {"message": f"Hello {name}"}from config.mysql_config import get_db
from models.entities import PowerPlant
from pojo.entities import PowerPlantPo
@app.get("/hi")
async def say_hello():with get_db() as db:  # 確保會話被正確管理powerPlant = PowerPlant(power_plant_date="2024-11-11", month_power_generation=12.21, unit="機組")db.add(powerPlant)db.commit()return {"message": f"添加成功"}@app.get("/getAll")
async def get_all_power_plants():with get_db() as db:powerPlants = db.query(PowerPlant).all()  # 查詢所有記錄return [{"id": plant.id,"power_plant_date": plant.power_plant_date,"month_power_generation": plant.month_power_generation,"unit": plant.unit} for plant in powerPlants]@app.put("/update_power_plant")
async def update_power_plant(powerPlant: PowerPlantPo):with get_db() as db:db_power_plant = db.query(PowerPlant).filter(PowerPlant.id == powerPlant.id).first()if db_power_plant:db_power_plant.power_plant_date = powerPlant.power_plant_datedb_power_plant.month_power_generation = powerPlant.month_power_generationdb_power_plant.unit = powerPlant.unitdb.commit()  # 提交事務db.refresh(db_power_plant)  # 確保數據已經被提交并刷新到數據庫print(f"Updated power plant: {db_power_plant}")  # 打印確認是否更新return {"message": "更新成功"}return {"message": "未找到該電廠信息"}@app.post("/addpow")
async def add_power_plant(powerPlant: PowerPlantPo):with get_db() as db:powerPlant = PowerPlant(power_plant_date=powerPlant.power_plant_date,month_power_generation=powerPlant.month_power_generation,unit=powerPlant.unit)db.add(powerPlant)  # 將實體添加到會話db.commit()  # 提交事務return {"message": "添加成功"}@app.delete("/deletepower/{plant_id}")
async def delete_power_plant(plant_id: int):with get_db() as db:powerPlant = db.query(PowerPlant).filter(PowerPlant.id == plant_id).first()if powerPlant:db.delete(powerPlant)  # 刪除數據db.commit()  # 提交事務return {"message": "刪除成功"}return {"message": "未找到該電廠信息"}@app.get("/powerplants")
async def get_power_plants(page: int = 1,  # 默認第一頁size: int = 10,  # 默認每頁10條name: str = Query(None),  # 過濾條件:電廠名稱location: str = Query(None)  # 過濾條件:電廠位置
):offset = (page - 1) * size  # 計算偏移量with get_db() as db:# 構造查詢過濾條件query_filters = []if name:query_filters.append(PowerPlant.unit.like(f"%{name}%"))if location:query_filters.append(PowerPlant.power_plant_date.like(f"%{location}%"))# 使用and_將多個過濾條件組合query = db.query(PowerPlant).filter(and_(*query_filters)) if query_filters else db.query(PowerPlant)# 獲取總數total_count = query.count()# 獲取分頁后的數據power_plants = query.offset(offset).limit(size).all()# 計算總頁數total_pages = (total_count + size - 1) // sizereturn {"total_count": total_count,"total_pages": total_pages,"page": page,"size": size,"power_plants": power_plants}if __name__ == '__main__':uvicorn.run(app)
``## 多個文件對應flask的藍圖
### 注冊多個文件```python
from fastapi import APIRouter
from config.mysql_config import get_db
from models.entities import PowerPlantrouter = APIRouter(prefix="/user",tags=["user"],responses={404: {"description": "Not found"}}
)@router.get('/getAll',tags=["users"])
def read_pow():with get_db() as db:powerPlants = db.query(PowerPlant).all()  # 查詢所有記錄return [{"id": plant.id,"power_plant_date": plant.power_plant_date,"month_power_generation": plant.month_power_generation,"unit": plant.unit} for plant in powerPlants]

在main.py中聲明

from service.user_service import router as user_router
app = FastAPI()app.include_router(user_router)

路由就已經注冊好了,可以正常訪問

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62249.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

云計算.運維.面試題

1、計算機能直接識別的語言( C )。 A、匯編語言 B、自然語言 C、機器語言 D、高級語言 2、應用軟件是指( D )。 A、所有能夠使用的軟件 B、能被各應用單位共同使用的某種軟件 C、所有計算機上都應使用的基本軟件D、專門為某一應用目的而編制的軟件 3、計算機的顯示器是一…

如何優雅地實現單例模式?內部靜態類還是雙重檢查鎖定?

在最近的一個項目中,我需要為一個核心配置類實現單例模式。在設計過程中,我發現要同時滿足延遲加載和線程安全這兩個要求,常見的實現方式有兩種:內部靜態類和雙重檢查鎖定(Double-Checked Locking, DCL)。 …

【計算機網絡】 —— 數據鏈路層(壹)

文章目錄 前言 一、概述 1. 基本概念 2. 數據鏈路層的三個主要問題 二、封裝成幀 1. 概念 2. 幀頭、幀尾的作用 3. 透明傳輸 4. 提高效率 三、差錯檢測 1. 概念 2. 奇偶校驗 3. 循環冗余校驗CRC 1. 步驟 2. 生成多項式 3. 例題 4. 總結 四、可靠傳輸 1. 基本…

golang實現簡單的redis服務

golang 手搓redis服務器倉庫地址:實現思路: golang 手搓redis服務器 倉庫地址: 倉庫: https://github.com/dengjiayue/my-redis.git 實現思路: ● 協議: tcp通信 ● 數據包: 長度(4byte)方法(1byte)數據json ● 數據處理: 單線程map讀寫 ○ 依次處理待處理隊列的請求(chan)…

智慧銀行反欺詐大數據管控平臺方案(八)

智慧銀行反欺詐大數據管控平臺的核心理念,在于通過整合先進的大數據技術、算法模型和人工智能技術,構建一個全面、智能、動態的反欺詐管理框架,以實現對金融交易的全方位監控、欺詐行為的精準識別和高效處理。這一理念強調數據驅動決策&#…

3D 生成重建019-LERF用文本在Nerf中開啟上帝之眼

3D 生成重建019-LERF用文本在Nerf中開啟上帝之眼 文章目錄 0 論文工作1 論文方法2 實驗結果 0 論文工作 人類利用自然語言描述物理世界,根據各種特性(視覺外觀、語義、抽象關聯)尋找具體的3D位置。在這項工作中,作者提出了語言嵌…

如何選擇合適的期刊投稿?從課題組經驗到在線工具的使用全解析

~~~本文是作者個人的經驗分享,建立在導師讓自己選刊的情況下~~~ 投稿選刊是科研過程中至關重要的一步,選刊過程可能讓許多初投稿的研究者感到迷茫和困惑:期刊那么多,如何找到最合適的? 本文將從多個角度介紹如何選擇投…

024、Docker與SSH在分布式系統中的實踐指南

1. Docker SSH配置最佳實踐 Docker容器通常不需要SSH服務來運行,因為它們設計為輕量級、無狀態的,并且通常通過Docker命令行界面與宿主機進行交互。但是,在某些情況下,您可能需要通過SSH訪問Docker容器進行調試、維護或其他操作。…

【kafka】消息隊列的認識,Kafka與RabbitMQ的簡單對比

什么是消息隊列? 消息隊列(Message Queue,簡稱 MQ)是一個在不同應用程序、系統或服務之間傳遞數據的機制。 它允許系統間異步地交換信息,而無需直接交互,確保消息的可靠傳輸。 想象一下,你正在…

.NET MAUI與.NET for Android/IOS的關系

2024年11月13日微軟發布了.Net9.0,我打算體驗一下。安裝好.Net9.0 SDK后發現Visual Studio識別不到9.0,但是通過命令行dotnet --info查看是正常的,后面看到了VS有版本可以升級,把VS升級到17.12.0就可以了。更新完打開以后看到如下界面 這里…

SqlDataAdapter

SqlDataAdapter 是 .NET Framework 和 .NET Core 中提供的一個數據適配器類,屬于 System.Data.SqlClient 命名空間(或在 .NET 6 中屬于 Microsoft.Data.SqlClient 命名空間)。它的作用是充當數據源(如 SQL Server 數據庫&#xff…

【vivado】時序報告--best時序和worst時序

利用vivado進行開發時,生成best時序報告和worst時序報告。 best時序報告 slow選擇min_max,fast選擇none。 worst時序報告 fast選擇min_max,slow選擇none。

FastAPI 響應狀態碼:管理和自定義 HTTP Status Code

FastAPI 響應狀態碼:管理和自定義 HTTP Status Code 本文介紹了如何在 FastAPI 中聲明、使用和修改 HTTP 狀態碼,涵蓋了常見的 HTTP 狀態碼分類,如信息響應(1xx)、成功狀態(2xx)、客戶端錯誤&a…

力扣題庫-擲骰子模擬詳細解析

題目如下: 有一個骰子模擬器會每次投擲的時候生成一個 1 到 6 的隨機數。 不過我們在使用它時有個約束,就是使得投擲骰子時,連續 擲出數字 i 的次數不能超過 rollMax[i](i 從 1 開始編號)。 現在,給你一…

深入淺出:PHP中的數據類型全解析

文章目錄 引言理解數據類型標量類型整數 (integer)浮點數 (float)布爾值 (boolean)字符串 (string) 復合類型數組 (array)對象 (object)資源 (resource)NULL 特殊類型Callable強制類型轉換 實戰案例總結與展望參考資料 引言 在編程的世界里,數據類型是構建任何應用…

當linux可執行文件缺少或者不兼容so庫時候,如何查看版本以及缺少那些庫

解決方法: ldd 命令來驗證程序是否加載了正確的庫: 如檢查linear_elasticity可執行文件缺少的庫,用下面命令: ldd linear_elasticity 可以發現下面not found就是缺少的庫,還有對應的庫的位置已經版本 $ ldd lin…

第P1周:Pytorch實現mnist手寫數字識別

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 目標 1. 實現pytorch環境配置 2. 實現mnist手寫數字識別 3. 自己寫幾個數字識別試試具體實現 (一)環境 語言環境:Python…

Seq2Seq模型的發展歷史;深層RNN結構為什么出現梯度消失/爆炸問題,Transformer為什么不會;Seq2Seq模型存在問題

目錄 Seq2Seq模型的發展歷史 改進不足的地方 深層RNN結構為什么出現梯度消失/爆炸問題,Transformer為什么不會 深層RNN結構為什么出現梯度消失/爆炸問題: Transformer為什么不會出現梯度消失/爆炸問題: Seq2Seq模型存在問題 T5模型介紹 Seq2Seq模型的發展歷史 序列到…

網絡安全技術詳解:虛擬專用網絡(VPN) 安全信息與事件管理(SIEM)

虛擬專用網絡(VPN)詳細介紹 虛擬專用網絡(VPN)通過在公共網絡上創建加密連接來保護數據傳輸的安全性和隱私性。 工作原理 VPN的工作原理涉及建立安全隧道和數據加密: 隧道協議:使用協議如PPTP、L2TP/IP…

Hive 窗口函數與分析函數深度解析:開啟大數據分析的新維度

Hive 窗口函數與分析函數深度解析:開啟大數據分析的新維度 在當今大數據蓬勃發展的時代,Hive 作為一款強大的數據倉庫工具,其窗口函數和分析函數猶如一把把精巧的手術刀,助力數據分析師們精準地剖析海量數據,挖掘出深…