Post

NetworkSec - Fast API

ref:

  • https://github.com/tiangolo/fastapi/blob/master/README.md
  • https://fastapi.tiangolo.com/tutorial/

NetworkSec - Fast API

FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production


Documentation: https://fastapi.tiangolo.com

Source Code: https://github.com/tiangolo/fastapi


Overall

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.


Requirements

Python 3.7+

FastAPI stands on the shoulders of giants:


Installation

1
$ pip install fastapi

You will also need an ASGI server, for production such as Uvicorn or Hypercorn.

1
$ pip install "uvicorn[standard]"

Example

Create it

  • Create a file main.py with:
from typing import Union
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: Union[str, None] = None):
    return {"item_id": item_id, "q": q}
Or use async def...

If your code uses async / await, use async def:

from typing import Union

from fastapi import FastAPI

app = FastAPI()

# https://127.0.0.1:8000/
@app.get("/")
def read_root():
    return {"Hello": "World"}

# https://127.0.0.1:8000/items/5?q=somequery.
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

Note:

If you don’t know, check the “In a hurry?” section about async and await in the docs.


Run it

Run the server with:

1
2
3
4
5
6
7
$ uvicorn main:app --reload

INFO:     Uvicorn running on https://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [28720]
INFO:     Started server process [28722]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
About the command uvicorn main:app --reload...

The command uvicorn main:app refers to:

  • main: the file main.py (the Python “module”).
  • app: the object created inside of main.py with the line app = FastAPI().
  • --reload: make the server restart after code changes. Only do this for development.

Check it

Open your browser at https://127.0.0.1:8000/items/5?q=somequery.

You will see the JSON response as:

{"item_id": 5, "q": "somequery"}

You already created an API that:

  • Receives HTTP requests in the paths / and /items/{item_id}.
  • Both paths take GET operations (HTTP methods).
  • The path /items/{item_id} has a path parameter item_id that should be an int.
  • The path /items/{item_id} has an optional str query parameter q.

API docs

Interactive API docs

https://127.0.0.1:8000/docs

  • automatic interactive API documentation (provided by Swagger UI):

Swagger UI


Alternative API docs

https://127.0.0.1:8000/redoc

  • alternative automatic documentation (provided by ReDoc):

ReDoc


Example upgrade

Now modify the file main.py to receive a body from a PUT request.

Declare the body using standard Python types, thanks to Pydantic.

from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    is_offer: Union[bool, None] = None

# https://127.0.0.1:8000/
@app.get("/")
def read_root():
    return {"Hello": "World"}

# https://127.0.0.1:8000/items/5?q=somequery.
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
    return {"item_name": item.name, "item_id": item_id}

The server should reload automatically (because you added --reload to the uvicorn command above).

FastAPI will:

  • Validate that item_id in the path for GET and PUT requests.
  • Validate that item_id is of type int for GET and PUT requests.
    • If it is not, the client will see a useful, clear error.
  • Check if there is an optional query parameter named q for GET requests.
    • As the q parameter is declared with = None, it is optional.
    • Without the None it would be required (as is the body in the case with PUT).
  • For PUT requests to /items/{item_id}, Read the body as JSON:
    • Check that it has a required attribute name that should be a str.
    • Check that it has a required attribute price that has to be a float.
    • Check that it has an optional attribute is_offer, that should be a bool, if present.
    • All this would also work for deeply nested JSON objects.
  • Convert from and to JSON automatically.

  • Document everything with OpenAPI, that can be used by:
    • Interactive documentation systems.
    • Automatic client code generation systems, for many languages.
  • Provide 2 interactive documentation web interfaces directly.

Interactive API docs upgrade

https://127.0.0.1:8000/docs

  • The interactive API documentation will be automatically updated, including the new body:

Swagger UI

  • “Try it out”: fill the parameters and directly interact with the API:

Swagger UI interaction

  • “Execute”: communicate with your API, send the parameters, get the results and show them on the screen:

Swagger UI interaction


Alternative API docs upgrade

https://127.0.0.1:8000/redoc

  • The alternative documentation will also reflect the new query parameter and body:

ReDoc


command

For example, for an int:

item_id: int

or for a more complex Item model:

item: Item

…and with that single declaration you get:

  • Editor support, including:
    • Completion.
    • Type checks.
  • Validation of data:
    • Automatic and clear errors when the data is invalid.
    • Validation even for deeply nested JSON objects.
  • Conversion of input data: coming from the network to Python data and types. Reading from:
    • JSON.
    • Path parameters.
    • Query parameters.
    • Cookies.
    • Headers.
    • Forms.
    • Files.
  • Conversion of output data: converting from Python data and types to network data (as JSON):
    • Convert Python types (str, int, float, bool, list, etc).
    • datetime objects.
    • UUID objects.
    • Database models.
    • …and many more.
  • Automatic interactive API documentation, including 2 alternative user interfaces:
    • Swagger UI.
    • ReDoc.
This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.