FastAPI 小白教程:從入門級到實戰(源碼教程)

目錄

1. FastAPI 基本介紹

安裝 FastAPI

2. 簡單的 CRUD 示例

2.1 創建基本應用

2.2 添加 CRUD 操作???????

3. 處理跨域請求 (CORS)

4. 普通案例:待辦事項 API???????

5. 企業案例:認證和數據庫集成

5.1 使用 SQLAlchemy 和 JWT 認證???????

6. 常見問題

6.1 性能問題

6.2 異步支持

6.3 數據庫遷移

6.4 部署問題

6.5 測試

6.6 文件上傳


?

1. FastAPI 基本介紹

FastAPI 是一個現代、快速(高性能)的 Web 框架,用于基于 Python 構建 API。它具有以下特點:

  • 快速:與 NodeJS 和 Go 相當的高性能

  • 快速編碼:開發功能的速度提高約 200%-300%

  • 更少的錯誤:減少約 40% 的人為錯誤

  • 直觀:強大的編輯器支持

  • 簡單:易于使用和學習

  • 簡短:最小化代碼重復

  • 穩健:生產就緒的代碼

  • 基于標準:完全兼容 API 開放標準(如 OpenAPI 和 JSON Schema)

安裝 FastAPI

pip install fastapipip install uvicorn  # ASGI 服務器

2. 簡單的 CRUD 示例

讓我們創建一個簡單的用戶管理 API,包含創建、讀取、更新和刪除操作。

2.1 創建基本應用???????

from fastapi import FastAPIapp = FastAPI()# 模擬數據庫fake_db = []@app.get("/")def read_root():    return {"message": "Welcome to FastAPI!"}

運行應用:

uvicorn main:app --reload

2.2 添加 CRUD 操作???????

from fastapi import FastAPI, HTTPExceptionfrom pydantic import BaseModelfrom typing import Listapp = FastAPI()# 用戶模型class User(BaseModel):    id: int    name: str    email: str# 模擬數據庫fake_db: List[User] = []# 創建用戶@app.post("/users/", response_model=User)def create_user(user: User):    fake_db.append(user)    return user# 獲取所有用戶@app.get("/users/", response_model=List[User])def read_users():    return fake_db# 獲取單個用戶@app.get("/users/{user_id}", response_model=User)def read_user(user_id: int):    for user in fake_db:        if user.id == user_id:            return user    raise HTTPException(status_code=404, detail="User not found")# 更新用戶@app.put("/users/{user_id}", response_model=User)def update_user(user_id: int, updated_user: User):    for index, user in enumerate(fake_db):        if user.id == user_id:            fake_db[index] = updated_user            return updated_user    raise HTTPException(status_code=404, detail="User not found")# 刪除用戶@app.delete("/users/{user_id}")def delete_user(user_id: int):    for index, user in enumerate(fake_db):        if user.id == user_id:            del fake_db[index]            return {"message": "User deleted"}    raise HTTPException(status_code=404, detail="User not found")

3. 處理跨域請求 (CORS)

當你的前端應用運行在不同的域名下時,需要處理跨域請求:???????

from fastapi.middleware.cors import CORSMiddlewareapp = FastAPI()# 設置允許的源origins = [    "http://localhost",    "http://localhost:8080",    "http://localhost:3000",]# 添加中間件app.add_middleware(    CORSMiddleware,    allow_origins=origins,    allow_credentials=True,    allow_methods=["*"],    allow_headers=["*"],)

4. 普通案例:待辦事項 API???????

from fastapi import FastAPI, HTTPExceptionfrom pydantic import BaseModelfrom typing import List, Optionalapp = FastAPI()class Todo(BaseModel):    id: int    title: str    description: Optional[str] = None    completed: bool = Falsetodos = []@app.post("/todos/", response_model=Todo)def create_todo(todo: Todo):    todos.append(todo)    return todo@app.get("/todos/", response_model=List[Todo])def read_todos(completed: Optional[bool] = None):    if completed is None:        return todos    return [todo for todo in todos if todo.completed == completed]@app.put("/todos/{todo_id}", response_model=Todo)def update_todo(todo_id: int, updated_todo: Todo):    for index, todo in enumerate(todos):        if todo.id == todo_id:            todos[index] = updated_todo            return updated_todo    raise HTTPException(status_code=404, detail="Todo not found")@app.delete("/todos/{todo_id}")def delete_todo(todo_id: int):    for index, todo in enumerate(todos):        if todo.id == todo_id:            del todos[index]            return {"message": "Todo deleted"}    raise HTTPException(status_code=404, detail="Todo not found")

