FastAPI - новый фреймворк для создания REST API, ориентированный на скорость работы, удобство разработки, интуитивность, простоту использования, наличие дополнительного функционала, уменьшающего объём кода и следование стандартам (OpenAPI, JSON Schema).
FastAPI построен на основе Starlette, ASGI мифкрофреймворка, и имеет схожую с ним скорость работы и Pydantic, библиотеки для парсинга и валидации данных на основе типизации (type hinting), встроенной в Python.
FastAPI также автоматически создаёт документацию посредством библиотек Swagger и ReDoc.
По замеркам производительности результаты такие:
Фреймворк | Производительность | Классификация | Платформа | Вебсервер |
---|---|---|---|---|
fastapi | 14,442 100.0%(31.5%) | Микрофреймворк | Нет | Нет |
starlette | 14,363 99.5%(31.3%) | Платформа | Нет | Нет |
uvicorn | 14,284 98.9%(31.1%) | Платформа | Нет | Нет |
blacksheep | 14,159 98.0%(30.9%) | Платформа | Нет | Нет |
aiohttp-pg-raw | 12,019 83.2%(26.2%) | Микрофреймворк | asyncio | Gunicorn |
tornado-py3-uvloop | 11,778 81.6%(25.7%) | Платформа | Нет | Tornado |
bottle-raw | 8,247 57.1%(18.0%) | Микрофреймворк | Meinheld | Нет |
api_hour | 7,018 48.6%(15.3%) | Микрофреймворк | asyncio | Gunicorn |
flask-raw | 6,969 48.3%(15.2%) | Микрофреймворк | Meinheld | Нет |
flask-pypy2-raw | 6,821 47.2%(14.9%) | Микрофреймворк | Tornado | Нет |
morepath | 6,208 43.0%(13.5%) | Микрофреймворк | Meinheld | Gunicorn |
web2py-optimized | 5,825 40.3%(12.7%) | Fullstack | Meinheld | Нет |
weppy-pypy2 | 5,403 37.4%(11.8%) | Fullstack | Tornado | Нет |
api_hour-mysql | 4,978 34.5%(10.9%) | Микрофреймворк | asyncio | Gunicorn |
weppy | 3,140 21.7%(6.8%) | Fullstack | Meinheld | Нет |
weppy-nginx-uwsgi | 3,109 21.5%(6.8%) | Fullstack | uWSGI | nginx |
weppy-py3 | 3,107 21.5%(6.8%) | Fullstack | Meinheld | Нет |
web2py | 2,338 16.2%(5.1%) | Fullstack | Meinheld | Нет |
aiohttp | 2,293 15.9%(5.0%) | Микрофреймворк | asyncio | Gunicorn |
tornado-pypy2 | 2,192 15.2%(4.8%) | Платформа | Нет | Tornado |
flask-nginx-uwsgi | 1,618 11.2%(3.5%) | Микрофреймворк | Нет | nginx |
django-postgresql | 1,607 11.1%(3.5%) | Fullstack | Нет | Meinheld |
bottle-pypy2 | 1,581 10.9%(3.4%) | Микрофреймворк | Tornado | Нет |
flask | 1,576 10.9%(3.4%) | Микрофреймворк | Meinheld | Нет |
django-py3 | 1,570 10.9%(3.4%) | Fullstack | Нет | Meinheld |
django | 1,459 10.1%(3.2%) | Fullstack | Нет | Meinheld |
tornado-py3 | 1,396 9.7%(3.0%) | Платформа | Нет | Tornado |
bottle-nginx-uwsgi | 1,291 8.9%(2.8%) | Микрофреймворк | uWSGI | nginx |
turbogears | 1,291 8.9%(2.8%) | Микрофреймворк | Нет | Meinheld |
bottle | 1,239 8.6%(2.7%) | Микрофреймворк | Meinheld | Нет |
pyramid-py2 | 1,222 8.5%(2.7%) | Fullstack | Нет | Meinheld |
pyramid | 1,215 8.4%(2.6%) | Fullstack | Нет | Meinheld |
tornado | 1,213 8.4%(2.6%) | Платформа | Нет | Tornado |
spyne-nginx-uwsgi | 1,106 7.7%(2.4%) | Микрофреймворк | Нет | nginx |
cherrypy-py3 | 77 0.5%(0.2%) | Микрофреймворк | Нет | Нет |
klein | 72 0.5%(0.2%) | Микрофреймворк | Нет | Twisted |
cherrypy | 67 0.5%(0.1%) | Микрофреймворк | Нет | Нет |
Фреймворк | Средняя задержка | Максимальная задержка |
---|---|---|
fastapi | 34.4 ms 0.9% | 244.2 ms |
starlette | 34.7 ms 0.9% | 263.3 ms |
uvicorn | 34.9 ms 0.9% | 247.6 ms |
blacksheep | 35.7 ms 1.0% | 146.1 ms |
aiohttp-pg-raw | 41.6 ms 1.1% | 280.7 ms |
tornado-py3-uvloop | 42.4 ms 1.1% | 256.1 ms |
bottle-raw | 60.5 ms 1.6% | 234.9 ms |
flask-raw | 71.4 ms 1.9% | 240.2 ms |
api_hour | 74.7 ms 2.0% | 563.3 ms |
morepath | 80.7 ms 2.2% | 329.6 ms |
flask-pypy2-raw | 84.4 ms 2.3% | 888.7 ms |
web2py-optimized | 85.4 ms 2.3% | 481.7 ms |
weppy-pypy2 | 92.8 ms 2.5% | 554.4 ms |
api_hour-mysql | 106.7 ms 2.9% | 674.8 ms |
cherrypy-py3 | 128.7 ms 3.5% | 216.6 ms |
cherrypy | 148.1 ms 4.0% | 187.9 ms |
weppy | 158.2 ms 4.3% | 663.6 ms |
weppy-nginx-uwsgi | 160.0 ms 4.3% | 340.6 ms |
weppy-py3 | 160.5 ms 4.3% | 709.2 ms |
web2py | 214.7 ms 5.8% | 1010.0 ms |
aiohttp | 215.4 ms 5.8% | 656.4 ms |
tornado-pypy2 | 224.3 ms 6.0% | 557.7 ms |
flask-nginx-uwsgi | 307.6 ms 8.3% | 514.3 ms |
django-postgresql | 310.4 ms 8.4% | 1080.0 ms |
django-py3 | 314.3 ms 8.5% | 1320.0 ms |
flask | 315.9 ms 8.5% | 1380.0 ms |
bottle-pypy2 | 318.8 ms 8.6% | 1560.0 ms |
django | 341.1 ms 9.2% | 2440.0 ms |
tornado-py3 | 367.6 ms 9.9% | 1430.0 ms |
bottle-nginx-uwsgi | 385.1 ms 10.4% | 595.1 ms |
turbogears | 386.9 ms 10.4% | 1610.0 ms |
bottle | 395.6 ms 10.7% | 1490.0 ms |
pyramid | 403.8 ms 10.9% | 1640.0 ms |
tornado | 406.0 ms 10.9% | 716.3 ms |
pyramid-py2 | 406.9 ms 11.0% | 1710.0 ms |
spyne-nginx-uwsgi | 447.8 ms 12.1% | 685.5 ms |
webware | 2680.0 ms 72.2% | 3610.0 ms |
klein | 3710.0 ms 100.0% | 7200.0 ms |
FastAPI обрабатывает большее количество запросов в секунду по сравнению с другими фреймворками, имеет наименьшую задержку, поэтому хорошо подходит для высоконагруженных проектов.
Отдельно стоит сказать, что документация, создаваемая Swagger и ReDoc генерируется на старте фреймворка и опосля уже не тратит ресурсы при обращении к ней на её создание.
FastAPI можно назвать наибыстрейшим фреймворком на Python'е.
FastAPI взял за идею Flask (и некоторые его плагины) для написания кода в очень простом виде. Например определение путей (routes) сделано в таком же виде. Однако дальше идут различия. Если Flask использовал текущий, он же старый, стандарт WSGI, то Starlette, на котором основан FastAPI, и FastAPI используют новый стандарт асинхронных веб фреймворков ASGI. Отсюда возникает удобство при написании асинхронного кода, которым Flask обделён и требует дополнительного кода.
Далее ASGI предоставляет функционал, который отсутствовал в WSGI или не имел имплементации в большинстве фреймворках: вебсокеты (WebSockets), фоновые задачи (background tasks), и др.
В отличии от некоторых других фреймворков на FastAPI, благодаря его функционалу, удобнее работать с вебсокетами, использовать новый стандарт запросов в БД GraphQL, работать с шаблонами (templates) и др.
Пример кода простого сервера с двумя эндпоинтами (корень сайта и /items/ с числовым аргументом):
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
Так как FastAPI основан на Starlette, то он имеет весь его функционал, а так же в добавок свой собственный. Он может делать всё то же, что и может Flask. Также при наличии кода на Flask будет очень легко перенести (migrate) его на FastAPI.
FastAPI использует преимущества Python'а для определения параметров, заголовков, содержимого запросов (request/response), удобства работы с JSON, автоматическую проверку типов данных (валидацию) на основе типизации (type hinting), сериализацию данных или их конвертацию, автомтическую документацию с интерактивным API.
Помимо удобства функционал упрощает разработку ещё больше, чем на других фреймворках, благодаря автоматизации различных процедур нет необходимости в их написании, что увеличивает скорость разработки, уменьшает количество ошибок, уменьшает время, необходимое для освоения фреймворка.
Также наличие вспомогательного функционала убирает необходимость использования плагинов или каких-либо обходных путей для работы с вещами.
"Из коробки" можно работать как с синхронными процессами, так и асинхронными и различие в определении будет лишь в добавлении async к функции. Допустим, если подключение к БД идёт с использованием асинхронной библиотеки, например asyncpg (PostgreSQL), aiomysql (MySQL), aioredis (Redis) или не только БД, например отправку запросов с использованием aiohttp, или асинхронной работы с файлами aiofiles, то к примеру код выше изменится на такой:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
# здесь может быть использована какая-либо асинхронная операция
# например: `await database.connect()`
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
FastAPI, следуя стандартам OpenAPI, JSON Schema, OAuth 2.0 и др., автоматически поддерживает их и имеет полную совместимость. Фреймворк также позволяет очень просто написать код с вставками (middleware), например использование авторизации (authentication).
FastAPI также не имеет привязанности к вебсерверу (какие есть у Flask, Django, aiohttp и др. из коробки), что позволяет использовать собственный на выбор (например рекомендуют использовать uvicorn из-за небольшого объёма кода и быстрой скорости работы с FastAPI), что также убирает путаницу при переносе приложения в продакшн (deployment), что присутствует, например, у Django при разработке.
FastAPI также не имеет привязанности к БД, что позволяет выбрать любую SQL или NoSQL базу данных.
Также официальная документация очень простая и интуитивная. Освоение фреймворком произойдёт очень быстро.
Подводя итоги по всем категориям, можно сказать что FastAPI способен заменить большинство фреймворков, не нацеленных на конкретный функционал. Например в большинстве своём он полностью заменяет Flask, но вот Django имеет некоторый функционал, который фреймворк из коробки не имеет.
В то же время если сравнивать с Django, то Django однопоточный, привязан к SQL базе данных и не имеет асинхронного функционала и если конкретный функционал Django при разработке не будет необходим, то можно использовать FastAPI, получив преимущество в других его сильных сторонах.
Сравнивая с aiohttp преимуществом FastAPI будет наличие автоматизации процессов и следования упомянутым стандартам, что в случае с aiohttp потребует дополнительной обработки данных, а это увеличивает шансы совершения ошибки при работе с aiohttp.
Когда стоит выбрать FastAPI:
- Когда нужна скорость работы
- Когда важна скорость написания кода
- Когда программисты не знают фреймворков и необходим фреймворк, требующий меньшего времени для его освоения
- Если код уже был написан на другом фреймворке и требуется большая производительность
- Если требуется использование технологий вебсокетов, GraphQL, асинхронного кода и др.
- Если БД специфичная и не поддерживается другими фреймворками, либо является NoSQL БД.