diff --git a/alembic/env.py b/alembic/env.py index 5d4475a..2d5b9e7 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -1,14 +1,26 @@ from logging.config import fileConfig from sqlalchemy import engine_from_config -from sqlalchemy import pool,create_engine +from sqlalchemy import pool, create_engine from app.database import Base import app.models from alembic import context +import os +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config +# Force Alembic to use the URL from our environment variables +# If no .env is found, it defaults to the Docker container URL +config.set_main_option( + "sqlalchemy.url", + os.getenv("DATABASE_URL", "postgresql+psycopg://postgres:postgres@db:5432/wheretf") +) + # Interpret the config file for Python logging. # This line sets up loggers basically. if config.config_file_name is not None: @@ -16,16 +28,8 @@ # add your model's MetaData object here # for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata target_metadata = Base.metadata -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - def run_migrations_offline() -> None: """Run migrations in 'offline' mode. @@ -55,12 +59,11 @@ def run_migrations_online() -> None: In this scenario we need to create an Engine and associate a connection with the context. - """ + # Create the engine dynamically using the URL we configured at the top + connectable = create_engine(config.get_main_option("sqlalchemy.url")) -# We force Alembic to use localhost and the exact password 'postgres' - connectable = create_engine("postgresql+psycopg://postgres:postgres@localhost:5433/wheretf") with connectable.connect() as connection: context.configure( connection=connection, target_metadata=target_metadata @@ -73,4 +76,4 @@ def run_migrations_online() -> None: if context.is_offline_mode(): run_migrations_offline() else: - run_migrations_online() + run_migrations_online() \ No newline at end of file diff --git a/app/main.py b/app/main.py index 9210162..adaaf66 100644 --- a/app/main.py +++ b/app/main.py @@ -1,11 +1,14 @@ from fastapi import FastAPI from app.routes import search +from app.routes import upload + app = FastAPI( title="WhereTF Backend" ) app.include_router(search.router) +app.include_router(upload.router) @app.get("/health", tags=["System"]) def health_check(): @@ -16,4 +19,4 @@ def health_check(): "status": "healthy", "service": "WhereTF Backend", "database_connected": True # If the API booted, the Docker depends_on guarantees this is true - } \ No newline at end of file + } diff --git a/app/routes/upload.py b/app/routes/upload.py new file mode 100644 index 0000000..7d7fad8 --- /dev/null +++ b/app/routes/upload.py @@ -0,0 +1,43 @@ +import os +import shutil + +from fastapi import APIRouter, UploadFile, File, BackgroundTasks, HTTPException + +from app.services.indexer import background_index_file + +router = APIRouter(tags=["File Upload"]) + + +@router.post("/upload/") +async def upload_file( + background_tasks: BackgroundTasks, + file: UploadFile = File(...) +): + """ + Accept a document and send it for background indexing. + """ + + try: + os.makedirs("temp", exist_ok=True) + + temp_path = os.path.join("temp", file.filename) + + with open(temp_path, "wb") as buffer: + shutil.copyfileobj(file.file, buffer) + + background_tasks.add_task( + background_index_file, + temp_path + ) + + return { + "status": "success", + "message": "File accepted for indexing", + "filename": file.filename + } + + except Exception as e: + raise HTTPException( + status_code=500, + detail=f"Upload failed: {str(e)}" + ) diff --git a/requirements.txt b/requirements.txt index 1e2d2c9..a37573b 100644 Binary files a/requirements.txt and b/requirements.txt differ