太通透了!Python FastAPI核心功能及主要特点最全总结!

FastAPI是一个用于构建高性能Web应用程序的Python框架。它基于Python 3.7+的新特性,如类型注释、异步I/O和API路由等,提供了一种快速、简单和易于使用的方法来构建Web API。

在这篇文章中,将介绍FastAPI及其主要特点和性能,以及Python与其他流行框架相比较的应用实例。

太通透了!Python FastAPI核心功能及主要特点最全总结!_第1张图片

什么是FastAPI?

FastAPI是由Sebastián Ramírez在2018年发布的。他创建FastAPI的想法来自于在使用当时存在的框架来执行开发API的任务时所遇到的一些困难。

FastAPI号称是目前最快的Python框架之一,可将开发速度提高多达300%并具有高性能。这个框架使用了Python最新版本中增加的功能,创造了一个用于构建API的现代工具。此外,FastAPI使用scarlettPydanticOpenAPI等工具,以寻求高性能、低学习曲线和易于应用程序编码。

技术交流

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

技术交流、资料干货、数据&源码,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:Python学习与数据挖掘,后台回复: 交流
方式②、添加微信号:dkl88194,备注:来自CSDN +交流

毕设/大作业系列

  • 毕设/大作业:基于Python+Flask+MySQL的豆瓣电影可视化系统
  • 毕设/大作业:搭建基于 Python+Flask+MySQL 的学生培养计划管理系统(附源码)
  • 毕设/大作业:一款基于 Python+flask 的态势感知系统(附完整源码)
  • 毕设/大作业:基于 Python 的 Flask 框架开发的在线电影网站系统(附完整源码)
  • 毕设/大作业:基于 Echarts + Python Flask 动态实时大屏轻松可以实现
  • 毕设/大作业:基于 Python+Django 构建智能互动拍照系统
  • 毕设/大作业:基于 Python+Flask+SQLite 的网易云音乐评论情感分析系统
  • 毕设/大作业:基于 Python 和Surprise库,新手轻松搭建推荐系统
  • 毕设/大作业:基于 Python+Django+MySQL 数据库的租房数据可视化系统

主要特点:

性能

毋庸置疑,FastAPI最吸引人的是它的性能测试结果。与其他更传统的框架如DjangoFlask相比,FastAPI的性能更强。这是由于该框架是使用Starlette构建的,Starlette是一个轻量级的ASGI框架/工具,是在Python中构建异步Web服务的理想选择。

在下面的图片中,可以看到各种框架之间的性能比较。FastAPI在这个测试中的表现比DjangoFlask好,仅次于UvicornStarlette,在查看其性能时是由于UvicornStarlette更适合,因为它们是针对这一特定情况的更具体的框架,然而FastAPI和其他框架相比有更多的功能。

太通透了!Python FastAPI核心功能及主要特点最全总结!_第2张图片

并发和异步/等待

FastAPI实现的本地异步支持也支持应用程序的性能。与其他未实现异步编程的基于Python 2的框架相比,这是一个优势。

快速编码

由于使用了Type HintsPydantic(一种简单的声明性语法),FastAPI被认为是一个非常精简的框架,并且像Flask一样,它使用模块化的概念来增加新功能。

自动文档

只需几行代码,FastAPI就能使用OpenAPI生成其端点的文档。将在下面的例子中看到这个功能。

安装

要求

  • Python 3.7以上

使用如下的命令安装FastAPI。

pip install fastapi

还需要一个ASGI服务器,用于生产目的,如UvicornHypercorn

pip install "uvicorn[standard]"

在这个例子中也将使用SQLAlchemy ORM

pip install SQLAlchemy

电影CRUD API

接下来,将创建一个简单的应用程序,其中包括一个API,用于CRUD一个名为Movies的表。

在安装了FastAPI、UvicornSQLAlquemy之后,将创建以下文件结构。

太通透了!Python FastAPI核心功能及主要特点最全总结!_第3张图片

数据库

