使用 Python FastAPI 构建 Web 服务

FastAPI 是一个使用 Python 编写的 Web 框架,还应用了 Python asyncio 库中最新的优化。本文将会介绍如何搭建基于容器的开发环境,还会展现如何使用 FastAPI 实现一个小型 Web 服务。python

起步

咱们将使用 Fedora 做为基础镜像来搭建开发环境,并使用 Dockerfile 为镜像注入 FastAPI、Uvicornaiofiles 这几个包。linux

FROM fedora:32
RUN dnf install -y python-pip \
    && dnf clean all \
    && pip install fastapi uvicorn aiofiles
WORKDIR /srv
CMD ["uvicorn", "main:app", "--reload"]
复制代码

在工做目录下保存 Dockerfile 以后,执行 podman 命令构建容器镜像。git

$ podman build -t fastapi .
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/fastapi latest 01e974cabe8b 18 seconds ago 326 MB
复制代码

下面咱们能够开始建立一个简单的 FastAPI 应用程序,并经过容器镜像运行。github

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello Fedora Magazine!"}
复制代码

将上面的代码保存到 main.py 文件中,而后执行如下命令开始运行:web

$ podman run --rm -v $PWD:/srv:z -p 8000:8000 --name fastapi -d fastapi
$ curl http://127.0.0.1:8000
{"message":"Hello Fedora Magazine!"
复制代码

这样,一个基于 FastAPI 的 Web 服务就跑起来了。因为指定了 --reload 参数,一旦 main.py 文件发生了改变,整个应用都会自动从新加载。你能够尝试将返回信息 "Hello Fedora Magazine!" 修改成其它内容,而后观察效果。json

可使用如下命令中止应用程序:api

$ podman stop fastapi
复制代码

构建一个小型 Web 服务

接下来咱们会构建一个须要 I/O 操做的应用程序,经过这个应用程序,咱们能够看到 FastAPI 自身的特色,以及它在性能上有什么优点(能够在这里参考 FastAPI 和其它 Python Web 框架的对比)。为简单起见,咱们直接使用 dnf history 命令的输出来做为这个应用程序使用的数据。bash

首先将 dnf history 命令的输出保存到文件。服务器

$ dnf history | tail --lines=+3 > history.txt
复制代码

在上面的命令中,咱们使用 tail 去除了 dnf history 输出内容中无用的表头信息。剩余的每一条 dnf 事务都包括了如下信息:数据结构

  • id:事务编号(每次运行一条新事务时该编号都会递增)
  • command:事务中运行的 dnf 命令
  • date:执行事务的日期和时间

而后修改 main.py 文件将相关的数据结构添加进去。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class DnfTransaction(BaseModel):
    id: int
    command: str
    date: str
复制代码

FastAPI 自带的 pydantic 库让你能够轻松定义一个数据类,其中的类型注释对数据的验证也提供了方便。

再增长一个函数,用于从 history.txt 文件中读取数据。

import aiofiles

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class DnfTransaction(BaseModel):
    id: int
    command: str
    date: str


async def read_history():
    transactions = []
    async with aiofiles.open("history.txt") as f:
        async for line in f:
            transactions.append(DnfTransaction(
                id=line.split("|")[0].strip(" "),
                command=line.split("|")[1].strip(" "),
                date=line.split("|")[2].strip(" ")))
    return transactions
复制代码

这个函数中使用了 aiofiles 库,这个库提供了一个异步 API 来处理 Python 中的文件,所以打开文件或读取文件的时候不会阻塞其它对服务器的请求。

最后,修改 root 函数,让它返回事务列表中的数据。

@app.get("/")
async def read_root():
    return await read_history()
复制代码

执行如下命令就能够看到应用程序的输出内容了。

$ curl http://127.0.0.1:8000 | python -m json.tool
[
{
"id": 103,
"command": "update",
"date": "2020-05-25 08:35"
},
{
"id": 102,
"command": "update",
"date": "2020-05-23 15:46"
},
{
"id": 101,
"command": "update",
"date": "2020-05-22 11:32"
},
....
]
复制代码

总结

FastAPI 提供了一种使用 asyncio 构建 Web 服务的简单方法,所以它在 Python Web 框架的生态中日趋流行。要了解 FastAPI 的更多信息,欢迎查阅 FastAPI 文档

本文中的代码能够在 GitHub 上找到。


via: fedoramagazine.org/use-fastapi…

做者:Clément Verna 选题:lujun9972 译者:HankChow 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关文章
相关标签/搜索