5. 企業案例:認證和數據庫集成

5.1 使用 SQLAlchemy 和 JWT 認證???????

from fastapi import FastAPI, Depends, HTTPException, statusfrom fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestFormfrom pydantic import BaseModelfrom datetime import datetime, timedeltafrom jose import JWTError, jwtfrom passlib.context import CryptContextfrom typing import Optionalfrom sqlalchemy import create_engine, Column, Integer, String, Booleanfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import sessionmaker, Session# 數據庫配置SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"engine = create_engine(SQLALCHEMY_DATABASE_URL)SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)Base = declarative_base()# 數據庫模型class DBUser(Base):    __tablename__ = "users"    id = Column(Integer, primary_key=True, index=True)    username = Column(String, unique=True, index=True)    hashed_password = Column(String)    is_active = Column(Boolean, default=True)Base.metadata.create_all(bind=engine)# JWT 配置SECRET_KEY = "your-secret-key"ALGORITHM = "HS256"ACCESS_TOKEN_EXPIRE_MINUTES = 30class Token(BaseModel):    access_token: str    token_type: strclass TokenData(BaseModel):    username: Optional[str] = Noneclass User(BaseModel):    username: str    is_active: Optional[bool] = Noneclass UserInDB(User):    hashed_password: strpwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")app = FastAPI()# 數據庫依賴def get_db():    db = SessionLocal()    try:        yield db    finally:        db.close()# 密碼哈希def verify_password(plain_password, hashed_password):    return pwd_context.verify(plain_password, hashed_password)def get_password_hash(password):    return pwd_context.hash(password)# 用戶認證def authenticate_user(db: Session, username: str, password: str):    user = db.query(DBUser).filter(DBUser.username == username).first()    if not user:        return False    if not verify_password(password, user.hashed_password):        return False    return user# 創建 tokendef create_access_token(data: dict, expires_delta: Optional[timedelta] = None):    to_encode = data.copy()    if expires_delta:        expire = datetime.utcnow() + expires_delta    else:        expire = datetime.utcnow() + timedelta(minutes=15)    to_encode.update({"exp": expire})    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)    return encoded_jwt# 獲取當前用戶async def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):    credentials_exception = HTTPException(        status_code=status.HTTP_401_UNAUTHORIZED,        detail="Could not validate credentials",        headers={"WWW-Authenticate": "Bearer"},    )    try:        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])        username: str = payload.get("sub")        if username is None:            raise credentials_exception        token_data = TokenData(username=username)    except JWTError:        raise credentials_exception    user = db.query(DBUser).filter(DBUser.username == token_data.username).first()    if user is None:        raise credentials_exception    return user# 路由@app.post("/token", response_model=Token)async def login_for_access_token(    form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):    user = authenticate_user(db, form_data.username, form_data.password)    if not user:        raise HTTPException(            status_code=status.HTTP_401_UNAUTHORIZED,            detail="Incorrect username or password",            headers={"WWW-Authenticate": "Bearer"},        )    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)    access_token = create_access_token(        data={"sub": user.username}, expires_delta=access_token_expires    )    return {"access_token": access_token, "token_type": "bearer"}@app.get("/users/me/", response_model=User)async def read_users_me(current_user: User = Depends(get_current_user)):    return current_user@app.post("/users/", response_model=User)def create_user(user: User, db: Session = Depends(get_db)):    hashed_password = get_password_hash(user.password)    db_user = DBUser(username=user.username, hashed_password=hashed_password)    db.add(db_user)    db.commit()    db.refresh(db_user)    return db_user

6. 常見問題

6.1 性能問題

Q: FastAPI 真的比 Flask 快嗎?

A: 是的,FastAPI 基于 Starlette(用于 ASGI)和 Pydantic,性能接近 NodeJS 和 Go。根據基準測試,FastAPI 比 Flask 快得多,特別是在處理大量請求時。