开始创建管理数据库的模块。在这个模块中,将使用SQLAlchemy ORM来管理SQLite数据库,创建电影模型并访问数据。

src/db/database.py文件将负责创建数据库连接和管理会话。

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///db/db.sqlite3"

engine = create_engine(
    SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()


def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

src/db/models.py文件中,将创建Movies表,它将包含属性idtitledirectorduration_in_minutesrating

from sqlalchemy import Column, Integer, String
from db.database import Base


class Movies(Base):
    __tablename__ = "Movies"

    id: int = Column(Integer, primary_key=True, index=True)
    title: str = Column(String(100), nullable=False)
    director: str = Column(String(255), nullable=False)
    duration_in_minutes: int = Column(Integer, nullable=False)
    rating: int = Column(Integer, nullable=False)

最后,将创建src/db/repositories.py文件,它将作为一个接口,使API层能够访问数据库资源。

from sqlalchemy.orm import Session

from .models import Movies


class MovieRepository:
    @staticmethod
    def find_all(db: Session) -> list:
        return db.query(Movies).all()

    @staticmethod
    def save(db: Session, movie: Movies) -> Movies:
        if movie.id:
            db.merge(movie)
        else:
            db.add(movie)
        db.commit()
        return movie

    @staticmethod
    def find_by_id(db: Session, id: int) -> Movies:
        return db.query(Movies).filter(Movies.id == id).first()

    @staticmethod
    def exists_by_id(db: Session, id: int) -> bool:
        return db.query(Movies).filter(Movies.id == id).first() is not None

    @staticmethod
    def delete_by_id(db: Session, id: int) -> None:
        movie = db.query(Movies).filter(Movies.id == id).first()
        if movie is not None:
            db.delete(movie)
            db.commit()

模式

src/schemas.py文件将包含表示将在HTTP请求或响应的主体中接收和返回的数据的类。为了创建这些类,将使用Pydantic,这是一个安装FastAPI时附带的库。Pydantic旨在通过使用Python的Type Hints功能,提供一种更简单、更直接的方式来执行数据验证。

MovieBase类中,拥有在请求和API响应中都存在的基本属性。创建这个类是为了减少代码的重复。请注意,除了使用Type Hints之外,duration_in_minutesrating属性也使用了Pydantic验证。

另外,在MovieResponse类中创建了一个叫做Config(配置)的不同的类,用于向我们的Pydantic模型传递额外的配置。所做的配置将orm_mode选项设置为True,从而使类中的一个静态方法称为from_orm。这个类允许从ORM的一个模型类中创建一个Pydantic模型的实例。

from pydantic import BaseModel, Field


class MovieBase(BaseModel):
    title: str
    director: str
    duration_in_minutes: int = Field(ge=0)
    rating: int = Field(ge=1, le=5)


class MovieRequest(MovieBase):
    pass


class MovieResponse(MovieBase):
    id: int

    class Config:
        orm_mode = True

FastAPIs CRUD

现在准备创建src/main.py文件,在该文件中将实例化FastApi应用程序。除了FastAPI文件外,还将SQLAlchemy的元素导入该文件,以建立与数据库的连接、先前创建的模式类以及用于数据类型的类。

第一个函数是创建函数,它负责在数据库中注册电影。这个函数使用@app.post装饰器,这样路由就被解释为POST。在这个装饰器中,告知路由端点response_model,告知响应体中会包含什么类型的数据,最后是status_code,定义了成功请求后的预期HTTP状态。

在创建方法中,定义了一个叫做request的参数,它是MovieRequest的类型。这个参数接收在请求正文中传递的数据。还有一个名为db的第二个参数,其类型为Session,其默认值为Depends(get_db)指令。此刻正在执行依赖注入,FastAPI将执行get_db函数。这将返回一个LocalSession类的实例,它是数据库会话;然后它将把这个会话传递给创建函数。

列出所有电影、通过ID搜索电影、更新电影和删除电影的其他端点与创建端点的模式相同。所有的端点都有一个路由和一个HTTP动词,此外还有一些响应,例如在没有找到电影ID的情况下,会有一个失败的状态。

from fastapi import FastAPI, Depends, HTTPException, status, Response
from sqlalchemy.orm import Session

from db.models import Movies
from db.database import engine, Base, get_db
from db.repositories import MovieRepository
from schemas import MovieRequest, MovieResponse

Base.metadata.create_all(bind=engine)

app = FastAPI()


@app.post(
    "/api/movies", response_model=MovieResponse, status_code=status.HTTP_201_CREATED
)
def create(request: MovieRequest, db: Session = Depends(get_db)):
    movie = MovieRepository.save(db, Movies(**request.dict()))
    return MovieResponse.from_orm(movie)


@app.get("/api/movies", response_model=list)
def find_all(db: Session = Depends(get_db)):
    movies = MovieRepository.find_all(db)
    return [MovieResponse.from_orm(movie) for movie in movies]


@app.get("/api/movies/{id}", response_model=MovieResponse)
def find_by_id(id: int, db: Session = Depends(get_db)):
    movie = MovieRepository.find_by_id(db, id)
    if not movie:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="movie not found"
        )
    return MovieResponse.from_orm(movie)


