Introducing FastAPI

Instead of a foreword

, . , , . . , , . , copy/paste , . , .
 


:

  • ,
  • ,
  • ,

, , HTTP API, POST , , . FastAPI, ?


Who is FastAPI?


FastAPI is a framework for creating concise and fairly fast HTTP API servers with built-in validation, serialization and asynchrony,
as they say, out of the box. He stands on the shoulders of the other two frameworks: the work with the web in FastAPI engaged Starlette , and is responsible for the validation Pydantic .


The harvester turned out to be light, not overloaded and more than sufficient in functionality.


Minimum required


FastAPI requires an ASGI server to work, by default the documentation offers uvcorn , based on uvloop , however FastAPI can also work with other servers, for example, c hypercorn


Here are my dependencies:


[packages]
fastapi = "*"
uvicorn = "*"

And this is more than enough.


For more thorough readers, at the end of the article there is a link to the repository with a bot, where you can look at the dependencies for development and testing.

Well, we pipenv install -dstarted!


Build the API


It should be noted that the approach to designing handlers in FastAPI is extremely reminiscent of the same in Flask, Bottle, and thousands of them. Apparently, millions of flies cannot be wrong.


In the very first approximation, my release processing route looked like this:


from fastapi import FastAPI
from starlette import status
from starlette.responses import Response

from models import Body

app = FastAPI()  # noqa: pylint=invalid-name

@app.post("/release/")
async def release(*,
                  body: Body,
                  chat_id: str = None):
    await proceed_release(body, chat_id)
    return Response(status_code=status.HTTP_200_OK)

, , , FastAPI Body, chat_id URL params


models.py:


from datetime import datetime
from enum import Enum

from pydantic import BaseModel, HttpUrl

class Author(BaseModel):
    login: str
    avatar_url: HttpUrl

class Release(BaseModel):
    name: str
    draft: bool = False
    tag_name: str
    html_url: HttpUrl
    author: Author
    created_at: datetime
    published_at: datetime = None
    body: str

class Body(BaseModel):
    action: str
    release: Release

, Pydantic. , , , :


class Body(BaseModel):
    action: str
    releases: List[Release]

FastAPI . . , - โ€” .


Pydantic , HttpUrl, URL , FastAPI . Pydantic


.



FastAPI , , , ,
โ€” !


FastAPI , :


from fastapi import FastAPI, HTTPException, Depends
from starlette import status
from starlette.requests import Request

import settings
from router import api_router
from utils import check_auth

docs_kwargs = {}  # noqa: pylint=invalid-name
if settings.ENVIRONMENT == 'production':
    docs_kwargs = dict(docs_url=None, redoc_url=None)  # noqa: pylint=invalid-name

app = FastAPI(**docs_kwargs)  # noqa: pylint=invalid-name

async def check_auth_middleware(request: Request):
    if settings.ENVIRONMENT in ('production', 'test'):
        body = await request.body()
        if not check_auth(body, request.headers.get('X-Hub-Signature', '')):
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

app.include_router(api_router, dependencies=[Depends(check_auth_middleware)])

, request.body โ€” , . FastAPI( Starlette) , .


, FastAPI โ€” OpenAPI Swagger/ReDoc , _/docs _/redoc .


. .


, :


from fastapi import APIRouter
from starlette import status
from starlette.responses import Response

from bot import proceed_release
from models import Body, Actions

api_router = APIRouter()  # noqa: pylint=invalid-name

@api_router.post("/release/")
async def release(*,
                  body: Body,
                  chat_id: str = None,
                  release_only: bool = False):

    if (body.release.draft and not release_only) \
            or body.action == Actions.released:
        res = await proceed_release(body, chat_id)
        return Response(status_code=res.status_code)
    return Response(status_code=status.HTTP_200_OK)


, HTTP API- , .



FastAPI โ€” , , , . , (, , 2020- ?
), .


, , , , , FastAPI.



, , . โ€” , , , , .


, , github actions


The report is over, thank you all!


All Articles