Skip to content

Instantly share code, notes, and snippets.

@XCanG
Created January 28, 2020 09:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save XCanG/e60038668f2ff78a0c1439f36202cfd5 to your computer and use it in GitHub Desktop.
Save XCanG/e60038668f2ff78a0c1439f36202cfd5 to your computer and use it in GitHub Desktop.
Рассмотр фреймворка FastAPI

FastAPI

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 БД.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment