[build-system] requires = ["setuptools>=69"] build-backend = "setuptools.build_meta" [project] name = "rarelens-api" version = "0.1.0" description = "FastAPI backend for rarelens" requires-python = ">=3.12" dependencies = [ "fastapi>=0.115", "uvicorn[standard]>=0.30", "sqlalchemy[asyncio]>=2.0", "asyncpg>=0.29", "alembic>=1.13", "pydantic>=2.8", "pydantic-settings>=2.4", "httpx>=0.27", # mlflow major must match rarelens-ml and the tracking server image. "mlflow-skinny>=3,<4", "lightgbm>=4.5", "scikit-learn>=1.5", # the pickled LGBMClassifier inside the pyfunc needs it to load "pandas>=2.2", ] [project.optional-dependencies] # pubsub: Kubernetes track; run: serverless track; storage: load a model from gs:// gcp = ["google-cloud-pubsub>=2.23", "google-cloud-run>=0.10", "google-cloud-storage>=2.18"] dev = [ "pytest>=8", "pytest-asyncio>=1.0", "ruff==0.16.2", "mypy>=1.11", "pandas-stubs", # Throwaway Postgres for `pytest` when DATABASE_URL is unset (no Docker needed). "pgserver; sys_platform != 'win32'", ] # The repo also has top-level `alembic/` and `tests/` dirs; only `app` is the package. [tool.setuptools.packages.find] include = ["app*"] [tool.ruff] line-length = 100 target-version = "py312" [tool.ruff.lint.isort] # Without this the local `alembic/` migrations dir makes ruff treat the alembic library as first-party. known-third-party = ["alembic"] [tool.mypy] python_version = "3.12" [[tool.mypy.overrides]] module = ["google.cloud.*", "mlflow.*"] ignore_missing_imports = true [tool.pytest.ini_options] asyncio_mode = "auto" # asyncpg connections are bound to the loop that opened them; one loop for the whole run # lets the app's pooled engine be shared across tests. asyncio_default_fixture_loop_scope = "session" asyncio_default_test_loop_scope = "session" pythonpath = ["."] testpaths = ["tests"]