FastAPI 是一个使用 Python 编写的 Web 框架,还应用了 Python asyncio 库中最新的优化。本文将会介绍如何搭建基于容器的开发环境,还会展示如何使用 FastAPI 实现一个小型 Web 服务。
起步
我们将使用 Fedora 作为基础镜像来搭建开发环境,并使用 Dockerfile 为镜像注入 FastAPI、Uvicorn 和 aiofiles 这几个包。
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 命令构建容器镜像。
$ podman build -t fastapi . $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/fastapi latest 01e974cabe8b 18 seconds ago 326 MB
下面我们可以开始创建一个简单的 FastAPI 应用程序,并通过容器镜像运行。
from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello Fedora Magazine!"}
将上面的代码保存到 main.py 文件中,然后执行以下命令开始运行:
$ 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!" 修改为其它内容,然后观察效果。
可以使用以下命令停止应用程序:
$ podman stop fastapi
构建一个小型 Web 服务
接下来我们会构建一个需要 I/O 操作的应用程序,通过这个应用程序,我们可以看到 FastAPI 自身的特点,以及它在性能上有什么优势(可以在这里参考 FastAPI 和其它 Python Web 框架的对比)。为简单起见,我们直接使用 dnf history 命令的输出来作为这个应用程序使用的数据。
首先将 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 上找到。
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】