I'm working on a webserver built with FastAPI version 0.111.0 and SQLModel version 0.0.18.
When I'm calling the POST endpoint with partial data or with keys I don't specify in my class, it doesn't trigger the unprocessable entity or bad request error. I'm using the method POST only for inserting data and not updating it. For update an entity, I use a separate PUT request.
Here's my model:
from sqlmodel import SQLModel, Field
class Job(SQLModel, table=True):
job_id: int = Field(primary_key=True)
title: str
start_time: str
end_time: str | None = None
pipeline_id: int = Field(foreign_key="pipeline.pipeline_id")
prj_path: str
branch_tag: str
user: str
status: str
log: str = ""
result: str = ""
and here's the controller:
from fastapi import APIRouter
from models.job import Job
job_router = APIRouter(prefix="/job", tags=["Jobs"])
@job_router.post("/", status_code=201, response_model=Job)
async def add_job(job: Job):
job = await c.insert_job(job)
return job
The c.insert_job(job)
is where I'm saving the object in the database and the job_router
is importend in the main file with the FastAPI app:
from fastapi import FastAPI
from routers.job import job_router
app = FastAPI()
app.include_router(job_router)
Even if the auto-created documentation tells me that there are some required fields as shown here:
job class in swagger
if I'm sending a request with a body like { "job_id": 0 }
or even { "job_id": 0, "test": "test" }
, it passes without triggering anything like shown in the next image (here I return the partial object I get instead of adding it to the database because it would throw an error on fields without the default value):
returned object
Use this model for response validation
from pydantic import BaseModel
from typing import Optional
class JobRead(BaseModel):
job_id: int
title: str
start_time: str
end_time: Optional[str] = Field(default=None)
pipeline_id: int
prj_path: str
branch_tag: str
user: str
status: str
log: Optional[str] = Field(default="")
result: Optional[str] = Field(default="")
And you can do use Pydantic validation about validation https://docs.pydantic.dev/latest/#why-use-pydantic
or use Depends() with Pydantic model
from fastapi import APIRouter
from models.job import Job
job_router = APIRouter(prefix="/job", tags=["Jobs"])
@job_router.post("/", status_code=201, response_model=Job)
async def add_job(job: Job = Depends()):
job = await c.insert_job(job)
return job
about Depends https://fastapi.tiangolo.com/tutorial/dependencies/