skip to content
Jakub Szafran

Learning FastAPI (#1)

/ 2 min read

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