Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions api/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
from fastapi import FastAPI
import logging
import time
from fastapi import FastAPI, Request
from api.routes import templates, forms
from api.errors.handlers import register_exception_handlers

app = FastAPI()
logger = logging.getLogger("fireform.api")

app = FastAPI(title="FireForm API", version="1.0.0")

register_exception_handlers(app)

app.include_router(templates.router)
app.include_router(forms.router)
app.include_router(forms.router)


@app.middleware("http")
async def log_requests(request: Request, call_next):
start = time.time()
response = await call_next(request)
duration_ms = (time.time() - start) * 1000
logger.info(
"%s %s -> %s (%.1fms)",
request.method,
request.url.path,
response.status_code,
duration_ms,
)
return response


@app.get("/health", tags=["health"])
def health_check():
return {"status": "ok"}
18 changes: 9 additions & 9 deletions src/file_manipulator.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os
from src.filler import Filler
from src.llm import LLM
from src.logger import setup_logger
from commonforms import prepare_form

logger = setup_logger(__name__)


class FileManipulator:
def __init__(self):
Expand All @@ -22,26 +25,23 @@ def fill_form(self, user_input: str, fields: list, pdf_form_path: str):
It receives the raw data, runs the PDF filling logic,
and returns the path to the newly created file.
"""
print("[1] Received request from frontend.")
print(f"[2] PDF template path: {pdf_form_path}")
logger.info("Received request from frontend.")
logger.info("PDF template path: %s", pdf_form_path)

if not os.path.exists(pdf_form_path):
print(f"Error: PDF template not found at {pdf_form_path}")
logger.error("PDF template not found at %s", pdf_form_path)
return None # Or raise an exception

print("[3] Starting extraction and PDF filling process...")
logger.info("Starting extraction and PDF filling process...")
try:
self.llm._target_fields = fields
self.llm._transcript_text = user_input
output_name = self.filler.fill_form(pdf_form=pdf_form_path, llm=self.llm)

print("\n----------------------------------")
print("✅ Process Complete.")
print(f"Output saved to: {output_name}")
logger.info("Process complete. Output saved to: %s", output_name)

return output_name

except Exception as e:
print(f"An error occurred during PDF generation: {e}")
# Re-raise the exception so the frontend can handle it
logger.exception("An error occurred during PDF generation: %s", e)
raise e
16 changes: 8 additions & 8 deletions src/llm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import json
import os
import requests
from src.logger import setup_logger

logger = setup_logger(__name__)


class LLM:
Expand Down Expand Up @@ -76,10 +79,9 @@ def main_loop(self):
# print(parsed_response)
self.add_response_to_json(field, parsed_response)

print("----------------------------------")
print("\t[LOG] Resulting JSON created from the input text:")
print(json.dumps(self._json, indent=2))
print("--------- extracted data ---------")
logger.info("Resulting JSON created from the input text:")
logger.info(json.dumps(self._json, indent=2))
logger.debug("--------- extracted data ---------")

return self

Expand Down Expand Up @@ -115,9 +117,7 @@ def handle_plural_values(self, plural_value):
f"Value is not plural, doesn't have ; separator, Value: {plural_value}"
)

print(
f"\t[LOG]: Formating plural values for JSON, [For input {plural_value}]..."
)
logger.debug("Formatting plural values for JSON, input: %s", plural_value)
values = plural_value.split(";")

# Remove trailing leading whitespace
Expand All @@ -127,7 +127,7 @@ def handle_plural_values(self, plural_value):
clean_value = values[current].lstrip()
values[current] = clean_value

print(f"\t[LOG]: Resulting formatted list of values: {values}")
logger.debug("Resulting formatted list of values: %s", values)

return values

Expand Down
26 changes: 26 additions & 0 deletions src/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import logging
import sys

LOG_FORMAT = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s"
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"


def setup_logger(name: str = "fireform", level: int = logging.INFO) -> logging.Logger:
"""
Create and return a configured logger.

Usage:
from src.logger import setup_logger
logger = setup_logger(__name__)
logger.info("Hello from %s", __name__)
"""
logger = logging.getLogger(name)

# Avoid adding duplicate handlers if called more than once
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter(LOG_FORMAT, datefmt=DATE_FORMAT))
logger.addHandler(handler)

logger.setLevel(level)
return logger
28 changes: 15 additions & 13 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os
# from backend import Fill
from typing import Union
from commonforms import prepare_form
from pypdf import PdfReader
from controller import Controller
from logger import setup_logger

logger = setup_logger(__name__)

def input_fields(num_fields: int):
fields = []
Expand All @@ -11,39 +14,38 @@ def input_fields(num_fields: int):
fields.append(field)
return fields

def run_pdf_fill_process(user_input: str, definitions: list, pdf_form_path: Union[str, os.PathLike]):
def run_pdf_fill_process(user_input: str, definitions: Union[dict, list], pdf_form_path: Union[str, os.PathLike]):
"""
This function is called by the frontend server.
It receives the raw data, runs the PDF filling logic,
and returns the path to the newly created file.
"""

print("[1] Received request from frontend.")
print(f"[2] PDF template path: {pdf_form_path}")
logger.info("Received request from frontend.")
logger.info("PDF template path: %s", pdf_form_path)

# Normalize Path/PathLike to a plain string for downstream code
pdf_form_path = os.fspath(pdf_form_path)

if not os.path.exists(pdf_form_path):
print(f"Error: PDF template not found at {pdf_form_path}")
logger.error("PDF template not found at %s", pdf_form_path)
return None # Or raise an exception

print("[3] Starting extraction and PDF filling process...")
logger.info("Starting extraction and PDF filling process...")
try:
output_name = Fill.fill_form(
controller = Controller()
output_name = controller.fill_form(
user_input=user_input,
definitions=definitions,
pdf_form=pdf_form_path
fields=definitions,
pdf_form_path=pdf_form_path
)

print("\n----------------------------------")
print(f"✅ Process Complete.")
print(f"Output saved to: {output_name}")
logger.info("Process complete. Output saved to: %s", output_name)

return output_name

except Exception as e:
print(f"An error occurred during PDF generation: {e}")
logger.exception("An error occurred during PDF generation: %s", e)
# Re-raise the exception so the frontend can handle it
raise e

Expand Down