feat: Implement core application structure, AI extraction, persistence, and Telegram bot modules with updated configuration and dependencies.

This commit is contained in:
Marco Gallegos
2025-12-18 12:15:04 -06:00
parent 7276e480b0
commit 899482580e
45 changed files with 1157 additions and 225 deletions

84
app/main.py Normal file
View File

@@ -0,0 +1,84 @@
"""
Application entry point.
Initializes the FastAPI application, sets up logging, database,
and defines the main API endpoints.
"""
import logging
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
# It's crucial to set up the config before other imports
from app.config import config
# Now, set up logging based on the config
logging.basicConfig(level=config.LOG_LEVEL.upper())
logger = logging.getLogger(__name__)
# Import other components
from app.schema.base import RawInput
from app.router import process_expense_input
from app.persistence import repositories, db
# Create database tables on startup
# This is simple, but for production, you'd use migrations (e.g., Alembic)
repositories.create_tables()
# Initialize the FastAPI app
app = FastAPI(
title="Telegram Expenses Bot API",
description="Processes and manages expense data from various sources.",
version="1.0.0"
)
@app.on_event("startup")
async def startup_event():
logger.info("Application startup complete.")
logger.info(f"Log level is set to: {config.LOG_LEVEL.upper()}")
@app.get("/", tags=["Status"])
async def root():
"""Health check endpoint."""
return {"message": "Telegram Expenses Bot API is running."}
@app.post("/webhook/telegram", tags=["Webhooks"])
async def process_telegram_update(request: dict):
"""
This endpoint would receive updates directly from a Telegram webhook.
It needs to be implemented to parse the Telegram Update object and
convert it into our internal RawInput model.
"""
logger.info(f"Received Telegram update: {request}")
# TODO: Implement a parser for the Telegram Update object.
# For now, this is a placeholder.
return {"status": "received", "message": "Telegram webhook handler not fully implemented."}
@app.post("/process-expense", tags=["Processing"])
async def process_expense(raw_input: RawInput, db_session: Session = Depends(db.get_db)):
"""
Receives raw expense data, processes it through the full pipeline,
and returns the result.
"""
logger.info(f"Received raw input for processing: {raw_input.dict()}")
try:
result = process_expense_input(db=db_session, raw_input=raw_input)
if result:
return {"status": "success", "expense_id": result.id}
else:
# This could happen if confidence is low or an error occurred
raise HTTPException(
status_code=400,
detail="Failed to process expense. It may require manual review or had invalid data."
)
except ValueError as e:
logger.error(f"Validation error: {e}")
raise HTTPException(status_code=422, detail=str(e))
except Exception as e:
logger.critical(f"An unexpected error occurred in the processing pipeline: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="An internal server error occurred.")
# To run this app:
# uvicorn app.main:app --reload