Home > Net >  FastAPI Query with dataclass not working with alias
FastAPI Query with dataclass not working with alias

Time:06-29

the following FastAPI code is producing unexpected behaviour to me:

import uvicorn
from fastapi import FastAPI, Depends, Query
from typing import Optional
from pydantic.dataclasses import dataclass


app = FastAPI()

@dataclass
class Catz:
    qqq: Optional[str] = Query(None, alias="q")

@app.get("/productz/")
def search_products(query: Catz = Depends(Catz)  ):
    products = [{"name": "Computer"}, {"name": "HDD"}]
    if not query.qqq:
        query.qqq = ""
    return {"query": query, "results": [product for product in products if query.qqq in product["name"]]}


@dataclass
class Cats:
    qqq: Optional[str] = Query(None )

@app.get("/products/")
def search_products(query: Cats = Depends(Cats)  ):
    products = [{"name": "Computer"}, {"name": "HDD"}]
    if not query.qqq:
        query.qqq = ""
    return {"query": query, "results": [product for product in products if query.qqq in product["name"]]}




if __name__ == "__main__":
    uvicorn.run("main:app", port=11978, log_level="info", reload=True)

when I use the service via curl, I get the following outputs:

  1. the expected behaviour with the endpoint /products/ that has no aliases
>> curl -X 'GET'  'http://localhost:11978/products/?qqq=H'  -H 'accept: application/json' -H 'api-version: 1.0' ; echo
{"query":{"qqq":"H"},"results":[{"name":"HDD"}]}
  1. not the expected behaviour with the endpoint /productz/ that has no aliases (regardless of me using a query parameter with its own name or with the alias I have in the code)
>> curl -X 'GET'  'http://localhost:11978/productz/?qqq=H'  -H 'accept: application/json' -H 'api-version: 1.0' ; echo
{"query":{"qqq":""},"results":[{"name":"Computer"},{"name":"HDD"}]}

>> curl -X 'GET'  'http://localhost:11978/productz/?q=H'  -H 'accept: application/json' -H 'api-version: 1.0' ; echo
{"query":{"qqq":""},"results":[{"name":"Computer"},{"name":"HDD"}]}

any idea why that would be?

CodePudding user response:

Do not import dataclass from pydantic.dataclasses - it should be imported from Python's own built-in dataclasses module:

from fastapi import FastAPI, Depends, Query
from fastapi.exceptions import RequestValidationError
from dataclasses import dataclass
from typing import Optional


app = FastAPI()


@dataclass
class Catz:
    qqq: Optional[str] = Query(None, alias="q")

    
@app.get("/productz/")
def search_products(query: Catz = Depends()):
    products = [{"name": "Computer"}, {"name": "HDD"}]
    if not query.qqq:
        query.qqq = ""
    return {"query": query, "results": [product for product in products if query]}

Outputs for /productz?q=123:

{"query":{"qqq":"123"},"results":[{"name":"Computer"},{"name":"HDD"}]}
  • Related