Home > Blockchain >  Is there any Query constraint exception on fastapi?
Is there any Query constraint exception on fastapi?

Time:10-12

I'm using fastapi 0.70.0, with python 3.8.10.

I was expecting Query to raise RequestValidationError (or something) when querying /items/0 (because 0 is not gte=1)

I took the fastapi sample code, adding Query param constraint (item 0 is not allowed):

from fastapi import FastAPI, HTTPException, Query
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse

app = FastAPI()

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return PlainTextResponse(str(exc), status_code=400)

@app.get("/items/{item_id}")
async def read_item(item_id: int = Query(default=1, gte=1)):             # /!\ Important line.
    if item_id == 3:
        raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
    return {"item_id": item_id}

Few queries:

item 1: A valid query:

curl http://127.0.0.1:8000/items/1             # Return item_id as expected.
{"item_id": 1}

item a: Exception, "a" is not an integer:

curl http://127.0.0.1:8000/items/a             # RequestValidationError as expected

item 0: No Exception raised, 0 not allowed.

curl http://127.0.0.1:8000/items/0             # ô_O, no exception, 0 is not gte=1 
{"item_id": 0}

So, if no exception raised, Query constraints are not available yet ?

CodePudding user response:

There is no such key as gte. You need to use:

  • gt - greater than, or
  • ge - greater than or equal

Number validations

@app.get("/items/{item_id}")
async def read_item(item_id: int = Query(default=1, ge=1)):             # /!\ Important line.
    if item_id == 3:
        raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
    return {"item_id": item_id}

CodePudding user response:

The parameter is defined as ge: Optional[float] = None,, not gte:

from fastapi import FastAPI, Query

app = FastAPI()

@app.get('/')
async def get_magic(a: int = Query(default=1, ge=1)):
    return {'foo': a}
    

if __name__ == '__main__':
    import uvicorn

    uvicorn.run('foo:app', port=4008, reload=True)

Calling this with ?a=0 gives the expected error:

{"detail":[{"loc":["query","a"],"msg":"ensure this value is greater than or equal to 1","type":"value_error.number.not_ge","ctx":{"limit_value":1}}]}
  • Related