I decided to learn FastAPI and this post (first post from a series) will contain my notes from learning process.
What is FastAPI?
Quote from FastAPI official website:
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.8+ based on standard Python type hints.
FastAPI installation
Easy stuff - just use pip install fastapi[uvicorn]
. This will install FastAPI along with uvicorn
as the ASGI server.
Basic application
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
Above hello world
example defines a simple API with just one route - ”/” for a GET method.
If you’d like to use other HTTP methods (i.e. POST, PUT, PATCH), they are all available as decorators within app
object.
Type below command to start the program:
uvicorn main:app
This starts uvicorn server that serves our API. By default, application will be started on port 8000, but in can be easily adjusted:
uvicorn main:app --port 9000
main
is the name of the module that our application lives in (main.py
file) and app
is the name of the FastAPI instance. If we decide to name module/app object differently, we should adjust the uvicorn
arguments accordingly.
Another useful flag is --reload
- it will reload our app after there’s been any changes in the code.
Once application is started, running
curl localhost:8000
should return our “hello world” message.
Path parameters
Adding path parameter is very simple - we include a name of the parameter inside curly brackets in the path and include it in our function parameters:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/{name}")
async def root(name: str):
return {"message": f"Hello World, {name}"}
Note the : str
type hint - it will be used by Pydantic
when doing path validation and it’ll try to coerce the type into the one from the hint. Path parameter is a string by default so there’s no type casting in this case. However, if we’ve added a new endpoint that would’ve expected an integer and would return its value increased by one, then we could see that in action:
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/{name}")
async def root(name: str):
return {"message": f"Hello World, {name}"}
@app.get("/increase_by_one/{number}")
async def increase_by_one(number: int):
res = number + 1
return {"number": res}
curl localhost:8000/increase_by_one/1
# returns {"number":2}
curl localhost:8000/increase_by_one/foo
# {"detail":[{"type":"int_parsing","loc":["path","number"],
# "msg":"Input should be a valid integer, unable to parse string as an integer","input":"foo",
# "url":"https://errors.pydantic.dev/2.6/v/int_parsing"}]}
(12/52) This is a 12th post from my blogging challenge (publishing 52 posts in 2024).