Pozzo90
Pozzo90

Reputation: 173

FastAPI - Set response_model_exclude when calling API

In FastAPI I have a situation similar to this:

models.py

class MachineGroups(Base):
    __tablename__ = 'MachineGroups'

    MachineGroupsId = Column(NVARCHAR(25), primary_key=True)
    Description = Column(NVARCHAR(255))


class Machines(Base):
    __tablename__ = 'Machines'

    MachinesId = Column(NVARCHAR(50), primary_key=True)
    Description = Column(NVARCHAR(255))
    MachineGroupsId = Column(NVARCHAR(25), ForeignKey("MachineGroups.MachineGroupsId", ondelete="SET NULL"), nullable=True)

    group = relationship("MachineGroups")

schemas.py

class MachineGroups(BaseModel):
    MachineGroupsId: str
    Description: str

    class Config:
        orm_mode = True


class Machines(BaseModel):
    MachinesId: str
    Description: str
    MachineGroupsId: str = None
    group: Optional[MachineGroups] = None

    class Config:
        orm_mode = True

In the controller I have a function create like this:

controller.py

@app.get(
    "/machines",
    response_model=List[machine_schemas.Machines],
    response_model_exclude={'group'}
)
def get_machines(db: Session = Depends(get_db)):
    return db.query(machine_models.Machines).all()

I would like to be able to set the response_model_exclude field value in the decorator directly from the API call. In practice I would like to have a query parameter on the function that allows me allows me to get the foreign key information or not.

To avoid having this situation:

@app.get(
    "/machines",
    response_model=List[machine_schemas.Machines],
    response_model_exclude={'group'}
)
def get_machines(db: Session = Depends(get_db)):
    return db.query(machine_models.Machines).all()

@app.get(
    "/machines/all",
    response_model=List[machine_schemas.Machines],
)
def get_machines_all(db: Session = Depends(get_db)):
    return db.query(machine_models.Machines).all()

Is it possible to achieve this?

Thank you.

Upvotes: 2

Views: 2077

Answers (1)

Pozzo90
Pozzo90

Reputation: 173

I solved the problem by creating a custom JSONResponse and using the jsonable_encoder function to exclude the foreign key fields.

@app.get(
    "/machines/all",
    response_model=List[machine_schemas.Machines],
)
def get_machines_all(get_foreign_keys: bool = True, db: Session = Depends(get_db)):
    machines = db.query(machine_models.Machines).all()
    if get_foreign_keys:
        return machines
    else:
        return JSONResponse(jsonable_encoder(machines, exclude={'group'}))

Upvotes: 4

Related Questions