10

I spent last month learning Flask, and am now moving on to Pyramid and FastAPI. One of the requirements for my application is to get all the query parameters in a dictionary (there are multiple combinations, and I can assume all keys are unique and have a single value)

In Flask, for request like GET /?foo=1&bar=2 I can get the foo and bar parameters from a dictionary like this:

from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def root():
     if 'foo' in request.args:
         return f"foo was provided: {request.args['foo']}", 200
     else:
         return "I need your foo, fool!", 400

I cannot figure out how to do the same easily in FastAPI / Starlette. Best solution I've come up with is to manually build the dictionary by splitting up request.query_params:

from fastapi import FastAPI, Request
app = FastAPI()

@app.get("/")
@app.get("/{path:path}")
def root(path, request: Request):

    request_args = {}
    if request.query_params:
        for _ in str(request.query_params).split("&"):
            [key, value] = _.split("=")
            request_args[key] = str(value)

It certainly seems there should be an easier way?

2
  • 1
    Does this answer your question? URL query parameters to dict python Commented May 4, 2021 at 23:20
  • Why do you have two @app.get and why is your path {path:path}? Commented May 5, 2021 at 2:44

2 Answers 2

20

This is simple, just isn't documented very well. The Request class has an attribute called query_params. It's a mulitdict, but can easily be converted to a standard dictionary via the dict() function:

def root(path, req: Request):
    request_args = dict(req.query_params)
Sign up to request clarification or add additional context in comments.

2 Comments

Indeed, req.query_params is perhaps the easiest way to get it.
Be careful with blindly casting request.query_params to a dict. If you have, as the HTTP spec allows, multiple query parameters with the same key, it will only return the first key/value pair. Thus, app?id=foo&id=bar will only give you a dict with: dict(req.query_params) => { 'id': 'foo' } It's much safer to iterate through them, or re-parse as in stackoverflow.com/a/73831142/1183198
0

And to access any received JSON payload as dictionary (Flask-style, without the need to pre-define all dictionary keys), use the type hint Dict:

from fastapi import FastAPI
from typing import Any, Dict, List, Union

app = FastAPI()

@app.get("/")
async def root(path, request_dict: Union[List,Dict,Any]=None):
    return request_dict # a dict

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.