[project] name = "mcma-backend" version = "0.1.0" description = "Self-hosted, offline-first music service — backend (hexagonal architecture)" readme = "README.md" requires-python = ">=3.14" dependencies = [ # web "fastapi>=0.115", "uvicorn[standard]>=0.32", "python-multipart>=0.0.12", # data "sqlalchemy[asyncio]>=2.0.36", "asyncpg>=0.30", "alembic>=1.14", # config / validation "pydantic>=2.10", "pydantic-settings>=2.6", # cache / queue "redis>=5.2", "arq>=0.26", # auth "pyjwt>=2.10", "pwdlib[argon2]>=0.2.1", # outbound http (ML client, MusicBrainz, AcoustID) "httpx>=0.28", # logging "structlog>=24.4", ] [project.scripts] mcma = "app.cli:main" [dependency-groups] dev = [ "pytest>=8.3", "pytest-asyncio>=0.24", "ruff>=0.8", "mypy>=1.13", "asgi-lifespan>=2.1", ] [tool.uv] package = true [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["app"] # --------------------------------------------------------------------------- # Tooling # --------------------------------------------------------------------------- [tool.ruff] target-version = "py314" line-length = 100 src = ["app", "tests"] [tool.ruff.lint] select = [ "E", "F", "W", # pycodestyle / pyflakes "I", # isort "N", # pep8-naming "UP", # pyupgrade "B", # bugbear "ASYNC", # async pitfalls "RUF", ] ignore = ["B008"] # FastAPI Depends() in defaults is idiomatic [tool.mypy] python_version = "3.14" strict = true plugins = ["pydantic.mypy"] warn_unused_ignores = true disallow_untyped_defs = true [[tool.mypy.overrides]] module = ["arq.*"] ignore_missing_imports = true [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] addopts = "-ra"