6.2 異步支持

Q: 如何在 FastAPI 中正確使用 async/await?

A: FastAPI 完全支持異步。對于 I/O 密集型操作(如數據庫查詢、API 調用),使用 async def:???????

@app.get("/items/{item_id}")async def read_item(item_id: int):    item = await some_async_function(item_id)    return item

6.3 數據庫遷移

Q: 如何管理數據庫遷移?

A: 推薦使用 Alembic:???????

pip install alembicalembic init migrations

然后配置?alembic.ini?和?migrations/env.py?文件。

6.4 部署問題

Q: 如何部署 FastAPI 應用?

A: 常見部署方式:

  1. 使用 Uvicorn 或 Hypercorn 作為 ASGI 服務器

  2. 使用 Gunicorn 作為進程管理器(配合 Uvicorn worker)

  3. 使用 Docker 容器化

  4. 部署到云平臺(如 AWS, GCP, Azure)

6.5 測試

Q: 如何測試 FastAPI 應用?

A: 使用?TestClient:???????

from fastapi.testclient import TestClientclient = TestClient(app)def test_read_main():    response = client.get("/")    assert response.status_code == 200    assert response.json() == {"message": "Welcome to FastAPI!"}

6.6 文件上傳

Q: 如何處理文件上傳?

A: 使用?File?和?UploadFile:???????

from fastapi import FastAPI, File, UploadFile@app.post("/uploadfile/")async def create_upload_file(file: UploadFile = File(...)):    return {"filename": file.filename}

FastAPI 是一個強大而現代的 Python Web 框架,適合構建高性能的 API。它結合了 Python 類型提示、自動文檔生成和異步支持,使得開發體驗非常愉快。通過本教程,你應該已經掌握了 FastAPI 的基本用法、CRUD 操作、跨域處理、認證授權等核心功能。


* Thanks you *

如果覺得文章內容不錯,隨手幫忙點個贊在看轉發一下,如果想第一時間收到推送,也可以給我個星標?~謝謝你看我的文章。


*往期推薦?*

實現如何利用 Kafka 延時刪除 用戶郵箱的驗證碼(如何發送郵箱+源碼) - 第一期

Docker小白入門教程一篇領你入門(CRUD全命令+無廢話版+問題集)-第三期

Docker小白入門教程一篇領你入門(CRUD全命令+無廢話版+問題集)

想要高效處理,那不妨看看 Python的 異步 Asyncio 保證效率翻多倍

銀河麒麟 | ubuntu 安裝國產達夢DM8數據庫(安裝+外網通+IDEA連接)

網絡設備日志存儲到指定的Kiwi-log服務器(圖解+軟件)

銀河麒麟 | ubuntu 安裝運用 docker 容器,實現容器化部署項目

銀河麒麟 | ubuntu 安裝zabbix監控設備信息(親測包對)

國產操作系統-銀河麒麟本地化部署Ollama國產開源的AI大模型Qwen3

Ubuntu | ?安裝 Zabbix 一篇就夠了

Swagger | 手把手帶你寫自動生成接口文檔的爽感(零基礎親測實用)

SpringBoot整合Openfeign接入Kimi Ai!!超簡單,居然沒多少行代碼??(附加兜底教程)

SpringBoot接入Kimi實踐記錄輕松上手

Linux | 零基礎Ubuntu搭建JDK

Maven | 站在初學者的角度配置與項目創建(新手必學會)

Spring Ai | 極簡代碼從零帶你一起走進AI項目(中英)

Open Ai | 從零搭建屬于你的Ai項目(中英結合)

MongoDB | 零基礎學習與Springboot整合ODM實現增刪改查(附源碼)

Openfeign | 只傳遞城市代碼,即可獲取該地域實時的天氣數據(免費的天氣API)

Redis | 緩存技術對后端的重要性,你知道多少?

Mongodb | 基于Springboot開發綜合社交網絡應用的項目案例(中英)


感謝閱讀?|?更多內容盡在公棕號?WMCode?| CSDN@小Mie不吃飯

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

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

相關文章

java中jasypt是用來做什么的?