@app.delete("/api/movies/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_by_id(id: int, db: Session = Depends(get_db)):
    if not MovieRepository.exists_by_id(db, id):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="movie not found"
        )
    MovieRepository.delete_by_id(db, id)
    return Response(status_code=status.HTTP_204_NO_CONTENT)


@app.put("/api/movies/{id}", response_model=MovieResponse)
def update(id: int, request: MovieRequest, db: Session = Depends(get_db)):
    if not MovieRepository.exists_by_id(db, id):
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="movie not found"
        )
    movie = MovieRepository.save(db, Movies(id=id, **request.dict()))
    return MovieResponse.from_orm(movie)

运行应用程序

随着所有代码的准备就绪,现在可以运行应用程序。

uvicorn main:app --reload

自动文档

正如之前所看到的,FastAPI的主要功能之一是用OpenAPI轻松创建自动文档。在对应用程序进行本地部署之后,访问http://localhost:8000/docs route,可以找到一个包含所有端点、模型和验证的交互式文档,所有这些都是只用PydanticType Hints创建的。

太通透了!Python FastAPI核心功能及主要特点最全总结!_第4张图片

FastAPI vs. Flask vs. Django

当谈论用Python开发Web应用时,最流行的框架是DjangoFlask

Django于2005年发布,直到今天它都是最常用的框架,有大量的学习资料、库和活跃的社区。Django遵循单体结构,有自己的ORM,也有DRF等流行框架。由于它的结构,Django被认为是一个完整的框架,推荐用于复杂的应用程序。

另一方面,Flask被认为是与Django相反的。它被归类为一个微框架,使用模块化结构,可以使用不同的库和框架来构建应用程序。由于Flask的简单性和快速开发,它被推荐用于小型应用。

最终,FastAPI试图在关注性能的同时,在简单性和更多的本地功能之间取得平衡。该框架因使用了其他框架因过时而没有的较新功能而获得欢迎。建议在需要高性能、低延迟和高开发速度的工具中使用FastAPI。然而,人们应该考虑到,由于它是一个相对较新的框架,除了有一个较小的社区外,它没有如此大量的库。

太通透了!Python FastAPI核心功能及主要特点最全总结!_第5张图片

结论

总之,FastAPI有几个优点,包括容易编码的应用程序,使用简单,学习迅速,有一个用户友好的界面,并与大多数Python库和工具兼容。

然而,像任何技术一样,它也有其局限性,例如,与FlaskDjango等更成熟的框架相比,社区相对较小,教程和资源数量有限。最终,使用FastAPI的决定将取决于项目的具体需求和开发团队的经验。然而,凭借其速度和易用性,FastAPI肯定值得在未来的任何API开发项目中考虑。

你可能感兴趣的:(学习笔记,python,fastapi,开发语言)