赞
踩
FastAPI是一个用于构建高性能Web应用程序的Python框架。它基于Python 3.7+的新特性,如类型注释、异步I/O和API路由等,提供了一种快速、简单和易于使用的方法来构建Web API。
在这篇文章中,将介绍FastAPI及其主要特点和性能,以及Python与其他流行框架相比较的应用实例。
FastAPI是由Sebastián Ramírez在2018年发布的。他创建FastAPI的想法来自于在使用当时存在的框架来执行开发API的任务时所遇到的一些困难。
FastAPI号称是目前最快的Python框架之一,可将开发速度提高多达300%并具有高性能。这个框架使用了Python最新版本中增加的功能,创造了一个用于构建API的现代工具。此外,FastAPI使用scarlett
、Pydantic
和OpenAPI
等工具,以寻求高性能、低学习曲线和易于应用程序编码。
技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。
技术交流、资料干货、数据&源码,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。
方式①、微信搜索公众号:Python学习与数据挖掘,后台回复: 交流
方式②、添加微信号:dkl88194,备注:来自CSDN +交流
毋庸置疑,FastAPI最吸引人的是它的性能测试结果。与其他更传统的框架如Django
和Flask
相比,FastAPI的性能更强。这是由于该框架是使用Starlette
构建的,Starlette
是一个轻量级的ASGI
框架/工具,是在Python中构建异步Web服务的理想选择。
在下面的图片中,可以看到各种框架之间的性能比较。FastAPI在这个测试中的表现比Django
和Flask
好,仅次于Uvicorn
和Starlette
,在查看其性能时是由于Uvicorn
和Starlette
更适合,因为它们是针对这一特定情况的更具体的框架,然而FastAPI和其他框架相比有更多的功能。
FastAPI实现的本地异步支持也支持应用程序的性能。与其他未实现异步编程的基于Python 2的框架相比,这是一个优势。
由于使用了Type Hints
和Pydantic
(一种简单的声明性语法),FastAPI被认为是一个非常精简的框架,并且像Flask
一样,它使用模块化的概念来增加新功能。
只需几行代码,FastAPI就能使用OpenAPI生成其端点的文档。将在下面的例子中看到这个功能。
使用如下的命令安装FastAPI。
pip install fastapi
还需要一个ASGI
服务器,用于生产目的,如Uvicorn
或Hypercorn
。
pip install "uvicorn[standard]"
在这个例子中也将使用SQLAlchemy ORM
。
pip install SQLAlchemy
接下来,将创建一个简单的应用程序,其中包括一个API,用于CRUD一个名为Movies
的表。
在安装了FastAPI、Uvicorn
和SQLAlquemy
之后,将创建以下文件结构。
开始创建管理数据库的模块。在这个模块中,将使用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
表,它将包含属性id
、title
、director
、duration_in_minutes
和rating
。
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_minutes
和rating
属性也使用了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
现在准备创建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
,可以找到一个包含所有端点、模型和验证的交互式文档,所有这些都是只用Pydantic
和Type Hints
创建的。
当谈论用Python开发Web应用时,最流行的框架是Django
和Flask
。
Django
于2005年发布,直到今天它都是最常用的框架,有大量的学习资料、库和活跃的社区。Django
遵循单体结构,有自己的ORM
,也有DRF
等流行框架。由于它的结构,Django
被认为是一个完整的框架,推荐用于复杂的应用程序。
另一方面,Flask
被认为是与Django
相反的。它被归类为一个微框架,使用模块化结构,可以使用不同的库和框架来构建应用程序。由于Flask
的简单性和快速开发,它被推荐用于小型应用。
最终,FastAPI试图在关注性能的同时,在简单性和更多的本地功能之间取得平衡。该框架因使用了其他框架因过时而没有的较新功能而获得欢迎。建议在需要高性能、低延迟和高开发速度的工具中使用FastAPI。然而,人们应该考虑到,由于它是一个相对较新的框架,除了有一个较小的社区外,它没有如此大量的库。
总之,FastAPI有几个优点,包括容易编码的应用程序,使用简单,学习迅速,有一个用户友好的界面,并与大多数Python库和工具兼容。
然而,像任何技术一样,它也有其局限性,例如,与Flask
和Django
等更成熟的框架相比,社区相对较小,教程和资源数量有限。最终,使用FastAPI的决定将取决于项目的具体需求和开发团队的经验。然而,凭借其速度和易用性,FastAPI肯定值得在未来的任何API开发项目中考虑。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。