FastAPI

From Colettapedia
Revision as of 20:14, 4 October 2019 by Ccoletta (talk | contribs)
Jump to navigation Jump to search

Why fastAPI

  • a free UI to test your rest api - interactive API documentation systems, OpenAPI (Swagger) and JSON Schema standards
  • Supposedly security and authentication is integrated
  • Supposedly fast
  • Editor support, useful for code editor autocompletion

Technologies

  • REST
    • how you form your API
    • Representational State Transfer
    • Has an HTTP verb, a URL which related to a bit of data, and a parameterization of that
  • Async
    • How you deliver it
    • Co-operative multitasking
    • Puts the onus on you to decide when the rest of your computer should be able to do stuff
    • Easy to get wrong
    • Easy to write code that will block the whole web application rather than make just one request slow
    • Excels in that it's able to deal with thousands and thousands of network sockets
  • Dependency Injection (DI)


URL mapping

app = FastAPI()

@app.get( "/" )
def root( ... ):
   return {"greeting": "Hello world"}

app.include_router( events.router, prefix="/events"...)
router = APIRouter()

@router.post( "/", ..., status=201)
def create_object( ... ):
   ...


Getting stuff from requests: Path variables

  • given this info
    • GET /events/1234?detail=full
    • Authorization: Token ABCD1234
  • implicit way
@router.get( "/event/{id}" )
def get_object( id: int ):
  ...
  • more explicit way - make things be required
from fastapi import Path
from pydantic import Required

@router.get( "/event/{id}" )
def get_object( id: int = Path(Required) ):
  ...


Getting stuff from URL requests: Query parameters

  • given this info
    • GET /search/?text=something
    • Authorization: Token ABCD1234
  • implicit way
@router.get( "/search" )
def search( text: str = None, offset: int = 0, limit: int = 100 ):
  ...
  • more explicit way - make things be required
from fastapi import Query

@router.get( "/search" )
def search(
  text: str = Query( default=None, max_length=20 ),
  offset: int = Query( 0 ),
  limit: int = Query( 100 )
):

Data Validation: Pydantic

  • Is this valid data??
  • Throws helpful error messages if the data isn't formatted correctly
  • "This field is required, but you didn't specify it."
from datatime import date as DateType
from enum import Enum
from pydantic import BaseModel

class Types( Enum ):
  done = 'DONE'
  cancelled = 'CANCELLED'

class Event( BaseModel ):
  date: DateType
  type: Types
  text: str

Extract blob of JSON that came in from request

from pydantic import Required

@router.post( "/events/" )
def create_object( event: Event = Required ):
   ...

Creating responses

  • If you need to retun something, just return simple Python objects. The framework renders them to JSON for you
@app.get( "/" )
def root( ... ):
  return {"greeting": "Hello World" }

@app.post( "/events/". response_model=Event, status_code=201 )
def create_object( event: Event = Required ):
  ...
  return {
    "date": "2019-06-02",
    "type": "DONE",
    "text": "some stuff got done"
  }

==