Skip to content
Merged
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
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ COPY run.py /app/
# Port the application listens on
EXPOSE 8000

# Health check to ensure the container is responding to requests
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

# Command to run the application using Uvicorn
# The command format is: uvicorn [module:app_object] --host [ip] --port [port]
# We use the standard uvicorn worker configuration
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Copy `.env.example` to `.env` (done automatically by `make dev-setup`) and fill
| `ENABLE_ETL_SCHEDULER` | | Set `true` to run the ETL on a schedule |
| `ETL_CRON` | | Cron expression (UTC) — takes precedence over `ETL_INTERVAL_MINUTES` |
| `ETL_INTERVAL_MINUTES` | | ETL polling interval in minutes (default `15`) |
| `SHUTDOWN_TIMEOUT_SECONDS` | | Graceful shutdown timeout in seconds (default `30`) |
| `BQ_ENABLED` | | Set `true` to enable BigQuery loading |
| `BQ_PROJECT_ID` | | GCP project ID |
| `BQ_DATASET` | | BigQuery dataset name |
Expand Down
9 changes: 8 additions & 1 deletion run.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
from src.main import app # noqa: F401

if __name__ == "__main__":
uvicorn.run("src.main:app", host="0.0.0.0", port=8000)
from src.config import get_settings
settings = get_settings()
uvicorn.run(
"src.main:app",
host="0.0.0.0",
port=8000,
timeout_graceful_shutdown=settings.SHUTDOWN_TIMEOUT_SECONDS
)


6 changes: 1 addition & 5 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict

from pydantic_settings import BaseSettings

class Settings(BaseSettings):


class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")

Expand Down Expand Up @@ -38,6 +33,7 @@ class Settings(BaseSettings):
POOL_SIZE: int = 5
POOL_MAX_OVERFLOW: int = 10
REPORT_CACHE_MINUTES: int = 60
SHUTDOWN_TIMEOUT_SECONDS: int = 30

SERVICE_API_KEY: str = "default_service_secret_change_me"
ADMIN_API_KEY: str = "default_admin_secret_change_me"
Expand Down
9 changes: 6 additions & 3 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,14 @@ def on_startup() -> None:
@app.on_event("shutdown")
def on_shutdown() -> None:
global etl_scheduler
log_info("Shutdown initiated: waiting for in-flight requests and scheduler...")
if etl_scheduler is not None:
try:
etl_scheduler.shutdown(wait=False)
except Exception:
pass
# wait=True ensures running jobs complete before scheduler stops
etl_scheduler.shutdown(wait=True)
log_info("ETL scheduler shut down successfully.")
except Exception as exc:
log_error("Error during scheduler shutdown", {"error": str(exc)})


# ---------------------------------------------------------------------------
Expand Down
Loading