Skip to content

#217: Path- and Query Parameters in FastAPI

FastAPI offers us two main options to specify what data we want: as part of the path or as query parameters. In this post we expand on our minimalistic example and dig a bit deeper into the basic concepts of FastAPI.

Query parameters

We can append our query parameters to the URL with this pattern:

?valueA=1&valueB=Hello

The query starts with a ? and then follow the variables with their values, separated by a &.

We can add this little method to our main.py file to experiment with the query parameters:

1
2
3
4
5
from fastapi import FastAPI, Request,

@app.get("/echo")
async def echo(request: Request):
    return request.query_params

If we access the URL http://localhost:8000/echo?a=1&b=Hello, we should see something like this:

FastAPI turns our parameters into a key/value pair and encodes it as JSON.

You can play with it and add more variables and you should get immediate feedback.

A more explicit usage of query parameters

If we want to create a small calculation function that creates the sum of the variables a, b, and c, we can write the function like this:

1
2
3
@app.get("/calculator")
async def calculate(a, b, c):
    return a + b + c

If we now go to http://localhost:8000/calculator?a=1&b=2&c=3, we get a result back that may not be what we expected:

We get the string 123 back instead of the result of the addition of 1 + 2 + 3.

The result is 123, then by default everything we get into FastAPI is a string. We could go and convert the values like this:

1
2
3
4
5
6
@app.get("/calculator")
async def calculate(a, b, c):
    a = int(a)
    b = int(b)
    c = int(c)
    return {"value": a + b + c}

However, while that works, it is much easier to use type hints:

1
2
3
@app.get("/calculator")
async def calculate(a: int, b: int, c: int):
    return {"value": a + b + c}

Whatever you choose, if you go back to the API, you now should get the correct result:

We now get 6 back, what is the value for 1 + 2 + 3.

Path parameters

The other option we can use to influence the results we get is a path parameter. For that we define our path and add {} around the parameters, like we would with f-strings:

1
2
3
@app.get("/weather/{city}")
async def weather(city):
    return {"city": city}

We can now call our weather endpoint with the name of the city or a postal code, then FastAPI again interprets the parameter as a string:

We get back a JSON response that has our input as a string, even when we enter a number.

We get back a JSON response that has our input as a string when we enter a string

If we want our parameter to be something else than a string, we need to specify it:

1
2
3
@app.get("/weather/{city}")
async def weather(city: int):
    return {"city": city}

If we run it now with a string while we expect an integer, we get an error: Since abc is not a number, we get an error that tells us about the exception at the conversion to an int.

While type hints for python are hints, with FastAPI those hints are turned into checks and the parameters are validated against them. That gives us an input check for free.

Next

Type hints allow us to get the data that we want from the path and query parameters. If we are explicit on what we expect, we do not need to make the conversation by ourselves. Instead, FastAPI delegates this task to Pydantic and throws errors if the types do not match.

Next week we try something new and send data to FastAPI.