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).