思路: 簡要介紹Jasypt:一句話說明它的作用。配置解析:分別解釋password和algorithm的作用。工作流程:說明如何加密敏感數據并在配置文件中使用。安全提醒:強調密鑰管理的重要性。 最終回答: Jasypt&…

牛客周賽 Round 98

1.小紅與奇數 解題思路&#xff1a;如果給定的數是偶數, 由于1是任意正數的因子, 偶數1奇數 若給定的數是奇數, 1/自身, 都變成了偶數 #include <bits/stdc.h> using namespace std; void solve() {int x;cin >> x;if (x & 1)cout << "No" <…

(2)手摸手-學習 Vue3 之 變量聲明【ref 和 reactive】

手摸手-學習 Vue3 之 變量聲明【ref 和 reactive】 前言refreactive 前言 vue3 前端代碼開發過程中&#xff0c;必然會涉及變量聲明&#xff0c;會用到&#xff1a;ref、reactive 。本章節 進行講解說明。 演示的項目&#xff0c;經處理后的結構如下&#xff1a; ref 用途…

[Terence Tao訪談] 無限 | 關注模型 | 矢量場 | 策略性“作弊” | Lean

關注模型 改變視角真的很重要 無限&#xff1a;假設是球形的奶牛 陶哲軒&#xff1a;一個很好的例子是數學中的塞邁雷迪定理&#xff0c;于1970年代得以證明&#xff0c;它涉及在一組數字集合中尋找某種類型的模式&#xff0c;即等差數列&#xff0c;例如3、5、7或10、15、20。…

汽車v型推力桿總成三維5自由度性能及疲勞測試系統

V型推力桿總成裝置&#xff0c;通常設置在載重汽車中、后橋上&#xff0c;成對使用。其一端通過球面銷與車架鉸接&#xff0c;另一端則安裝在車橋上&#xff0c;通過關節軸承與車橋鉸接&#xff0c;其主要作用是穩定車橋&#xff0c;保持車橋的穩定位置&#xff0c;同時克服彈簧…

制動系統故障定義與診斷標準

核心定義&#xff1a; 制動不足 (Brake Insufficiency) 定義&#xff1a;制動系統產生的實際制動力低于預期制動力&#xff0c;但未完全喪失制動能力 關鍵特征&#xff1a; 制動距離增加20%以上 減速度低于預期值30%-50% 制動踏板行程異常增長 等效物理描述&#xff1a;&a…

server-rs

今天早上 看到有人 用cursor寫rust東西了 效果不錯遂嘗試寫一下web serverserver本身這個詞就不確指單單這一個東西在與cursor交流中,還是越來越明白了之前 沒有管過的一些"常識"一個業務服務之所以能“一直處理請求”&#xff0c;是因為有一個“東西”在背后做著持續…

python打卡day59@浙大疏錦行

知識點回顧&#xff1a; SARIMA模型的參數和用法&#xff1a;SARIMA(p, d, q)(P, D, Q)m模型結果的檢驗可視化&#xff08;昨天說的是摘要表怎么看&#xff0c;今天是對這個內容可視化&#xff09;多變量數據的理解&#xff1a;內生變量和外部變量多變量模型 統計模型&#xff…

Redisson的分布式鎖源碼分析2

文章目錄Redisson的讀寫鎖使用加鎖源碼分析釋放鎖源碼分析&#xff1a;Redisson一次加多個鎖RedissonMultiLock加鎖源碼分析&#xff1a;RedissonMultiLock釋放鎖源碼分析&#xff1a;RCountDownLatch介紹&#xff1a;RCountDownLatch源碼分析&#xff1a;RSemaphore分布式信號…

系統架構設計師論文分享-論軟件過程模型及應用

我的軟考歷程 摘要 2023年2月&#xff0c;我所在的公司通過了研發紗線MES系統的立項&#xff0c;該系統為國內紗線工廠提供SAAS服務&#xff0c;旨在提升紗線工廠的數字化和智能化水平。我在該項目中擔任架構設計師&#xff0c;負責該項目的架構設計工作。本文結合我在該項目…

云原生Kubernetes系列 | etcd3.5集群部署和使用

