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

from fastapi import FastAPI

app = FastAPI()

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 ( 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:

from fastapi import FastAPI

app = FastAPI()

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:

from fastapi import FastAPI

app = FastAPI()

async def root(name: str):
    return {"message": f"Hello World, {name}"}

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":""}]}

(12/52) This is a 12th post from my blogging challenge (publishing 52 posts in 2024).