question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] How to define empty query parameters as missing?

See original GitHub issue

First check

  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.

Description

How can I make empty query parameters to be interpreted as missing value (and therefore default value is used) instead of empty string? For example, if I were to use optional int query param, empty string would find its way as value being passed and validation error for invalid int would be raised.

Additional context

Sample code:

from fastapi import APIRouter

router = APIRouter()


@router.get("/test/", tags=["test"])
def test(q: int = None):
    return {"q": q}

GET http://URL/test/?q=

or

GET http://URL/test/?q

results in:

{
  "detail": [
    {
      "loc": [
        "query",
        "q"
      ],
      "msg": "value is not a valid integer",
      "type": "type_error.integer"
    }
  ]
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:7
  • Comments:9 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
Dectinccommented, Jul 9, 2020

@tiangolo thanks for the reply!

Actually, I’m not sure which approach is better either, but I think that there should be a way to handle this in both use-cases. Since use-case “empty query parameter (?q or ?q=) has value of empty string” is the default one, I am curios about how to achieve “empty query parameter (?q or ?q=) is missing (e.g. None & default value is used)”?

Appreciate your help, thanks!

Same requirements here, and handled with a middleware at last.

We can just drop those fields with blank values, which are empty strings or strings contain only whitespaces, default values will be handled by Query models.

# Add blank query parameters processing middleware
@app.middleware('http')
async def drop_blank_query_params_middleware(request: Request, call_next):
    _scope = request.scope
    if request.method != 'GET':
        return await call_next(request)
    if not _scope or not _scope.get('query_string'):
        return await call_next(request)

    def _process_query_params(query_params):
        _query_params = QueryParams(query_params)

        from urllib.parse import urlencode
        return urlencode([
            # using `_query_params.items()` will mistakenly process list parameters
            (k, v) for k, v in _query_params._list if v and v.strip()  # noqa
        ])

    _scope['query_string'] = _process_query_params(_scope['query_string']).encode('latin-1')
    return await call_next(Request(_scope, request.receive, request._send))  # noqa

However, as @tiangolo commented, this approach may not be correct, maybe it’s not recommended. 😃

2reactions
mrchicommented, Jun 7, 2022

@tiangolo thanks for the reply! Actually, I’m not sure which approach is better either, but I think that there should be a way to handle this in both use-cases. Since use-case “empty query parameter (?q or ?q=) has value of empty string” is the default one, I am curios about how to achieve “empty query parameter (?q or ?q=) is missing (e.g. None & default value is used)”? Appreciate your help, thanks!

Same requirements here, and handled with a middleware at last. We can just drop those fields with blank values, which are empty strings or strings contain only whitespaces, default values will be handled by Query models.

# Add blank query parameters processing middleware
@app.middleware('http')
async def drop_blank_query_params_middleware(request: Request, call_next):
    _scope = request.scope
    if request.method != 'GET':
        return await call_next(request)
    if not _scope or not _scope.get('query_string'):
        return await call_next(request)

    def _process_query_params(query_params):
        _query_params = QueryParams(query_params)

        from urllib.parse import urlencode
        return urlencode([
            # using `_query_params.items()` will mistakenly process list parameters
            (k, v) for k, v in _query_params._list if v and v.strip()  # noqa
        ])

    _scope['query_string'] = _process_query_params(_scope['query_string']).encode('latin-1')
    return await call_next(Request(_scope, request.receive, request._send))  # noqa

However, as @tiangolo commented, this approach may not be correct, maybe it’s not recommended. 😃

Note that QueryParams comes from starlette.datastructures. For it to work add from starlette.datastructures import QueryParams.

Works like a charm, btw. Thanks!

Thanks for the answer. I met this issue when I use amis with FastAPI.

According to above code snippet, I make a litte optimization to simplify code.

from typing import Callable
from urllib.parse import parse_qsl, urlencode

from fastapi import Request

@app.middleware("http")
async def filter_blank_query_params(request: Request, call_next: Callable):
    scope = request.scope
    if scope and scope.get("query_string"):
        filtered_query_params = parse_qsl(
            qs=scope["query_string"].decode("latin-1"),
            keep_blank_values=False,
        )
        scope["query_string"] = urlencode(filtered_query_params).encode("latin-1")
    return await call_next(request)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Checking for null and missing query string parameters in ...
I want to be able to distinguish between existing query string parameters set to null, and missing parameters. So the parts of the...
Read more >
How To Send A Request With Empty Query Parameters?
How To Send A Request With Empty Query Parameters? To mark a parameter as required, you need to go to the Request editor...
Read more >
Solved: How to raise a fault on missing or empty request p...
Hi,. I have an endpoint which needs an 'email' parameter and if the email parameter is missing or empty it need to raise...
Read more >
How to overcome missing query parameters in Databricks ...
I'm trying to build up my first dashboard based on Dataabricks SQL. As far as I can see if you define a query...
Read more >
Query string query | Elasticsearch Guide [8.5]
The query string “mini-language” is used by the Query string and by the q query ... and would not match if the field...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found