NetworkSec - Fast API
ref:
- https://github.com/tiangolo/fastapi/blob/master/README.md
- https://fastapi.tiangolo.com/tutorial/
NetworkSec - Fast API
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 filemain.py
(the Python “module”).app
: the object created inside ofmain.py
with the lineapp = 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 parameteritem_id
that should be anint
. - The path
/items/{item_id}
has an optionalstr
query parameterq
.
API docs
Interactive API docs
https://127.0.0.1:8000/docs
- automatic interactive API documentation (provided by Swagger UI):
Alternative API docs
https://127.0.0.1:8000/redoc
- alternative automatic documentation (provided by 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 forGET
andPUT
requests. - Validate that
item_id
is of typeint
forGET
andPUT
requests.- If it is not, the client will see a useful, clear error.
- Check if there is an optional query parameter named
q
forGET
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 withPUT
).
- As the
- For
PUT
requests to/items/{item_id}
, Read the body as JSON:- Check that it has a required attribute
name
that should be astr
. - Check that it has a required attribute
price
that has to be afloat
. - Check that it has an optional attribute
is_offer
, that should be abool
, if present. - All this would also work for deeply nested JSON objects.
- Check that it has a required attribute
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:
- “Try it out”: fill the parameters and directly interact with the API:
- “Execute”: communicate with your API, send the parameters, get the results and show them on the screen:
Alternative API docs upgrade
https://127.0.0.1:8000/redoc
- The alternative documentation will also reflect the new query parameter and body:
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.
- Convert Python types (
- Automatic interactive API documentation, including 2 alternative user interfaces:
- Swagger UI.
- ReDoc.
Comments powered by Disqus.