云原生Kubernetes系列 | etcd3.5集群部署和使用 1. etcd集群部署2. etcd集群操作3. 新增etcd集群節點1. etcd集群部署 etcd3.5官網站點: ?? https://etcd.io/docs/v3.5/op-guide/clustering/ ?? https://etcd.io/docs/v3.5/tutorials/how-to-setup-cluster/ [root@localh…

helm安裝配置jenkins

1、k8s1.28.2、helm3.12.0&#xff0c;集群搭建 查看節點運行情況 kubectl get node -o wide openebs部署情況 kubectl get sc -n openebs 2、添加Jenkins Helm倉庫 helm repo add jenkins https://charts.jenkins.iohelm repo update# 查看版本 helm search repo -l jen…

Wagtail - Django 內容管理系統

文章目錄 一、關于 Wagtail1、項目概覽2、相關鏈接資源3、功能特性 二、安裝配置三、使用入門1、快速開始2、兼容性 四、其它社區與支持1、社區資源2、商業支持 開發貢獻參考項目參考文獻 一、關于 Wagtail 1、項目概覽 Wagtail 是一個基于 Django 構建的開源內容管理系統&am…

Spring AI Alibaba 來啦!!!

博客標題&#xff1a;Spring AI Alibaba&#xff1a;深度解析其優勢與阿里云生態的無縫集成 引言 隨著人工智能技術的快速發展&#xff0c;越來越多的企業和開發者開始關注如何將 AI 技術融入到現有的應用開發框架中。Spring AI 作為 Spring 框架在 AI 領域的擴展&#xff0c;…

【論文閱讀39】PINN求邊坡內時空變化的地震動響應(位移、速度、加速度)場分布

論文提出了一種基于物理信息神經網絡&#xff08;PINN&#xff09;和極限分析上界定理相結合的巖體邊坡地震穩定性分析框架&#xff0c;重點考慮了邊坡中的預存裂縫對穩定性的影響。 PINN用來求解巖質邊坡內隨時間和空間變化的地震動響應&#xff08;位移、速度、加速度&#…

驅動開發系列59- 再述如何處理硬件中斷

在本文中,我們將重點討論編寫設備驅動程序時一個非常關鍵的方面:什么是硬件中斷,更重要的是,作為驅動開發者,你該如何準確地處理它們。事實上,大量的外設(也就是你可能會為其編寫驅動的設備)在需要操作系統或驅動程序立即響應時,通常會通過觸發硬件中斷的方式發出請求…

【藍牙】Linux Qt4查看已經配對的藍牙信息

在Linux系統中使用Qt4查看已配對的藍牙設備信息&#xff0c;可以基于DBus與BlueZ&#xff08;Linux下的藍牙協議棧&#xff09;進行交互。以下是一個實現方案&#xff1a; 1. 引入必要的庫和頭文件 確保項目中包含DBus相關的頭文件&#xff0c;并鏈接QtDBus模塊&#xff1a; …

企業客戶數據防竊指南:從法律要件到維權實操

作者&#xff1a;邱戈龍、曾建萍 ——上海商業秘密律師 在數字經濟時代&#xff0c;客戶數據已成為企業最核心的資產之一。然而&#xff0c;數據顯示&#xff0c;近三年全國商業秘密侵權案件中&#xff0c;涉及客戶信息的案件占比高達42%&#xff0c;但最終進入刑事程序的不足…

WHAT - React Native 中 Light and Dark mode 深色模式(黑暗模式)機制

文章目錄 一、Light / Dark Mode 的原理1. 操作系統層2. React Native 如何獲取?3. 樣式怎么跟著變?二、關鍵代碼示例講解代碼講解:三、自定義主題四、運行時自動更新五、核心原理一張圖組件應用例子最小示例:動態樣式按鈕的動態樣式如何封裝一套自定義主題四、如何和 Them…

[25-cv-07396、25-cv-07470]Keith代理Anderson這9張版權圖,除此之外原告還有50多個版權!賣家要小心!

Anderson 版權圖 案件號&#xff1a;25-cv-07396、25-cv-07470 立案時間&#xff1a;2025年7月2日 原告&#xff1a;Anderson Design Group, Inc. 代理律所&#xff1a;Keith 原告介紹 原告是美國的創意設計公司&#xff0c;成立于1993年&#xff0c;簡稱ADG&#xff0c;一…