Eric J Ma's Website

How to extract query params from FastAPI

written by Eric J. Ma on 2023-09-17 | tags: til htmx fastapi web development programming frontend backend python requests


Today, I learned how to extract query parameters from FastAPI.

This was within the context of a blog writing assistant that I was making. I used HTM[L/X] for my frontend and FastAPI for the backend. (HTMX rocks, btw, go check it out!) What I wanted to do was to make an HTML <select> tag's <options> depend on another <select>. As it turned out, the HTMX devs already had foreseen many people needing this example and wrote it up as part of the examples.

What intrigued me was that the example used a GET request to the API endpoint. This meant that I would get a URL that looked like this:

http://localhost:8732/get-latest-blog-posts?base_url=https%3A%2F%2Fericmjl.github.io%2Fblog%2F

There were two problems that I didn't know how to solve at first.

First, how do I access the key-value pair base_url=https%3A%2F%2Fericmjl.github.io%2Fblog%2F within Python?

Second, given that I knew how to access the key base_url, how do I get rid of those %3As and %2Fs?

A bit of Googling did the trick.

Access GET request key-value pairs

To access key-value pairs, the API endpoint must accept a Request object. Then, we can access request.query_params, an immutable dictionary, from the request object. The code looks like this:

from fastapi import Request
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/latest-blog-posts", response_class=HTMLResponse)
async def get_latest_blog_posts_api(request: Request): # <-- request: Request is important!
    base_url = request.query_params.get("base_url") # <-- get key-value pairs from .query_params!

I got this answer from this Stackoverflow post.

Properly format the URL

To properly format the URL, we need to use the urllib.parse submodule, part of the Python standard library. The code looks like this:

from urllib.parse import unquote
from fastapi import Request
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/latest-blog-posts", response_class=HTMLResponse)
async def get_latest_blog_posts_api(request: Request):
    base_url = request.query_params.get("base_url")
    base_url = unquote(base_url). # <-- use unquote here!

I got inspiration for this problem from this StackOverflow post.

That was the trickiest part for me here. I hope this piece of information is of use to you as well!


I send out a newsletter with tips and tools for data scientists. Come check it out at Substack.

If you would like to sponsor the coffee that goes into making my posts, please consider GitHub Sponsors!

Finally, I do free 30-minute GenAI strategy calls for organizations who are seeking guidance on how to best leverage this technology. Consider booking a call on Calendly if you're interested!