Skip to content

having problems with dict used in get requests #10404

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
HamzaYslmn opened this issue Apr 7, 2025 · 4 comments
Open

having problems with dict used in get requests #10404

HamzaYslmn opened this issue Apr 7, 2025 · 4 comments

Comments

@HamzaYslmn
Copy link

HamzaYslmn commented Apr 7, 2025

Q&A (please complete the following information)

  • OS: Windows 11
  • Browser: Chrome
  • Version: 134.0.6998.179
  • Method of installation: pip with fastapi
  • Swagger-UI version: 3.10.0
  • Swagger/OpenAPI version: OAS 3.1

Describe the bug you're encountering

having problems with dicts used in get requests

To reproduce...

Steps to reproduce the behavior:
write pydantic + fastapi code

import json
from typing import Optional, List
from fastapi import FastAPI, APIRouter, Query, Request, Response
from fastapi.responses import JSONResponse
from pydantic import BaseModel, Field
from pydantic import ConfigDict, field_validator

app = FastAPI()

class AdBase(BaseModel):
    id: str
    title: str
    owner: Optional[str] = None
    doc_id: Optional[List[str]] = None

class AdGetRequest(AdBase):
    page: int = Field(0, gt=-1)
    filters: Optional[dict] = Field(
        default=None,
        example={"location": ["Ankara", "İstanbul"], "position_title": "Yazılım"}
    )
    owner: Optional[str] = Field(None)
    doc_id: Optional[List[str]] = Field(None)
    
    model_config = ConfigDict(extra="ignore")
    
    @field_validator("filters", mode="before")
    def parse_filters(cls, value):
        if value is None:
            return value
        if isinstance(value, str):
            try:
                return json.loads(value)
            except json.JSONDecodeError:
                raise ValueError("filters must be a valid JSON string representing a dictionary")
        return value

@app.get("/management")
async def get_ads(request: Request, ad: AdGetRequest = Query(...)):
    print(f"Received Filters: {ad.filters}")
    
    return JSONResponse(content={"message": "Filters received","filters": ad.filters})

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Expected behavior

url should be:
localhost:8002/DB/ad/management?page=0&filters={"location": ["Ankara", "İstanbul"], "position_title": "Yazılım"}

not:
localhost:8002/DB/ad/management?page=0&location=["Ankara","İstanbul"]&position_title=Yazılım

filters missing.

Screenshots

Image

Image

The request is wrong, it's not usable.

@char0n
Copy link
Member

char0n commented Apr 17, 2025

Hi @HamzaYslmn,

We don't really know what API Description pydantic + fastapi code generates. If you could provide an actual generated API Description in JSON or YAML format, we would be able to determine if SwaggerUI is doing something problematic.

Thanks!

@HamzaYslmn
Copy link
Author

HamzaYslmn commented Apr 17, 2025

actual generated API Description in JSON

HERE:

{
  "openapi": "3.1.0",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "paths": {
    "/management": {
      "get": {
        "summary": "Get Ads",
        "operationId": "get_ads_management_get",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id"
            }
          },
          {
            "name": "title",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Title"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Owner"
            }
          },
          {
            "name": "doc_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "title": "Doc Id"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": -1,
              "default": 0,
              "title": "Page"
            }
          },
          {
            "name": "filters",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "object",
                  "additionalProperties": true
                },
                {
                  "type": "null"
                }
              ],
              "example": {
                "location": [
                  "Ankara",
                  "İstanbul"
                ],
                "position_title": "Yazılım"
              },
              "title": "Filters"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {

                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  }
}

http://localhost:8000/openapi.json

@HamzaYslmn
Copy link
Author

HamzaYslmn commented Apr 17, 2025

YAML

openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
paths:
  /management:
    get:
      summary: Get Ads
      operationId: get_ads_management_get
      parameters:
      - name: id
        in: query
        required: true
        schema:
          type: string
          title: Id
      - name: title
        in: query
        required: true
        schema:
          type: string
          title: Title
      - name: owner
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Owner
      - name: doc_id
        in: query
        required: false
        schema:
          anyOf:
          - type: array
            items:
              type: string
          - type: 'null'
          title: Doc Id
      - name: page
        in: query
        required: false
        schema:
          type: integer
          exclusiveMinimum: -1
          default: 0
          title: Page
      - name: filters
        in: query
        required: false
        schema:
          anyOf:
          - type: object
            additionalProperties: true
          - type: 'null'
          example:
            location:
            - Ankara
            - "\u0130stanbul"
            position_title: "Yaz\u0131l\u0131m"
          title: Filters
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants