[tool.poetry] name = "funkwhale-api" version = "1.4.0" description = "Funkwhale API" authors = ["Funkwhale Collective"] homepage = "https://funkwhale.audio" repository = "https://dev.funkwhale.audio/funkwhale/funkwhale" documentation = "https://docs.funkwhale.audio" license = "AGPL-3.0-only" packages = [ { include = "funkwhale_api" }, { include = "config" }, ] include = [ { path = "*.html" }, { path = "*.json" }, { path = "*.png" }, { path = "*.txt" }, ] exclude = ["tests"] [tool.poetry.scripts] funkwhale-manage = 'funkwhale_api.main:main' [tool.poetry.dependencies] python = "^3.10,<3.14" # Django dj-rest-auth = "7.0.1" django = "5.1.5" django-allauth = "65.3.1" django-cache-memoize = "0.2.1" django-cacheops = "==7.1" django-cleanup = "==9.0.0" django-cors-headers = "==4.6.0" django-dynamic-preferences = "==1.17.0" django-environ = "==0.12.0" django-filter = "==24.3" django-oauth-toolkit = "3.0.1" django-redis = "==5.4.0" django-storages = "==1.14.4" django-versatileimagefield = "==3.1" djangorestframework = "==3.15.2" drf-spectacular = "==0.28.0" markdown = "==3.7" persisting-theory = "==1.0" psycopg2-binary = "==2.9.10" redis = "==5.2.1" # Django LDAP django-auth-ldap = "==5.1.0" python-ldap = "==3.4.4" # Channels channels = { extras = ["daphne"], version = "==4.2.0" } channels-redis = "==4.2.1" # Celery kombu = "5.4.2" celery = "5.4.0" # Deployment gunicorn = "==23.0.0" uvicorn = { version = "==0.34.0", extras = ["standard"] } # Libs aiohttp = "3.11.11" arrow = "==1.3.0" backports-zoneinfo = { version = "==0.2.1", python = "<3.9" } bleach = "==6.2.0" boto3 = "==1.35.99" click = "==8.1.8" cryptography = "==44.0.0" defusedxml = "0.7.1" feedparser = "==6.0.11" python-ffmpeg = "==2.0.12" liblistenbrainz = "==0.5.5" musicbrainzngs = "==0.7.1" mutagen = "==1.46.0" pillow = "==11.1.0" pyld = "==2.0.4" python-magic = "==0.4.27" requests = "==2.32.3" requests-http-message-signatures = "==0.3.1" sentry-sdk = "==2.20.0" watchdog = "==6.0.0" troi = "==2025.1.10.0" lb-matching-tools = "==2024.1.30.1" unidecode = "==1.3.8" pycountry = "24.6.1" # Typesense typesense = { version = "==0.21.0", optional = true } # Dependencies pinning ipython = "==8.31.0" pluralizer = "==1.2.0" service-identity = "==24.2.0" unicode-slugify = "==0.1.5" [tool.poetry.group.dev.dependencies] aioresponses = "==0.7.7" asynctest = "==0.13.0" black = "==24.10.0" coverage = { version = "==7.6.10", extras = ["toml"] } debugpy = "==1.8.11" django-coverage-plugin = "==3.1.0" django-debug-toolbar = "==5.0.1" factory-boy = "==3.3.1" faker = "==33.3.1" flake8 = "==7.1.1" ipdb = "==0.13.13" pytest = "==8.3.4" pytest-asyncio = "==0.25.2" prompt-toolkit = "==3.0.48" pytest-cov = "==6.0.0" pytest-django = "==4.9.0" pytest-env = "==1.1.5" pytest-mock = "==3.14.0" pytest-randomly = "==3.16.0" pytest-sugar = "==1.0.0" requests-mock = "==1.12.1" pylint = "==3.3.3" pylint-django = "==2.6.1" django-extensions = "==3.2.3" [tool.poetry.extras] typesense = ["typesense"] [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.pylint.master] load-plugins = ["pylint_django"] django-settings-module = "config.settings.testing" [tool.pylint.messages_control] disable = [ "invalid-name", "missing-class-docstring", "missing-function-docstring", "missing-module-docstring", ] [tool.pylint.design] max-parents = 13 [tool.pylint.format] max-line-length = 120 [tool.pytest.ini_options] python_files = [ "tests.py", "test_*.py", "*_tests.py", ] testpaths = ["tests"] addopts = "-p no:warnings" env = [ "CELERY_BROKER_URL=memory://", "CELERY_TASK_ALWAYS_EAGER=True", "CREATE_IMAGE_THUMBNAILS=False", "DEBUG=False", "DEBUG_TOOLBAR_ENABLED=False", "DISABLE_PASSWORD_VALIDATORS=false", "DISABLE_PASSWORD_VALIDATORS=false", "EMAIL_CONFIG=consolemail://", "EXTERNAL_MEDIA_PROXY_ENABLED=true", "FEDERATION_HOSTNAME=test.federation", "FORCE_HTTPS_URLS=False", "FUNKWHALE_HOSTNAME=test.federation", "FUNKWHALE_HOSTNAME_PREFIX=", "FUNKWHALE_HOSTNAME_SUFFIX=", "FUNKWHALE_PLUGINS=", "FUNKWHALE_SPA_HTML_ROOT=http://noop/", "FUNKWHALE_URL=https://test.federation", "MUSIC_DIRECTORY_PATH=/music", "MUSIC_USE_DENORMALIZATION=true", "PROXY_MEDIA=true", "SECRET_KEY=test", "TYPESENSE_API_KEY=apikey", "WEAK_PASSWORDS=True", ] [tool.coverage.run] plugins = ["django_coverage_plugin"] source = ["funkwhale_api"] omit = [ "*migrations*", "*tests*", "funkwhale_api/schema.py", ]