本文是东京学业大学桥山实验室2020年出现日历第22天的文章。
介绍
您正在使用FastAPI吗? ??
Django,Flask等经常在python Web框架中使用,但这一次是有关Fast API的文章。
对于与RDS的连接,文档中引入了一个称为SQLAlchemy(Mysql)的ORM,但是这次我们将使用pymongo与MongoDB连接并执行CRUD操作。
使用mongo express进行检查,该显示器可以使用GUI操作MongoDB,并使用Fast API的自动生成文档(Swagger UI)。
执行将使用Docker构建。单击此处获取GitHub。
开发环境
- MacOs:Mac mini(2018)macOS Big Sur版本11.1
- 码头工人:20.10.0
- 码头工人组成:1.27.4
- MongoDB的:4.2
1准备
1.1目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | . ├── Makefile ├── README.md ├── docker │ ├── docker-compose.yml │ ├── fast_api │ │ └── Dockerfile │ ├── mongo-express │ │ └── Dockerfile │ ├── mongo_db │ │ ├── Dockerfile │ │ ├── configdb │ │ ├── db │ │ └── mongo-init.js │ └── wait-for-it.sh └── fast_api ├── Makefile ├── __init__.py ├── __pycache__ ├── app.py ├── database.py ├── requirements.txt ├── routers │ ├── __init__.py │ ├── __pycache__ │ └── posts.py ├── sample-json │ ├── sample.json │ └── update.json └── tests ├── __pycache__ └── test_initial.py |
将
泊坞目录中。 mongo的db数据也放置在这里。
另外,在
1.2准备文件
每个文件的内容如下。
制作文件
生成文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | .PHONY: setup setup: docker-compose -f docker/docker-compose.yml build $(MAKE) install .PHONY: install install: docker-compose -f docker/docker-compose.yml run --rm fast_api make setup .PHONY: start start: docker-compose -f docker/docker-compose.yml up --remove-orphans .PHONY: start.background start.background: docker-compose -f docker/docker-compose.yml up -d --remove-orphans .PHONY: stop stop: docker-compose -f docker/docker-compose.yml down .PHONY: pytest pytest: docker-compose -f docker/docker-compose.yml run --rm fast_api make test |
fast_api / Makefile
1 2 3 4 5 6 7 | # pipでの依存関係の解決 (.pipディレクトリに依存関係を全て入れる) setup: pip3 install --upgrade pip pip3 install -r requirements.txt -t ./.pip test: python -m pytest -v |
使用的命令如下。
-使用
-使用
-使用
-使用
-使用
执行pytest
Dockerfile(3)
FastAPI h5>
码头工人/ fast_api / Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | FROM python:3.7-alpine # alpineで軽量化 ENV LANG C.UTF-8 ENV TZ Asia/Tokyo RUN apk add --update --no-cache make bash gcc g++ tzdata git\ && pip install --upgrade pip \ && pip install uvicorn==0.11.8 ENV PYTHONUNBUFFERED 1 ENV PYTHONPATH /app/.pip ADD docker/wait-for-it.sh /usr/local/bin/wait-for-it.sh RUN chmod +x /usr/local/bin/wait-for-it.sh |
MongoDB h5>
码头工人/ mongo_db / Dockerfile
1 | FROM mongo:4.2 |
蒙哥快车 h5>
码头工人/ mongo_express /码头文件
1 2 3 4 | FROM mongo-express ADD wait-for-it.sh /usr/local/bin/wait-for-it.sh RUN chmod +x /usr/local/bin//wait-for-it.sh |
docker-compose.yml
泊坞窗/ docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | version: "3.7" services: fast_api: container_name: fast_api build: context: ../. dockerfile: ./docker/fast_api/Dockerfile working_dir: /app volumes: - ../fast_api:/app:cached ports: - 8000:8000 tty: true environment: MONGO_DATABASE_NAME: mongodb MONGO_DATABASE_USER: root MONGO_DATABASE_PASSWORD: root MONGO_DATABASE_CONTAINER_NAME: mongo_db MONGO_DATABASE_PORT: 27017 command: wait-for-it.sh mongo_db:27017 --timeout=30 -- uvicorn app:app --reload --host 0.0.0.0 --port 8000 networks: - fastapi-mongo-network mongodb: container_name: mongo_db environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: root build: context: . dockerfile: ./mongo_db/Dockerfile ports: - 27017:27017 tty: true volumes: - ./mongo_db/db:/data/db - ./mongo_db/configdb:/data/configdb - ./mongo_db/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js networks: - fastapi-mongo-network mongo-express: container_name: mongo_express build: context: . dockerfile: ./mongo-express/Dockerfile environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: root ME_CONFIG_MONGODB_SERVER: mongo_db ports: - 8081:8081 tty: true command: wait-for-it.sh mongo_db:27017 --timeout=30 -- node app restart: unless-stopped networks: - fastapi-mongo-network networks: fastapi-mongo-network: driver: bridge |
等待Itsh
我是从这里借来的。
您可以等待其他容器启动后再启动它们(仅取决于顺序)。
document.txt
fast_api /要求。
1 2 3 4 5 6 7 | aiofiles==0.6.0 fastapi==0.61.1 pymongo==3.11.0 pytest==6.1.0 python-dateutil==2.8.1 setuptools==49.2.0 uvicorn==0.11.8 |
描述所需的软件包。
apppy
fast_api /应用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import uvicorn from fastapi import FastAPI from routers import posts app = FastAPI(prefix="/") app.include_router(posts.router, prefix="/post") # routingを階層的にし読み込む @app.get('/') def get_hello(): return {'message': 'Hello from FastAPI Server!'} if __name__ == '__main__': uvicorn.run(app, host="0.0.0.0", port=8000) |
启动应用程序。在Flask中,使用Buleprint使路由分层,但是在FastAPI中,可以使用
posts.py
路由器/ posts.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | from fastapi import APIRouter, Body from bson.objectid import ObjectId from bson.json_util import dumps, loads from database import db router = APIRouter() @router.post('') def create_post(body=Body(...)): """postの作成 ---------- Parameters: body: body 任意のjson """ post = body['payload'] db.posts.insert(post) return {'post': "ok"} @router.get('') def read_post(): """postの取得 ---------- Parameters: なし """ db_post = db.posts.find_one() return {'item': dumps(db_post)} @router.get('/{id}') def read_post_by_id(id: str): """postの取得(id) ---------- Parameters: id: str オブジェクトID """ db_post = db.posts.find_one({'_id': ObjectId(id)}) print(db_post) return {'item': dumps(db_post)} @router.put('') def update_post(body=Body(...)): """postの更新(id) ---------- Parameters: body: body 任意のjson """ post = body['payload'] _id = post['_id'] title = post['title'] text = post['text'] db.posts.update_one( {'_id': ObjectId(_id)}, {'$set': { "title": title, 'text': text } } ) return {'update': "ok"} @router.delete('/') def delete_post_by_id(id: str): """postの削除(id) ---------- Parameters: id: str オブジェクトID """ db.posts.delete_one( {'_id': ObjectId(id)} ) return {'delete': "ok"} |
描述帖子的CRUD。这次仅是确认,因此错误处理未完成???Λ?
写作风格与Flask相似,我觉得它很容易写。
您可以在Swagger UI中引用文档,因此可以很好地描述它(我不知道如何编写...)!
需要注意的是,从MongoDB获得的对象无法按原样转换为json格式,因此将执行转储。希望您可以将每个形状做成自己喜欢的形状。
数据库py
fast_api /数据库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import os from pymongo import MongoClient MONGO_DATABASE_NAME = os.environ.get("MONGO_DATABASE_NAME") # mongodb MONGO_DATABASE_USER = os.environ.get("MONGO_DATABASE_USER") # root MONGO_DATABASE_PASSWORD = os.environ.get("MONGO_DATABASE_PASSWORD") # root MONGO_DATABASE_CONTAINER_NAME = os.environ.get( "MONGO_DATABASE_CONTAINER_NAME") # mongo_db MONGO_DATABASE_PORT = int(os.environ.get("MONGO_DATABASE_PORT")) # 27017 DATABASE_URL = "%s://%s:%s@%s:%d" % ( MONGO_DATABASE_NAME, MONGO_DATABASE_USER, MONGO_DATABASE_PASSWORD, MONGO_DATABASE_CONTAINER_NAME, MONGO_DATABASE_PORT) client = MongoClient(DATABASE_URL) db = client.first_test #database名がfirst_test |
描述与MongoDB的连接设置。每个环境变量都用
由于MongoDB是NoSQL,它将创建尚未创建的任何内容。
使用pymongo可以很容易地描述它。
使用的数据库名称如下。
1 | db = client.first_test #database名がfirst_test |
2运行应用程序
通过按以下顺序发出命令来启动应用程序。
这次
1.创建
2.阅读(无ID /具有ID)
3.更新
4.删除
我们将按
的顺序进行。
安慰
1 2 | $ make setup $ make start |
访问
3. CRUD操作
3.1创建
API执行
复制以下
fast_api / sample-json / sample.json
1 2 3 4 5 6 | { "payload":{ "title" : "初投稿!", "text" : "hogehoge" } } |
检查MongoDB
访问
如果转到[first_test]-> [posts]-> [created post],则会找到以下文档。
3.2读取(无ID /有)
没有ID
编号
以先前创建的帖子的对象ID(确认帖子时为
3.3更新
同样,对象ID(确认帖子时为
fast_api / sample-json / update.json
1 2 3 4 5 6 7 | { "payload":{ "_id" : "5fe1661f03100427fb1e8cd3", "title" : "投稿の編集", "text" : "fugefuge" } } |
检查它是否已被mongo express更改。
3.4删除
同样,执行对象ID(确认帖子时为
检查是否已被mongo express删除。
结尾
本文介绍使用带Fast API的MongoDB进行CRUD操作。
我很高兴您可以将其用作参考。