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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;一…