audio streaming app plyr.fm
at main 163 lines 4.3 kB view raw
1[project] 2name = "backend" 3dynamic = ["version"] 4description = "decentralized music streaming platform built on ATProto" 5authors = [{ name = "zzstoatzz", email = "thrast36@gmail.com" }] 6dependencies = [ 7 "fastapi>=0.115.0", 8 "uvicorn[standard]>=0.34.0", 9 "httpx>=0.28.0", 10 "pydantic>=2.11.0", 11 "pydantic-settings>=2.7.0", 12 "python-dotenv>=1.1.0", 13 "sqlalchemy>=2.0.36", 14 "alembic>=1.14.0", 15 "asyncpg>=0.30.0", 16 "atproto @ git+https://github.com/zzstoatzz/atproto@oauth-full", 17 "boto3>=1.37.0", 18 "python-multipart>=0.0.20", 19 "python-jose[cryptography]>=3.3.0", 20 "passlib[bcrypt]>=1.7.4", 21 "psycopg[binary]>=3.2.12", 22 "greenlet>=3.2.4", 23 "logfire[fastapi,sqlalchemy]>=4.14.2", 24 "cachetools>=6.2.1", 25 "pytest-asyncio>=0.25.3", 26 "aioboto3>=15.5.0", 27 "slowapi @ git+https://github.com/zzstoatzz/slowapi.git@fix-deprecation", 28 "orjson>=3.11.4", 29 "mutagen>=1.47.0", 30 "pydocket>=0.15.2", 31 "redis>=7.1.0", 32 "beartype>=0.22.8", 33 "turbopuffer>=0.5.0", 34 "Pillow>=11.0.0", 35 "feedgen>=1.0.0", 36] 37 38requires-python = ">=3.11" 39readme = "README.md" 40license = "Apache-2.0" 41 42keywords = ["music", "streaming", "atproto", "bluesky", "decentralized"] 43 44[dependency-groups] 45dev = [ 46 "dirty-equals>=0.9.0", 47 "ipython>=8.12.3", 48 "pdbpp>=0.10.3", 49 "plyrfm @ git+https://github.com/zzstoatzz/plyr-python-client#subdirectory=packages/plyrfm", 50 "prek>=0.2.13", 51 "pytest>=8.3.3", 52 "pytest-asyncio>=1.0.0", 53 "pytest-cov>=6.1.1", 54 "pytest-env>=1.1.5", 55 "pytest-timeout>=2.4.0", 56 "pytest-xdist>=3.6.1", 57 "ruff>=0.12.0", 58 "httpx>=0.28.0", 59 "ty>=0.0.1a25", 60] 61 62[build-system] 63requires = ["hatchling", "uv-dynamic-versioning>=0.7.0"] 64build-backend = "hatchling.build" 65 66[tool.hatch.version] 67source = "uv-dynamic-versioning" 68 69[tool.hatch.metadata] 70allow-direct-references = true 71 72[tool.uv-dynamic-versioning] 73vcs = "git" 74style = "pep440" 75bump = true 76fallback-version = "0.0.0" 77 78[tool.pytest.ini_options] 79asyncio_mode = "auto" 80asyncio_default_fixture_loop_scope = "function" 81timeout = 10 82env = [ 83 "RELAY_TEST_MODE=1", 84 "OAUTH_ENCRYPTION_KEY=hnSkDmgbbuK0rt7Ab3eJHAktb18gmebsdwKdTmq9mes=", 85 "LOGFIRE_IGNORE_NO_CONFIG=1", 86 # reduce connection pool for tests to avoid exhausting Neon's connection limit 87 "DATABASE_POOL_SIZE=2", 88 "DATABASE_MAX_OVERFLOW=0", 89 # redis URL for cache tests (uses test-redis from docker-compose) 90 # D: prefix means don't override if already set (e.g., by CI workflow) 91 "D:DOCKET_URL=redis://localhost:6380/0", 92 # disable automatic perpetual task scheduling in tests to avoid event loop issues 93 "DOCKET_SCHEDULE_AUTOMATIC_TASKS=false", 94] 95markers = [ 96 "integration: marks tests as integration tests (deselect with '-m \"not integration\"')", 97] 98pythonpath = ["."] 99testpaths = ["tests"] 100python_files = ["test_*.py", "*_test.py"] 101python_classes = ["Test*"] 102python_functions = ["test_*"] 103filterwarnings = [ 104 "ignore::pydantic.warnings.UnsupportedFieldAttributeWarning", 105] 106 107[tool.ruff.lint] 108fixable = ["ALL"] 109ignore = [ 110 "COM812", 111 "PLR0913", # Too many arguments 112 "SIM102", # Dont require combining if statements 113] 114extend-select = [ 115 "B", # flake8-bugbear 116 "C4", # flake8-comprehensions 117 "I", # isort 118 "PIE", # flake8-pie 119 "RUF", # Ruff-specific 120 "SIM", # flake8-simplify 121 "UP", # pyupgrade 122] 123 124[tool.ruff.lint.per-file-ignores] 125"__init__.py" = ["F401", "I001"] 126"tests/**/*.py" = ["S101"] # Allow assert in tests 127"src/backend/api/**/*.py" = [ 128 "B008", 129] # Allow Depends() and File() in FastAPI route defaults 130"src/backend/main.py" = ["E402"] # Need warnings filter before imports 131 132[tool.coverage.run] 133source = ["src"] 134omit = ["tests/*", "sandbox/*"] 135 136[tool.coverage.report] 137exclude_lines = [ 138 "pragma: no cover", 139 "def __repr__", 140 "raise AssertionError", 141 "raise NotImplementedError", 142 "if __name__ == .__main__.:", 143 "if TYPE_CHECKING:", 144] 145 146[tool.ty.src] 147include = ["src", "tests"] 148exclude = [ 149 "**/node_modules", 150 "**/__pycache__", 151 ".venv", 152 ".git", 153 "dist", 154 "frontend", 155] 156 157[tool.ty.environment] 158python-version = "3.11" 159 160[tool.ty.rules] 161# start with basic checks, can tighten later 162unknown-argument = "ignore" 163no-matching-overload = "ignore"