Lostsoul
Lostsoul

Reputation: 26067

In FastAPI can I make a input optional?

To make my code manageable I am using classes to define the inputs into my endpoints. Here is an example:

class BaseRequest(BaseModel):
    name: str

class details(BaseRequest):
    age: int
    gender: str

@router.put('/people')
async def add_people(body: details):
    try:
        name, age, gender = body.name.upper(), body.age, body.gender

        # insert the person
        res = await main_db_instance.fetch_rows(f"INSERT INTO myDB.people (name, age, gender)"
                                                f" VALUES ('{name}', '{age}', '{gender}')"
                                                f" RETURNING *")
        return JSONResponse(jsonable_encoder(res), status_code=200)

    except Exception as exp:
        logger.exception(f'Exception while inserting the person: {exp}')
        return JSONResponse(status_code=500, content="Error inserting the person")

I would send this data: {"name": "Bob" , "age": 25 , "gender": "Male" } This works right now but everything is mandatory. Here are my questions:

  1. What if gender is optional? or do I want to add a new data point to test without breaking all existing apps making API calls?
  2. If something is optional, what do I do with the DB inserts? Would I need to create a variation of all possible combinations? Or can I insert null values so I just have one insert statement?

Upvotes: 1

Views: 761

Answers (1)

AKX
AKX

Reputation: 169407

Make the types for those fields Optional[...] and give them default values:

class BaseRequest(BaseModel):
    name: str

class details(BaseRequest):
    age: int
    gender: Optional[str] = None

If the gender field is nullable in the database, you can then just do

res = await main_db_instance.fetch_rows(
    "INSERT INTO myDB.people (name, age, gender) "
    "VALUES (%s, %s, %s) RETURNING *",
    (name, age, gender),
)
return JSONResponse(jsonable_encoder(res), status_code=200)

(see use of parametrization to avoid the SQL injection attacks your code is currently vulnerable to – not sure if your main_db_instance supports that, but it really should)

Upvotes: 2

Related Questions