FastAPI入门实战:从零搭建到核心功能详解

文章目录

  • 前言
  • 一、FastAPI是什么
    • [1.1 FastAPI与其他Python Web框架对比](#1.1 FastAPI与其他Python Web框架对比)
    • [1.2 异步与同步的区别](#1.2 异步与同步的区别)
    • [1.3 FastAPI的两大核心组件](#1.3 FastAPI的两大核心组件)
  • 二、如何测试API
    • [2.1 如何测试API](#2.1 如何测试API)
    • [2.2 FastAPI自动生成文档](#2.2 FastAPI自动生成文档)
  • 三、路由
    • 3.1为什么要分包
    • [3.2 路由的基本用法](#3.2 路由的基本用法)
      • [3.2.1 创建路由对象](#3.2.1 创建路由对象)
      • [3.2.2 定义路由和处理函数](#3.2.2 定义路由和处理函数)
      • [3.2.3 应用(包)路由](#3.2.3 应用(包)路由)
  • 四、请求和相应
    • [4.1 路径参数](#4.1 路径参数)
    • [4.2 请求体](#4.2 请求体)
    • [4.3 查询参数](#4.3 查询参数)
    • [4.4 表单提交](#4.4 表单提交)
    • [4.5 文件上传](#4.5 文件上传)
      • [4.5.1 方式一:使用bytes(适合小文件)](#4.5.1 方式一:使用bytes(适合小文件))
      • [4.5.2 方式二:使用UploadFile(适合大文件,推荐)](#4.5.2 方式二:使用UploadFile(适合大文件,推荐))
  • 五、其他请求信息
    • [5.1 Header(请求头)](#5.1 Header(请求头))
    • [5.2 Cookie](#5.2 Cookie)
  • 结语

前言

学习Web开发,选对工具事半功倍。FastAPI以其简洁的设计和强大的性能,正成为Python后端开发的新选择。本文从环境搭建讲起,带你一步步掌握路由设计、参数处理、文件上传等核心技能,助你快速上手现代Web开发。

一、FastAPI是什么

FastAPI是一个用来写网站后端的Python框架。框架就是别人写好的代码库,可以直接拿来用,不用从零开始。

1.1 FastAPI与其他Python Web框架对比

Python有几个主流的Web框架:

  • Django:这是一个"重量级"框架。它什么都已经准备好了,其中数据库、后台管理、用户系统都有。但是问题也在这里------哪怕只是想做一个小功能,也得把整套系统都启动起来。这也是高耦合的一大痛点。
  • Flask:这是一个"轻量级"框架,比Django简单很多,但是需要自己搭配各种组件。
  • FastAPI:也是轻量级的,但设计理念是"高内聚,低耦合"。换句话你来说就是,FastAPI本身只负责核心功能,其他功能可以自由选择第三方库来搭配。这就像乐高积木,需要什么拼什么,很灵活。

相比于Django与Flask来说FastAPI还有一大优势就是支持异步编程。

1.2 异步与同步的区别

可以简单理解的:同步就是一件事做完再做下一件事。异步就是可以同时做几件事,不用等。FastAPI支持异步操作,这样处理请求更快。

1.3 FastAPI的两大核心组件

Starlette :负责网络通信部分。它是一个轻量级的ASGI框架,适合用来搭建高性能的异步服务。
Pydantic:负责数据部分。它主要是进行数据检验操作,利用Python的类型提示功能来检查数据是否符合要求。比如你希望接收一个数字,但用户传了文字,Pydantic会自动报错并给出清晰的错误信息。

二、如何测试API

2.1 如何测试API

写好API后,你需要测试它是否正常工作。我推荐了几个工具:

  • Postman:最经典的API测试功能,功能齐全。
  • Apifox、ApiPost、Yaak:这些都是国内的API测试工具,界面友好,有些还支持中文

注:现在主要用的还是Postman,所以在下面的下面演示中我主要还是用的Postman。

2.2 FastAPI自动生成文档

FastAPI有一个很实用的功能:它会自动给你生成API文档。你不需要额外写文档,访问方式就是先在PyCharm中运行.py文档,再浏览器中输入http://localhost:+你的端口号/docs就能看到Swagger界面。这个界面可以显示所有接口,还能直接在上面测试。

2.2.1 PyCharm中运行.py

再PyCharm中的左下角找到服务(service),再点击添加服务,接着点运行配置,再选择FastAPI即可,你的FastAPI项目名就会显示在这里,再你的FAstAPI项目鼠标右键点击,再点击运行或调试(如果需要的话)即可。




2.2.2 浏览器测试API

默认端口号一般是8000,但是如果不改端口话可能在运行的时候会出现端口占用,运行出错的情况,这是可以修改端口,点击编辑所选配置,按照我下面标出的操作步骤操作。

在再浏览器中输入对应的访问地址即可。

三、路由

3.1为什么要分包

在实际开发中,一个项目通常有很多功能模块,比如用户管理、角色管理、权限管理等。如果把所有的代码文件都堆在项目根目录下,很快就会乱成一团,找文件很费劲。所以,我们需要"分而治之"------把不同功能的代码放到包里,比如:

3.2 路由的基本用法

路由就是URL和处理函数的对应关系。FAstAPI使用APIRouter来创建路由。

3.2.1 创建路由对象

python 复制代码
from fastapi import APIRouter

# 创建一个路由对象
user_router = APIRouter()

3.2.2 定义路由和处理函数

python 复制代码
@user_router.get("/users/{id}")
async def get_user(id: int):
    # {id} 是路径参数,用户访问 /users/123 时,id 就是 123
    print(id)
    return {"id": id, "name": "Alice", "age": 30}

这里的@user_router.get("/users/{id}") 是装饰器,它告诉FAstAPI:当有人用get方法访问/user/{id} 这个地址时,就执行下面的get_user 函数。{id} 是一个变量,可以是任何数字。

3.2.3 应用(包)路由

python 复制代码
from fastapi import FastAPI

app = FastAPI()

# 把user_router注册到app
# prefix="" 表示URL前缀,tags=[] 用于文档分类
app.include_router(user_router, prefix="", tags=["用户"])


@app.get("/")
async def say_hello(name: str):
    return {"message": f"Hello {name}"}

prefix是前缀,比如你想让所有用户相关的地址都以/api开头,就可以写prefix="/api"

四、请求和相应

获取数据的方式有下列5种:

4.1 路径参数

路径参数是URL中的一部分,用花括号{} 表示。比如/user/{id} 中的id 就是路径参数。

python 复制代码
# 路径参数
# Union 联合类型
@user_router.get("/detail/{name}", description="根据用户名查询用户", summary="获取用户信息")
async def get_user_by_name(name: Union[str, None] = None):
    print(name)
    return {"name": name}

其中Union 联合类型是指name这个参数在传参时可以为str或None类型的数据,当然也可以利用Union联合类型给出默认参数,只需要改为name: Union[str, None] = None

4.2 请求体

请求体式客户端发送给服务器的完整数据,通常是post或put请求时携带的JSON数据。FAstAPI用Pydantic模型来定义请求体的结构。

python 复制代码
# 请求体
class User(BaseModel):
    id: int
    name: str = Field(default="张三", max_length=20, min_length=6)
    age: int = Field(default=10, gt=0, lt=150)
    birthday: Union[date, None] = None
    # 简写:
    # birthday: Optional[date] = None
    friends: List[int] = []


# restful 风格的api
@user_router.post("/")
async def add_user(user: User):
    print(user)
    return {"user": user}

在这个示例中应用到了Pydantic来对数据进行验证,这种用法在实际开发中是应用很多的。

在这个代码中Field(default="张三", max_length=20, min_length=6) 意思是默认值(default)是张三,字符串的最大长度(max_length)为20,最小长度(min_length)为6。Field(default=10, gt=0, lt=150) 意思是默认值(default)是10,数据必须要是0~150之间的数值。friends: List[int] = [] 是定义了一个列表,要传入的参数要是int类型的数据。

4.3 查询参数

查询参数跟在URL的问号后面,比如 /users?name=Tom&age=20

特别提醒:路径后面一定要加斜杠 /

python 复制代码
@user_router.get("/info/")
async def get_user_info(name: str, age: int):
    # name 和 age 是查询参数
    # 用户访问 /info/?name=Tom&age=20 时,这两个参数会自动解析
    print(name)
    print(age)
    return {"name": name, "age": age}

注意:如果不加斜杠写成 /info,访问 /info?name=Tom 时可能会出问题。

4.4 表单提交

要处理表单数据,需要先安装一个库:

shell 复制代码
pip install python-multipart

安装好之后就可以处理提交的表单数据了。

python 复制代码
@user_router.post("/login/")
async def login(name: str = Form(...), password: str = Form(...)):
    print(name)
    print(password)
    return {"name": name, "password": password}

4.5 文件上传

文件上传有两种方式:bytesUploadFile

4.5.1 方式一:使用bytes(适合小文件)

python 复制代码
# 文件上传
@user_router.post("/upload/")
async def upload(file: bytes = File(...)):
    """
    单文件上传
    :param file:
    :return:
    """
    print(f"文件上传成功,大小为:{len(file)}")
    return {"file_size": len(file)}


@user_router.post("/uploads/")
async def upload_multiple_files(files: List[bytes] = File(...)):
    """
    多文件上传
    :param file:
    :return:
    """
    for file in files:
        print(f"文件上传成功,大小为:{len(file)}")
    return {
        "size": [len(file) for file in files]
    }

4.5.2 方式二:使用UploadFile(适合大文件,推荐)

对于大文件,用 bytes 会导致内存占用过高。UploadFile 提供了更友好的接口,它不会一次性把文件读入内存。

python 复制代码
@user_router.post("/file/upload/")
async def file_upload(file: UploadFile):
    """
    单文件上传
    :param file:
    :return:
    """
    if file:
        print(file.filename, file.content_type)

        # 上传文件
        with open(file.filename, "wb") as f:
            f.write(await file.file.read())
    return {"filename": file.filename, "content_type": file.content_type}


@user_router.post("/file/uploads/")
async def file_uploads(files: List[UploadFile] = File(...)):
    """
    UploadFile实现多文件上传
    :param files:
    :return:
    """
    for file in files:
        print(file.filename, file.content_type)
        # 上传文件
        with open(file.filename, "wb") as f:
            f.write(await file.file.read())
    return {"filename": [file.filename for file in files], "content_type": [file.content_type for file in files]}

五、其他请求信息

5.1 Header(请求头)

请求头包含了很多元信息,比如用户的浏览器类型、认证令牌等。

Cookie是服务器保存在用户浏览器里的小段数据。它常用于识别用户身份,比如"记住登录状态"。当用户再次访问时,浏览器会自动带上Cookie,服务器就能认出这个用户。

python 复制代码
@user_router.get("/request/")
async def get_request(request: Request):
    # 获取请求头 headers Mapping(K-V)
    content_type = request.headers.get("Content-Type")
    print(content_type)

    print("-" * 20)

    # 获取 cookie 字典
    print(request.cookies)

    # URL对象,有很多属性  hostname(主机) path(路径) port(端口)
    print(request.url.path)
    print(request.url.port)
    print(request.url.hostname)

    # 获取到请求方式(get/post)
    print(request.method)

在上述所有的代码中能用到的模块,包括:

python 复制代码
from datetime import date
from typing import Union, List

from fastapi import APIRouter, Form, File, Request, UploadFile
from pydantic import BaseModel, Field

注:不要从库中导错模块了。

结语

掌握FastAPI只是开始。异步编程的思维、模块化的设计理念,这些能力会伴随你的整个编程生涯。希望本文能成为你技术路上的一块垫脚石,助你写出更优雅、更高效的代码。

相关推荐
爱音乐的marlon1 天前
FastAPI 学习笔记03|core 核心层:config 是总控制台,database 是整个工程的地基
笔记·学习·fastapi
花酒锄作田2 天前
Repository 模式在 FastAPI 中的应用
python·fastapi
喜欢的名字被抢了2 天前
FastAPI 接口安全与工程化 JWT、测试和配置管理
安全·fastapi
Maiko Star3 天前
从零落地「AI掘金头条」新闻模块:FastAPI + SQLAlchemy 异步实战
python·fastapi
喜欢的名字被抢了3 天前
FastAPI 接入异步 PostgreSQL 完成任务 CRUD 与数据库迁移
数据库·postgresql·fastapi
Esaka_Forever3 天前
uvicorn main.py 命令说明
fastapi
巴啦啦小魔仙变身4 天前
FastAPI 01 Create Demo
python·fastapi
李昊哲小课5 天前
fastapi sse websocket 奶茶店实时订单看板
人工智能·python·websocket·网络协议·fastapi·sse
李昊哲小课6 天前
fastapi sse websocket 智能家居实时控制台
python·websocket·智能家居·fastapi·sse
赵广陆6 天前
SQLAlchemy ORM 超全教程
python·fastapi