From 923c119f6f0f92fdf8356429fa021fb368cf8983 Mon Sep 17 00:00:00 2001 From: Lochit Vinay Date: Mon, 30 Mar 2026 00:58:50 +0530 Subject: [PATCH 1/4] Optimize fill_form by removing redundant get_template calls --- api/routes/forms.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/api/routes/forms.py b/api/routes/forms.py index f3430ed..b318520 100644 --- a/api/routes/forms.py +++ b/api/routes/forms.py @@ -11,13 +11,17 @@ @router.post("/fill", response_model=FormFillResponse) def fill_form(form: FormFill, db: Session = Depends(get_db)): - if not get_template(db, form.template_id): - raise AppError("Template not found", status_code=404) - fetched_template = get_template(db, form.template_id) + if not fetched_template: + raise AppError("Template not found", status_code=404) + controller = Controller() - path = controller.fill_form(user_input=form.input_text, fields=fetched_template.fields, pdf_form_path=fetched_template.pdf_path) + path = controller.fill_form( + user_input=form.input_text, + fields=fetched_template.fields, + pdf_form_path=fetched_template.pdf_path + ) submission = FormSubmission(**form.model_dump(), output_pdf_path=path) return create_form(db, submission) From 12697bfdf2231bcbe8745b6cbbb45a189db60a5f Mon Sep 17 00:00:00 2001 From: Lochit Vinay Date: Mon, 30 Mar 2026 01:17:27 +0530 Subject: [PATCH 2/4] validate-input-text --- api/routes/forms.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/routes/forms.py b/api/routes/forms.py index b318520..30ce798 100644 --- a/api/routes/forms.py +++ b/api/routes/forms.py @@ -11,18 +11,17 @@ @router.post("/fill", response_model=FormFillResponse) def fill_form(form: FormFill, db: Session = Depends(get_db)): + if not form.input_text.strip(): + raise AppError("Input text cannot be empty", status_code=400) fetched_template = get_template(db, form.template_id) - if not fetched_template: raise AppError("Template not found", status_code=404) - controller = Controller() path = controller.fill_form( user_input=form.input_text, fields=fetched_template.fields, pdf_form_path=fetched_template.pdf_path ) - submission = FormSubmission(**form.model_dump(), output_pdf_path=path) return create_form(db, submission) From 2f479ca6329851486348c39cf3aa4aba131bdbd8 Mon Sep 17 00:00:00 2001 From: Lochit Vinay Date: Mon, 30 Mar 2026 02:31:11 +0530 Subject: [PATCH 3/4] refactor: move input_text validation to schema level --- api/routes/forms.py | 2 -- api/schemas/forms.py | 8 +++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/routes/forms.py b/api/routes/forms.py index 30ce798..5e18013 100644 --- a/api/routes/forms.py +++ b/api/routes/forms.py @@ -11,8 +11,6 @@ @router.post("/fill", response_model=FormFillResponse) def fill_form(form: FormFill, db: Session = Depends(get_db)): - if not form.input_text.strip(): - raise AppError("Input text cannot be empty", status_code=400) fetched_template = get_template(db, form.template_id) if not fetched_template: raise AppError("Template not found", status_code=404) diff --git a/api/schemas/forms.py b/api/schemas/forms.py index 3cce650..bf6957e 100644 --- a/api/schemas/forms.py +++ b/api/schemas/forms.py @@ -1,9 +1,15 @@ -from pydantic import BaseModel +from pydantic import BaseModel, field_validator class FormFill(BaseModel): template_id: int input_text: str + @field_validator("input_text") + def validate_input_text(cls, value): + if not value or not value.strip(): + raise ValueError("Input text cannot be empty") + return value + class FormFillResponse(BaseModel): id: int From 1138766bf3ae89591eeb2ab6981f4483f58d68bb Mon Sep 17 00:00:00 2001 From: Lochit Vinay Date: Tue, 31 Mar 2026 03:59:38 +0530 Subject: [PATCH 4/4] Add centralized error handling using FastAPI exception handlers --- api/main.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/api/main.py b/api/main.py index d0b8c79..cec8000 100644 --- a/api/main.py +++ b/api/main.py @@ -1,7 +1,56 @@ from fastapi import FastAPI +from api.routes import templates, forms +from fastapi import Request +from fastapi.responses import JSONResponse +from fastapi.exceptions import RequestValidationError +from starlette.exceptions import HTTPException as StarletteHTTPException + from api.routes import templates, forms app = FastAPI() + +@app.exception_handler(StarletteHTTPException) +async def http_exception_handler(request: Request, exc: StarletteHTTPException): + return JSONResponse( + status_code=exc.status_code, + content={ + "error": { + "type": "HTTPException", + "message": exc.detail, + "details": {} + } + }, + ) + + +@app.exception_handler(RequestValidationError) +async def validation_exception_handler(request: Request, exc: RequestValidationError): + return JSONResponse( + status_code=422, + content={ + "error": { + "type": "ValidationError", + "message": "Invalid request data", + "details": exc.errors(), + } + }, + ) + + +@app.exception_handler(Exception) +async def general_exception_handler(request: Request, exc: Exception): + return JSONResponse( + status_code=500, + content={ + "error": { + "type": "InternalServerError", + "message": str(exc), + "details": {} + } + }, + ) + + app.include_router(templates.router) app.include_router(forms.router) \ No newline at end of file