FastAPI
Jump to navigation
Jump to search
Contents
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" }
==