用FastAPI开发网络数据接口
FastAPI 是一个用于构建API(网络数据接口)的现代、高性能的Web框架,基于Python 3.6+,使用了Python中的类型提示进行类型检查,非常符合工程化开发的需求,在业界有非常好的口碑。下面,我们先用代码告诉大家FastAPI到底能做什么,然后再来讲解它的方方面面。
FastAPI五分钟上手
FastAPI 的核心目标是提供一个简单、快速、易用的现代Web框架。它强调了开发效率和代码的可读性,可以帮助开发者更加快速地开发出高性能的API。
在五分钟内,我们可以通过以下几个步骤快速上手FastAPI:
-
安装依赖库和ASGI服务器(支持异步I/O的Python服务器)。
pip install fastapi pip install uvicorn
-
编写代码
main.py
。from fastapi import FastAPI app = FastAPI() @app.get('/') def say_hello(): return {'code': 200, 'message': 'hello, world!'}
-
运行服务。
uvicorn main:app --reload
说明:上面运行uvicorn时使用的–reload参数会在代码发生变更时自动重新加载新的内容,这个参数在开发阶段非常的有用。
-
访问服务。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NKR8CbM0-1681296439192)(res/run-first-demo.png)]
我们可以看到,通过以上四个简单的步骤,我们就可以在浏览器中访问到一个FastAPI应用程序。如果我们想要查看API的文档,只需要在浏览器中访问
http://localhost:8000/docs
即可。
请求和响应
在FastAPI中,我们可以使用GET
、POST
、PUT
、DELETE
等RESTful API方式来实现服务的请求和响应。我们通过定义视图函数,将其装饰为对应的请求方法,然后在函数中实现对应的业务逻辑就好了。FastAPI会自动根据参数注解、返回类型注解等信息,为我们生成对应的文档和类型检查。
例如,我们可以定义一个POST请求,用来接收一个JSON格式的请求体,然后返回一个JSON格式的响应。代码如下:
from fastapi import FastAPI
app = FastAPI()
@app.post('/test')
def test(payload: dict):
return {'status': 'OK', 'payload': payload}
在上面的代码中,我们定义了一个/test
的POST请求,该请求接收一个名为payload
的JSON请求体,然后返回一个名为status
的字符串和一个名为payload
的JSON响应体。如果我们访问http://localhost:8000/docs
,就可以看到如下的API文档:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K08beY4x-1681296439193)(res/request-response-example.png)]
我们可以看到,FastAPI根据我们的代码自动生成了API文档,包括了请求和响应的格式、参数的类型、参数的描述等信息。
接入关系型数据库
我们可以使用SQLAlchemy三方库来实现对关系型数据库的接入。SQLAlchemy是一个ORM(对象关系映射)框架,ORM框架可以解决Python程序的面向对象模型和关系型数据库的关系模型并不匹配的问题,使得我们可以用面向对象的方式实现数据的CRUD操作。
使用SQLAlchemy连接数据库的步骤如下:
-
安装依赖库。
pip install sqlalchemy
-
编写代码。
from sqlalchemy import create_engine, Column, Integer, String from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base engine = create_engine('postgresql://user:password@localhost:5432/dbname') Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True, index=True) name = Column(String) email = Column(String, unique=True) password = Column(String) Base.metadata.create_all(bind=engine) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
-
使用Session进行数据库操作。
from fastapi import FastAPI, Depends from sqlalchemy.orm import Session app = FastAPI() def get_db(): db = SessionLocal() try: yield db finally: db.close() @app.get('/users/{user_id}') def get_user(user_id: int, db: Session = Depends(get_db)): return db.query(User).filter(User.id == user_id).first()
在上面的代码中,我们使用了SQLAlchemy来连接一个名为dbname
的PostgreSQL数据库,并定义了一个users
表。然后,我们定义了一个get_db
函数来获取数据库的Session对象,并使用Depends
装饰器将其注入到FastAPI的视图函数中。
依赖注入
FastAPI支持依赖注入,我们可以使用Depends
装饰器来声明一个依赖,它可以是一个函数、一个类、一个参数,甚至是一个异步函数。在请求到达视图函数之前,FastAPI会先解析依赖关系,将依赖的对象传递给视图函数,使得我们可以在函数中使用这些对象。
例如,我们可以定义一个依赖,用来获取当前用户的信息:
from fastapi import FastAPI, Depends
app = FastAPI()
def get_current_user(token: str = Depends(get_token)):
return User(token)
@app.get('/users/me')
def read_current_user(current_user: User = Depends(get_current_user)):
return current_user
在上面的代码中,我们定义了一个get_current_user
函数作为依赖,用来获取当前用户的信息。然后,我们定义了一个read_current_user
函数,它的参数中包含了一个current_user
参数,该参数的类型为User
,表示当前用户的信息。在执行read_current_user
函数之前,FastAPI会先执行get_current_user
函数,并将其返回的User
对象注入到read_current_user
函数中。
中间件
FastAPI支持中间件,中间件是一种在请求到达视图函数之前或之后,对请求进行处理的机制。我们可以使用中间件来进行请求响应日志的记录、权限校验、异常处理等。
例如,我们可以定义一个中间件,用来记录请求的响应时间:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware('http')
async def log_request(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
end_time = time.time()
duration = end_time - start_time
logger.info(f'{request.method} {request.url.path} {response.status_code} {duration}s')
return response
在上面的代码中,我们定义了一个名为log_request
的中间件,它接收一个Request
对象和一个call_next
函数作为参数。在函数体内,我们记录了请求的开始时间,然后调用call_next
函数继续处理请求,并记录了请求的结束时间。最后,我们在日志中输出了请求的方法、路径、响应状态码和响应时间。
异步化
FastAPI天生支持异步I/O,使用异步I/O可以使得我们的Web服务更加高效、高并发。我们可以使用Python的异步框架asyncio
、异步HTTP客户端httpx
等,来实现异步I/O的功能。
例如,我们可以使用httpx
库来实现异步的HTTP请求:
import httpx
async def async_request(url: str):
async with httpx.AsyncClient() as client:
response = await client.get(url)
return response.text
在上面的代码中,我们使用了httpx
库来发送一个异步的HTTP请求,然后返回响应的文本内容。
虚拟化部署(Docker)
Docker是一个开源的应用容器引擎,可以让开发者打包应用程序以及其依赖项到一个可移植的容器中,然后发布到任何流行的Linux或Windows机器上,也可以实现云端部署。我们可以使用Docker将FastAPI应用程序打包成一个镜像,然后在任何支持Docker的环境中进行部署。
例如,我们可以使用以下Dockerfile来构建一个FastAPI应用程序的Docker镜像:
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
在上面的Dockerfile中,我们首先基于一个Python 3.8的slim镜像构建一个Docker镜像,然后将代码和依赖项复制到镜像中,并安装依赖项。最后,我们使用uvicorn
命令启动FastAPI应用程序,并将其绑定到0.0.0.0:8000地址上。
项目实战:车辆违章查询
我们可以使用FastAPI来实现一个车辆违章查询的API。首先,我们需要准备好违章查询的数据源,可以使用第三方的数据源,也可以自己爬取数据。然后,我们需要设计好API的接口,定义好请求和响应的数据格式。最后,我们通过FastAPI框架实现对应的业务逻辑,并将应用部署到云端。
例如,我们可以定义以下API接口:
from fastapi import FastAPI
app = FastAPI()
@app.get('/car-records/{car_number}')
def get_car_records(car_number: str):
records = query_car_records(car_number)
return {'records': records}
@app.post('/car-record')
def add_car_record(record: CarRecord):
add_car_record_to_database(record)
return {'status': 'OK', 'message': 'Car record added successfully.'}
在上面的代码中,我们定义了两个API接口:一个用于查询车辆的违章记录,一个用于添加车辆的违章记录到数据库中。在查询车辆的违章记录时,我们首先查询数据库中是否存在该车辆的记录,如果存在就返回记录,否则就返回空数组。在添加车辆的违章记录时,我们首先将记录添加到数据库中,然后返回添加成功的消息。
总结:
FastAPI是一个非常优秀的Python Web框架,它具有快速、易用、高性能等特点。通过本文的介绍,我们可以看到FastAPI的灵活性和强大的功能,可以帮助我们更加快速地开发出高性能的API。如果您还没有尝试过FastAPI,我强烈建议您去尝试一下!