Skip to content

✏ Allow integer constraints on openapi schema#9453

Closed
alesanfra wants to merge 1 commit into
fastapi:masterfrom
alesanfra:allow-integer-constraints-on-openapi-schema
Closed

✏ Allow integer constraints on openapi schema#9453
alesanfra wants to merge 1 commit into
fastapi:masterfrom
alesanfra:allow-integer-constraints-on-openapi-schema

Conversation

@alesanfra
Copy link
Copy Markdown

Hi everyone,

I'm opening this PR because I've recently found a weird behavior when dealing with constrained integers. Consider the following example:

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/item")
async def get_items(limit: Annotated[int, Query(ge=1, le=1000)] = 100):
    return {"message": f"Got items with limit {limit}"}

It will produce the following schema (not relevant sections elided):

{
  "paths": {
    "/item": {
      "get": {
        "summary": "Get Items",
        "operationId": "get_items_item_get",
        "parameters": [
          {
            "required": false,
            "schema": {
              "title": "Limit",
              "maximum": 1000.0,
              "minimum": 1.0,
              "type": "integer",
              "default": 100
            },
            "name": "limit",
            "in": "query"
          }
        ],
  },
}

As you can see even though ge=1 and le=1000 were defined as integers, the internal pydantic model coherces them to floats ("maximum": 1000.0 and "minimum": 1.0). This is a problem when using some security tools like 42 Crunch because the mismatch between type and values is reported as a possible vulnerability.

With this PR fastapi will keep the constraints as defined in the source code leveraging the smart union feature of pydantic, therefore in example above fastapi will produce the following schema:

{
  "paths": {
    "/item": {
      "get": {
        "summary": "Get Items",
        "operationId": "get_items_item_get",
        "parameters": [
          {
            "required": false,
            "schema": {
              "title": "Limit",
              "maximum": 1000,
              "minimum": 1,
              "type": "integer",
              "default": 100
            },
            "name": "limit",
            "in": "query"
          }
        ],
  },
}

@alesanfra alesanfra changed the title Allow integer constraints on openapi schema ✏ Allow integer constraints on openapi schema Apr 27, 2023
Copy link
Copy Markdown

@leotac leotac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, much needed.

Copy link
Copy Markdown

@matheushenrique98 matheushenrique98 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are changing 5 fields but:
1 - Not all fields you are changing have test (multipleOf)
2 - The change occurs in 5 fields, but you have not adjusted all the tests who use these fields

About point 2: the type number could be more representative, because can be (int or float), and is a pattern used in other tests for the same context

@tiangolo tiangolo added p3 feature New feature or request labels Jan 14, 2024
@YuriiMotov
Copy link
Copy Markdown
Member

Duplicate: #9517

This will convert values 100.0 to just 0 in schema.

@tiangolo
Copy link
Copy Markdown
Member

I would think the behavior from that tool is a bit strange. In JSON, there's no distinction between floats and integers, there's only one type "number". It's weird (and probably wrong) that a tool would flag and interpret different types of numbers. 🤔

Do you have a specific use case that needs this other than complying with what the tool is telling you?

@github-actions
Copy link
Copy Markdown
Contributor

As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.

@github-actions github-actions Bot closed this Aug 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request p3 waiting

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants