FastAPI Python
Введение | |
Установка | |
Запуск сервиса | |
Простейший пример | |
Проверка типа | |
Swagger docs | |
Похожие статьи |
Введение
FastAPI — веб-фреймворк для создания API, написанный на Python.
Один из самых быстрых и популярных (после Django и Flask) веб-фреймворков, написанных на Python (на 2023 год).
FastAPI активно использует декораторы, аннотации типов и интроспекцию кода, что позволяет уменьшить количество шаблонного кода в веб-приложении.
FastAPI автоматически генерирует и отображает документацию согласно спецификации OpenAPI.
В основе FastAPI лежат две библиотеки — Starlette (ASGI-фреймворк) и
Pydantic
(для описания схем данных); FastAPI склеивает их и реализует некоторые дополнительные возможности — регистрацию представлений через внедрение зависимостей, работу с аутентификацией и
авторизацией, автоматическую генерацию документации и другое.
Возможно использование как асинхронных, так и синхронных представлений.
Самый любимый (most loved) python-веб-фреймворк по опросу среди разработчиков на портале Stack Overflow (2021, 2022).
Официальный сайт -
https://fastapi.tiangolo.com/
Некоторые изображения будет лучше видно если открывать их в отдельной вкладке.
Установка
python -m venv venv
source venv/Scripts/activate
touch requirements.txt
vi requirements.txt
fastapi==0.110.1 uvicorn==0.29.0
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
Collecting fastapi Downloading fastapi-0.110.0-py3-none-any.whl (92 kB) |████████████████████████████████| 92 kB 5.7 MB/s Collecting uvicorn[standard] Downloading uvicorn-0.27.1-py3-none-any.whl (60 kB) |████████████████████████████████| 60 kB 4.1 MB/s Collecting typing-extensions>= 4.8.0 Downloading typing_extensions-4.10.0-py3-none-any.whl (33 kB) Collecting starlette<0.37.0,>= 0.36.3 Downloading starlette-0.36.3-py3-none-any.whl (71 kB) |████████████████████████████████| 71 kB 4.5 MB/s Collecting pydantic&33;= 1.8,&33;= 1.8.1,&33;= 2.0.0,&33;= 2.0.1,&33;= 2.1.0,<3.0.0,>= 1.7.4 Downloading pydantic-2.6.2-py3-none-any.whl (394 kB) |████████████████████████████████| 394 kB 6.4 MB/s Collecting pydantic-core= = 2.16.3 Downloading pydantic_core-2.16.3-cp38-none-win_amd64.whl (1.9 MB) |████████████████████████████████| 1.9 MB ... Collecting annotated-types>= 0.4.0 Downloading annotated_types-0.6.0-py3-none-any.whl (12 kB) Collecting anyio<5,>= 3.4.0 Downloading anyio-4.3.0-py3-none-any.whl (85 kB) |████████████████████████████████| 85 kB ... Collecting idna>= 2.8 Downloading idna-3.6-py3-none-any.whl (61 kB) |████████████████████████████████| 61 kB 4.5 MB/s Collecting exceptiongroup>= 1.0.2 Downloading exceptiongroup-1.2.0-py3-none-any.whl (16 kB) Collecting sniffio>= 1.1 Downloading sniffio-1.3.1-py3-none-any.whl (10 kB) Collecting h11>= 0.8 Downloading h11-0.14.0-py3-none-any.whl (58 kB) |████████████████████████████████| 58 kB 3.8 MB/s Collecting click>= 7.0 Using cached click-8.1.7-py3-none-any.whl (97 kB) Collecting websockets>= 10.4 Downloading websockets-12.0-cp38-cp38-win_amd64.whl (124 kB) |████████████████████████████████| 124 kB 6.8 MB/s Collecting httptools>= 0.5.0 Downloading httptools-0.6.1-cp38-cp38-win_amd64.whl (60 kB) |████████████████████████████████| 60 kB ... Collecting colorama>= 0.4 Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB) Collecting python-dotenv>= 0.13 Downloading python_dotenv-1.0.1-py3-none-any.whl (19 kB) Collecting pyyaml>= 5.1 Downloading PyYAML-6.0.1-cp38-cp38-win_amd64.whl (157 kB) |████████████████████████████████| 157 kB ... Collecting watchfiles>= 0.13 Downloading watchfiles-0.21.0-cp38-none-win_amd64.whl (279 kB) |████████████████████████████████| 279 kB 6.8 MB/s Installing collected packages: typing-extensions, sniffio, idna, exceptiongroup, colorama, pydantic-core, h11, click, anyio, annotated-types, websockets, watchfiles, uvicorn, starlette, pyyaml, python-dotenv, pydantic, httptools, fastapi Successfully installed annotated-types-0.6.0 anyio-4.3.0 click-8.1.7 colorama-0.4.6 exceptiongroup-1.2.0 fastapi-0.110.0 h11-0.14.0 httptools-0.6.1 idna-3.6 pydantic-2.6.2 pydantic-core-2.16.3 python-dotenv-1.0.1 pyyaml-6.0.1 sn sniffio-1.3.1 starlette-0.36.3 typing-extensions-4.10.0 uvicorn-0.27.1 watchfiles-0.21.0 websockets-12.0
Запуск сервиса
Если файл с кодом называется main.py а приложение вызывается как app, сервис будет запускаться командой uvicorn main:app
# main.py … app = FastAPI() …
uvicorn main:app
FastAPI запущенный таким образом остановится если вы закроете терминал. Если вы подлкючаетесь к облачному серверу uvicorn остановится после оключения.
Чтобы FastAPI постоянно работал на моём облачном сервере Beget я устанавливаю gunicorn и затем выполняю команду
gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:80
Простейший пример
touch main.py
vi main.py
from fastapi import FastAPI app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"}
uvicorn main:app
INFO: Started server process [33972] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
main - так как наш скрипт main.py
app - так как app = FastAPI()
uvicorn main:app --port 8003 --reload
INFO: Will watch for changes in these directories: ['C:\Users\Andrei\sandbox\python\fastapi'] INFO: Uvicorn running on http://127.0.0.1:8003 (Press CTRL+C to quit) INFO: Started reloader process [32404] using WatchFiles INFO: Started server process [19652] INFO: Waiting for application startup. INFO: Application startup complete.
Благодаря --reload внесённые изменения подгрузятся автоматически
from fastapi import FastAPI app = FastAPI() @app.get("/", description="This is our first route.") async def root(): return {"message": "Hello World"} @app.post("/") async def post(): return {"message": "hello from the post route"} @app.put("/") async def put(): return {"message": "hello from the put route"}
Если в браузере открыть
localhost:8003/docs
Появится автоматически созданная документация Swagger
РЕКЛАМА от Яндекса. Может быть недоступна в вашем регионе
Конец рекламы. Если там пусто считайте это рекламой моей телеги
Если обратится по несуществующему адресу FastAPI вернёт сообщение
detail "Not Found"
Проверка типа
В предыдущем примере мы не использовали type hints при объявлении get_item(item_id)
… @app.get("/items/{item_id}") async def get_item(item_id): return {"item_id": item_id}
Если теперь с помощью type hint указать тип как int, обратиться к строке уже не получится
… @app.get("/items/{item_id}") async def get_item(item_id: int): return {"item_id": item_id}
int по-прежнему работает
Swagger docs
Как уже было показано
выше
обратившись к /docs можно изучить Swagger документацию к нашему API
Протестируем её на примере item_id
Прямо из документации можно отправить curl запрос с желаемым id. 0 как целое число приведёт к успеху
Обратите внимание на Response body
{ "item_id": 0 }
Здесь 0 это число. Если бы type hint был не int а str, 0 всё-равно можно бы было передать, просто вернулся бы он как строка
{ "item_id": "0" }
"test" как строка приведёт к ошибке.
FastAPI перебирает адреса сверху вниз. Если вам нужно, чтобы у какого-то адрес был приоритет, ставьте его выше.
Например, если я хочу выделить специальный item с именем default нельзя объявить метод снизу.
… @app.get("/items/{item_id}") async def get_item(item_id: str): return {"item_id": item_id} @app.get("/items/default") async def get_default_item(): return {"message": "This is default item"}
В этом случае все мой обращения к
http://localhost:8003/items/default
Будут возвращать
item_id "default"
Так как до последнего адреса FastAPI просто не дойдет - предыдущий полностью подходит под запрос.
Если теперь поменять функции местами, default будет выполняться раньше чем всё остальное, но на все остальные запросы это никак не повлияет.
… @app.get("/items/default") async def get_default_item(): return {"message": "This is default item"} @app.get("/items/{item_id}") async def get_item(item_id: str): return {"item_id": item_id}
http://localhost:8003/items/default
message "This is default item"
http://localhost:8003/items/regulat
item_id "regular"
INFO: 127.0.0.1:65380 - "GET /favicon.ico HTTP/1.1" 404 Not Found
FastAPI | |
list comprehension: Абстракция списка | |
Python | |
Pydantic | |
Пример API с БД | |
Циклы | |
Фреймворки |