diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 878be7087..75a002853 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -26,10 +26,14 @@ logging.config.dictConfig(
"version": 1,
"disable_existing_loggers": False,
"formatters": {
- "console": {"format": "%(asctime)s %(name)-12s %(levelname)-8s %(message)s"}
+ "console": {
+ "format":
+ "%(asctime)s %(name)-12s %(levelname)-8s %(message)s"}
},
"handlers": {
- "console": {"class": "logging.StreamHandler", "formatter": "console"},
+ "console": {
+ "class": "logging.StreamHandler",
+ "formatter": "console"},
},
"loggers": {
"funkwhale_api": {
@@ -81,7 +85,8 @@ FUNKWHALE_PLUGINS_PATH = env(
"FUNKWHALE_PLUGINS_PATH", default="/srv/funkwhale/plugins/"
)
"""
-Path to a directory containing Funkwhale plugins. These will be imported at runtime.
+Path to a directory containing Funkwhale plugins.
+These will be imported at runtime.
"""
sys.path.append(FUNKWHALE_PLUGINS_PATH)
CORE_PLUGINS = [
@@ -101,14 +106,19 @@ if LOAD_CORE_PLUGINS:
PLUGINS = list(OrderedDict.fromkeys(PLUGINS))
if PLUGINS:
- logger.info("Running with the following plugins enabled: %s", ", ".join(PLUGINS))
+ logger.info(
+ "Running with the following plugins enabled: %s",
+ ", ".join(PLUGINS))
else:
logger.info("Running with no plugins")
from .. import plugins # noqa
plugins.startup.autodiscover([p + ".funkwhale_startup" for p in PLUGINS])
-DEPENDENCIES = plugins.trigger_filter(plugins.PLUGINS_DEPENDENCIES, [], enabled=True)
+DEPENDENCIES = plugins.trigger_filter(
+ plugins.PLUGINS_DEPENDENCIES,
+ [],
+ enabled=True)
plugins.install_dependencies(DEPENDENCIES)
FUNKWHALE_HOSTNAME = None
FUNKWHALE_HOSTNAME_SUFFIX = env("FUNKWHALE_HOSTNAME_SUFFIX", default=None)
@@ -128,7 +138,8 @@ else:
FUNKWHALE_PROTOCOL = env("FUNKWHALE_PROTOCOL", default="https")
"""
- Protocol end users will use to access your pod, either ``http`` or ``https``.
+ Protocol end users will use to access your pod,
+ either ``http`` or ``https``.
"""
except Exception:
FUNKWHALE_URL = env("FUNKWHALE_URL")
@@ -143,13 +154,16 @@ FUNKWHALE_SPA_HTML_ROOT = env(
"FUNKWHALE_SPA_HTML_ROOT", default=FUNKWHALE_URL + "/front/"
)
"""
-URL or path to the Web Application files. Funkwhale needs access to it so that
-it can inject tags relevant to the given page (e.g page title, cover, etc.).
+URL or path to the Web Application files.
-If a URL is specified, the index.html file will be fetched through HTTP. If a path is provided,
-it will be accessed from disk.
+Funkwhale needs access to it so that it can inject tags
+relevant to the given page (e.g page title, cover, etc.).
-Use something like ``/srv/funkwhale/front/dist/`` if the web processes shows request errors related to this.
+If a URL is specified, the index.html file will be fetched through HTTP.
+If a path is provided, it will be accessed from disk.
+
+Use something like ``/srv/funkwhale/front/dist/`` if the web processes
+shows request errors related to this.
"""
FUNKWHALE_SPA_HTML_CACHE_DURATION = env.int(
@@ -167,19 +181,25 @@ FUNKWHALE_SPA_REWRITE_MANIFEST_URL = env.bool(
APP_NAME = "Funkwhale"
-FEDERATION_HOSTNAME = env("FEDERATION_HOSTNAME", default=FUNKWHALE_HOSTNAME).lower()
+FEDERATION_HOSTNAME = env(
+ "FEDERATION_HOSTNAME",
+ default=FUNKWHALE_HOSTNAME).lower()
FEDERATION_SERVICE_ACTOR_USERNAME = env(
"FEDERATION_SERVICE_ACTOR_USERNAME", default="service"
)
# How many pages to fetch when crawling outboxes and third-party collections
-FEDERATION_COLLECTION_MAX_PAGES = env.int("FEDERATION_COLLECTION_MAX_PAGES", default=5)
+FEDERATION_COLLECTION_MAX_PAGES = env.int(
+ "FEDERATION_COLLECTION_MAX_PAGES",
+ default=5)
"""
-Number of existing pages of content to fetch when discovering/refreshing an actor or channel.
+Number of existing pages of content to fetch when discovering/refreshing
+an actor or channel.
More pages means more content will be loaded, but will require more resources.
"""
-ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[]) + [FUNKWHALE_HOSTNAME]
+ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=[]) +\
+ [FUNKWHALE_HOSTNAME]
"""
List of allowed hostnames for which the Funkwhale server will answer.
"""
@@ -256,7 +276,9 @@ INSTALLED_APPS = (
# MIDDLEWARE CONFIGURATION
# ------------------------------------------------------------------------------
-ADDITIONAL_MIDDLEWARES_BEFORE = env.list("ADDITIONAL_MIDDLEWARES_BEFORE", default=[])
+ADDITIONAL_MIDDLEWARES_BEFORE = env.list(
+ "ADDITIONAL_MIDDLEWARES_BEFORE",
+ default=[])
MIDDLEWARE = (
tuple(plugins.trigger_filter(plugins.MIDDLEWARES_BEFORE, [], enabled=True))
+ tuple(ADDITIONAL_MIDDLEWARES_BEFORE)
@@ -275,7 +297,10 @@ MIDDLEWARE = (
"funkwhale_api.users.middleware.RecordActivityMiddleware",
"funkwhale_api.common.middleware.ThrottleStatusMiddleware",
)
- + tuple(plugins.trigger_filter(plugins.MIDDLEWARES_AFTER, [], enabled=True))
+ + tuple(plugins.trigger_filter(
+ plugins.MIDDLEWARES_AFTER,
+ [],
+ enabled=True))
)
# DEBUG
@@ -283,12 +308,14 @@ MIDDLEWARE = (
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DJANGO_DEBUG = DEBUG = env.bool("DJANGO_DEBUG", False)
"""
-Whether to enable debugging info and pages. Never enable this on a production server,
+Whether to enable debugging info and pages.
+Never enable this on a production server,
as it can leak very sensitive information.
"""
# FIXTURE CONFIGURATION
# ------------------------------------------------------------------------------
-# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
+# See:
+# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),)
# EMAIL CONFIGURATION
@@ -297,7 +324,8 @@ FIXTURE_DIRS = (str(APPS_DIR.path("fixtures")),)
# EMAIL
# ------------------------------------------------------------------------------
DEFAULT_FROM_EMAIL = env(
- "DEFAULT_FROM_EMAIL", default="Funkwhale ".format(FUNKWHALE_HOSTNAME)
+ "DEFAULT_FROM_EMAIL",
+ default="Funkwhale ".format(FUNKWHALE_HOSTNAME)
)
"""
Name and email address used to send system emails.
@@ -335,7 +363,8 @@ On a production instance, you'll usually want to use an external SMTP server:
If ``user`` or ``password`` contain special characters (eg.
``noreply@youremail.host`` as ``user``), be sure to urlencode them, using
for example the command:
- ``python3 -c 'import urllib.parse; print(urllib.parse.quote_plus("noreply@youremail.host"))'``
+ ``python3 -c 'import urllib.parse;
+ print(urllib.parse.quote_plus("noreply@youremail.host"))'``
(returns ``noreply%40youremail.host``)
"""
@@ -399,20 +428,25 @@ USE_TZ = True
# See: https://docs.djangoproject.com/en/dev/ref/settings/#templates
TEMPLATES = [
{
- # See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
+ # See:
+ # https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATES-BACKEND
"BACKEND": "django.template.backends.django.DjangoTemplates",
- # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
+ # See:
+ # https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
"DIRS": [str(APPS_DIR.path("templates"))],
"OPTIONS": {
- # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
+ # See:
+ # https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
"debug": DEBUG,
- # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
+ # See:
+ # https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
# https://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
"loaders": [
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
],
- # See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
+ # See:
+ # https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
@@ -428,7 +462,8 @@ TEMPLATES = [
}
]
-# See: http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs
+# See:
+# http://django-crispy-forms.readthedocs.org/en/latest/install.html#template-packs
CRISPY_TEMPLATE_PACK = "bootstrap3"
# STATIC FILE CONFIGURATION
@@ -444,12 +479,15 @@ DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIFileSystemStorage"
PROXY_MEDIA = env.bool("PROXY_MEDIA", default=True)
"""
-Wether to proxy audio files through your reverse proxy. It's recommended to keep this on,
-as a way to enforce access control, however, if you're using S3 storage with :attr:`AWS_QUERYSTRING_AUTH`,
+Wether to proxy audio files through your reverse proxy.
+It's recommended to keep this on, as a way to enforce access control,
+however, if you're using S3 storage with :attr:`AWS_QUERYSTRING_AUTH`,
it's safe to disable it.
"""
AWS_DEFAULT_ACL = None
-AWS_QUERYSTRING_AUTH = env.bool("AWS_QUERYSTRING_AUTH", default=not PROXY_MEDIA)
+AWS_QUERYSTRING_AUTH = env.bool(
+ "AWS_QUERYSTRING_AUTH",
+ default=not PROXY_MEDIA)
"""
Whether to include signatures in S3 urls, as a way to enforce access-control.
@@ -462,7 +500,8 @@ AWS_S3_MAX_MEMORY_SIZE = env.int(
AWS_QUERYSTRING_EXPIRE = env.int("AWS_QUERYSTRING_EXPIRE", default=3600)
"""
-Expiration delay, in seconds, of signatures generated when :attr:`AWS_QUERYSTRING_AUTH` is enabled.
+Expiration delay, in seconds, of signatures generated
+when :attr:`AWS_QUERYSTRING_AUTH` is enabled.
"""
AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID", default=None)
@@ -486,14 +525,16 @@ if AWS_ACCESS_KEY_ID:
"""
AWS_S3_ENDPOINT_URL = env("AWS_S3_ENDPOINT_URL", default=None)
"""
- If you use a S3-compatible storage such as minio, set the following variable to
+ If you use a S3-compatible storage such as minio,
+ set the following variable to
the full URL to the storage server. Example:
- ``https://minio.mydomain.com``
- ``https://s3.wasabisys.com``
"""
AWS_S3_REGION_NAME = env("AWS_S3_REGION_NAME", default=None)
- """If you are using Amazon S3 to serve media directly, you will need to specify your region
+ """If you are using Amazon S3 to serve media directly,
+ you will need to specify your region
name in order to access files. Example:
- ``eu-west-2``
@@ -502,34 +543,38 @@ if AWS_ACCESS_KEY_ID:
AWS_S3_SIGNATURE_VERSION = "s3v4"
AWS_LOCATION = env("AWS_LOCATION", default="")
"""
- An optional bucket subdirectory were you want to store the files. This is especially useful
- if you plan to use share the bucket with other services
+ An optional bucket subdirectory were you want to store the files.
+ This is especially useful if you plan to use share the bucket with
+ other services.
"""
DEFAULT_FILE_STORAGE = "funkwhale_api.common.storage.ASCIIS3Boto3Storage"
-# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
+# See: https://docs.djangoproject.com/en/dev/ref/contrib/
+# staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (str(APPS_DIR.path("static")),)
-# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
+# See: https://docs.djangoproject.com/en/dev/ref/contrib/
+# staticfiles/#staticfiles-finders
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
# MEDIA CONFIGURATION
-# ------------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = env("MEDIA_ROOT", default=str(APPS_DIR("media")))
"""
-Path where media files (such as album covers or audio tracks) are stored on your system. Ensure this directory actually exists.
+Path where media files (such as album covers or audio tracks) are stored
+on your system. Ensure this directory actually exists.
"""
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = env("MEDIA_URL", default=FUNKWHALE_URL + "/media/")
"""
URL where media files are served. The default value should work fine on most
-configurations, but could can tweak this if you are hosting media files on a separate
-domain, or if you host Funkwhale on a non-standard port.
+configurations, but could can tweak this if you are hosting media files
+on a separate domain, or if you host Funkwhale on a non-standard port.
"""
FILE_UPLOAD_PERMISSIONS = 0o644
@@ -537,11 +582,12 @@ ATTACHMENTS_UNATTACHED_PRUNE_DELAY = env.int(
"ATTACHMENTS_UNATTACHED_PRUNE_DELAY", default=3600 * 24
)
"""
-Delay in seconds before uploaded but unattached attachements are pruned from the system.
+Delay, in seconds, before uploaded but unattached attachements are pruned
+from the system.
"""
# URL Configuration
-# ------------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
ROOT_URLCONF = "config.urls"
SPA_URLCONF = "config.spa_urls"
ASGI_APPLICATION = "config.routing.application"
@@ -552,7 +598,7 @@ SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
# AUTHENTICATION CONFIGURATION
-# ------------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
AUTHENTICATION_BACKENDS = (
"funkwhale_api.users.auth_backends.ModelBackend",
"funkwhale_api.users.auth_backends.AllAuthBackend",
@@ -567,17 +613,20 @@ ACCOUNT_EMAIL_VERIFICATION_ENFORCE = env.bool(
"ACCOUNT_EMAIL_VERIFICATION_ENFORCE", default=False
)
"""
-Determine wether users need to verify their email address before using the service. Enabling this can be useful
-to reduce spam or bots accounts, however, you'll need to configure a mail server so that your users can receive the
-verification emails, using :attr:`EMAIL_CONFIG`.
+Determine wether users need to verify their email address before using the
+service. Enabling this can be useful to reduce spam or bots accounts,
+however, you'll need to configure a mail server so that your users can receive
+the verification emails, using :attr:`EMAIL_CONFIG`.
-Note that regardless of the setting value, superusers created through the command line will never require verification.
+Note that regardless of the setting value, superusers created through the
+command line will never require verification.
"""
ACCOUNT_EMAIL_VERIFICATION = (
"mandatory" if ACCOUNT_EMAIL_VERIFICATION_ENFORCE else "optional"
)
-ACCOUNT_USERNAME_VALIDATORS = "funkwhale_api.users.serializers.username_validators"
+ACCOUNT_USERNAME_VALIDATORS = \
+ "funkwhale_api.users.serializers.username_validators"
# Custom user app defaults
# Select the correct user model
@@ -605,18 +654,23 @@ OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "users.RefreshToken"
SCOPED_TOKENS_MAX_AGE = 60 * 60 * 24 * 3
# LDAP AUTHENTICATION CONFIGURATION
-# ------------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
AUTH_LDAP_ENABLED = env.bool("LDAP_ENABLED", default=False)
"""
-Wether to enable LDAP authentication. See :doc:`/installation/ldap` for more information.
+Wether to enable LDAP authentication.
+
+See :doc:`/installation/ldap` for more information.
"""
if AUTH_LDAP_ENABLED:
- # Import the LDAP modules here; this way, we don't need the dependency unless someone
- # actually enables the LDAP support
+ # Import the LDAP modules here; this way, we don't need the dependency
+ # unless someone actually enables the LDAP support
import ldap
- from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType
+ from django_auth_ldap.config import \
+ LDAPSearch, \
+ LDAPSearchUnion, \
+ GroupOfNamesType
# Add LDAP to the authentication backends
AUTHENTICATION_BACKENDS += ("django_auth_ldap.backend.LDAPBackend",)
@@ -625,9 +679,9 @@ if AUTH_LDAP_ENABLED:
AUTH_LDAP_SERVER_URI = env("LDAP_SERVER_URI")
AUTH_LDAP_BIND_DN = env("LDAP_BIND_DN", default="")
AUTH_LDAP_BIND_PASSWORD = env("LDAP_BIND_PASSWORD", default="")
- AUTH_LDAP_SEARCH_FILTER = env("LDAP_SEARCH_FILTER", default="(uid={0})").format(
- "%(user)s"
- )
+ AUTH_LDAP_SEARCH_FILTER = env(
+ "LDAP_SEARCH_FILTER",
+ default="(uid={0})").format("%(user)s")
AUTH_LDAP_START_TLS = env.bool("LDAP_START_TLS", default=False)
AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = env(
"AUTH_LDAP_BIND_AS_AUTHENTICATING_USER", default=False
@@ -639,7 +693,9 @@ if AUTH_LDAP_ENABLED:
"username:cn",
"email:mail",
]
- LDAP_USER_ATTR_MAP = env.list("LDAP_USER_ATTR_MAP", default=DEFAULT_USER_ATTR_MAP)
+ LDAP_USER_ATTR_MAP = env.list(
+ "LDAP_USER_ATTR_MAP",
+ default=DEFAULT_USER_ATTR_MAP)
AUTH_LDAP_USER_ATTR_MAP = {}
for m in LDAP_USER_ATTR_MAP:
funkwhale_field, ldap_field = m.split(":")
@@ -686,12 +742,14 @@ URL to your redis server. Examples:
- ``redis://:/``
- ``redis://127.0.0.1:6379/0``
-- ``redis://:password@localhost:6379/0`` for password auth (the extra semicolon is important)
+- ``redis://:password@localhost:6379/0``
+for password auth (the extra semicolon is important)
- ``redis:///run/redis/redis.sock?db=0`` over unix sockets
.. note::
- If you want to use Redis over unix sockets, you'll also need to update :attr:`CELERY_BROKER_URL`
+ If you want to use Redis over unix sockets, you'll also need
+ to update :attr:`CELERY_BROKER_URL`
"""
CACHES = {
@@ -735,7 +793,8 @@ CELERY_BROKER_URL = env(
"CELERY_BROKER_URL", default=env("CACHE_URL", default=CACHE_DEFAULT)
)
"""
-URL to celery's task broker. Defaults to :attr:`CACHE_URL`, so you shouldn't have to tweak this, unless you want
+URL to celery's task broker. Defaults to :attr:`CACHE_URL`,
+so you shouldn't have to tweak this, unless you want
to use a different one, or use Redis sockets to connect.
Exemple:
@@ -813,18 +872,26 @@ def get_user_secret_key(user):
OLD_PASSWORD_FIELD_ENABLED = True
AUTH_PASSWORD_VALIDATORS = [
{
- "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
+ "NAME":
+ "django.contrib.auth.password_validation."
+ "UserAttributeSimilarityValidator"
},
{
- "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
+ "NAME":
+ "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {"min_length": env.int("PASSWORD_MIN_LENGTH", default=8)},
},
- {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
- {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
+ {"NAME":
+ "django.contrib.auth.password_validation.CommonPasswordValidator"},
+ {"NAME":
+ "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
-DISABLE_PASSWORD_VALIDATORS = env.bool("DISABLE_PASSWORD_VALIDATORS", default=False)
+DISABLE_PASSWORD_VALIDATORS = env.bool(
+ "DISABLE_PASSWORD_VALIDATORS",
+ default=False)
"""
-Wether to disable password validators (length, common words, similarity with username…) used during regitration.
+Wether to disable password validators (length, common words, similarity with
+username…) used during regitration.
"""
if DISABLE_PASSWORD_VALIDATORS:
AUTH_PASSWORD_VALIDATORS = []
@@ -837,7 +904,8 @@ CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
REST_FRAMEWORK = {
- "DEFAULT_PAGINATION_CLASS": "funkwhale_api.common.pagination.FunkwhalePagination",
+ "DEFAULT_PAGINATION_CLASS":
+ "funkwhale_api.common.pagination.FunkwhalePagination",
"PAGE_SIZE": 25,
"DEFAULT_PARSER_CLASSES": (
"rest_framework.parsers.JSONParser",
@@ -863,8 +931,10 @@ REST_FRAMEWORK = {
}
THROTTLING_ENABLED = env.bool("THROTTLING_ENABLED", default=True)
"""
-Wether to enable throttling (also known as rate-limiting). Leaving this enabled is recommended
-especially on public pods, to improve the quality of service.
+Wether to enable throttling (also known as rate-limiting).
+
+Leaving this enabled is recommended especially on public pods,
+to improve the quality of service.
"""
if THROTTLING_ENABLED:
@@ -874,12 +944,15 @@ if THROTTLING_ENABLED:
)
THROTTLING_SCOPES = {
- "*": {"anonymous": "anonymous-wildcard", "authenticated": "authenticated-wildcard"},
+ "*": {
+ "anonymous": "anonymous-wildcard",
+ "authenticated": "authenticated-wildcard"},
"create": {
"authenticated": "authenticated-create",
"anonymous": "anonymous-create",
},
- "list": {"authenticated": "authenticated-list", "anonymous": "anonymous-list"},
+ "list": {
+ "authenticated": "authenticated-list", "anonymous": "anonymous-list"},
"retrieve": {
"authenticated": "authenticated-retrieve",
"anonymous": "anonymous-retrieve",
@@ -926,7 +999,8 @@ THROTTLING_RATES = {
"description": "Anonymous GET requests on resource lists",
},
"authenticated-retrieve": {
- "rate": THROTTLING_USER_RATES.get("authenticated-retrieve", "10000/hour"),
+ "rate":
+ THROTTLING_USER_RATES.get("authenticated-retrieve", "10000/hour"),
"description": "Authenticated GET requests on resource detail",
},
"anonymous-retrieve": {
@@ -943,7 +1017,8 @@ THROTTLING_RATES = {
},
"authenticated-update": {
"rate": THROTTLING_USER_RATES.get("authenticated-update", "1000/hour"),
- "description": "Authenticated PATCH and PUT requests on resource detail",
+ "description":
+ "Authenticated PATCH and PUTrequests on resource detail",
},
"anonymous-update": {
"rate": THROTTLING_USER_RATES.get("anonymous-update", "1000/day"),
@@ -963,7 +1038,8 @@ THROTTLING_RATES = {
"description": "Anonymous report submission",
},
"authenticated-oauth-app": {
- "rate": THROTTLING_USER_RATES.get("authenticated-oauth-app", "10/hour"),
+ "rate":
+ THROTTLING_USER_RATES.get("authenticated-oauth-app", "10/hour"),
"description": "Authenticated OAuth app creation",
},
"anonymous-oauth-app": {
@@ -1013,9 +1089,10 @@ THROTTLING_RATES = {
}
THROTTLING_RATES = THROTTLING_RATES
"""
-Throttling rates for specific endpoints and features of the app. You can tweak this if you are
-encountering to severe rate limiting issues or, on the contrary, if you want to reduce
-the consumption on some endpoints.
+Throttling rates for specific endpoints and features of the app.
+
+You can tweak this if you are encountering to severe rate limiting issues or,
+on the contrary, if you want to reduce the consumption on some endpoints.
Example:
@@ -1037,8 +1114,8 @@ ATOMIC_REQUESTS = False
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = True
-# Wether we should use Apache, Nginx (or other) headers when serving audio files
-# Default to Nginx
+# Wether we should use Apache, Nginx (or other) headers when
+# serving audio files. Defaults to Nginx
REVERSE_PROXY_TYPE = env("REVERSE_PROXY_TYPE", default="nginx")
"""
Depending on the reverse proxy used in front of your funkwhale instance,
@@ -1046,11 +1123,13 @@ the API will use different kind of headers to serve audio files
Allowed values: ``nginx``, ``apache2``
"""
-assert REVERSE_PROXY_TYPE in ["apache2", "nginx"], "Unsupported REVERSE_PROXY_TYPE"
+assert REVERSE_PROXY_TYPE in \
+ ["apache2", "nginx"], \
+ "Unsupported REVERSE_PROXY_TYPE"
PROTECT_FILES_PATH = env("PROTECT_FILES_PATH", default="/_protected")
"""
-Which path will be used to process the internal redirection to the reverse proxy
+Path to be used to process the internal redirection to the reverse proxy
**DO NOT** put a slash at the end.
You shouldn't have to tweak this.
@@ -1110,11 +1189,15 @@ ACCOUNT_USERNAME_BLACKLIST = [
"actor",
] + env.list("ACCOUNT_USERNAME_BLACKLIST", default=[])
"""
-List of usernames that will be unavailable during registration, given as a list of strings.
+List of usernames that will be unavailable during registration,
+given as a list of strings.
"""
-EXTERNAL_REQUESTS_VERIFY_SSL = env.bool("EXTERNAL_REQUESTS_VERIFY_SSL", default=True)
+EXTERNAL_REQUESTS_VERIFY_SSL = env.bool(
+ "EXTERNAL_REQUESTS_VERIFY_SSL", default=True)
"""
-Wether to enforce HTTPS certificates verification when doing outgoing HTTP requests (typically with federation).
+Wether to enforce HTTPS certificates verification when doing outgoing
+HTTP requests (typically with federation).
+
Disabling this is not recommended.
"""
EXTERNAL_REQUESTS_TIMEOUT = env.int("EXTERNAL_REQUESTS_TIMEOUT", default=10)
@@ -1124,8 +1207,9 @@ Default timeout for external requests.
MUSIC_DIRECTORY_PATH = env("MUSIC_DIRECTORY_PATH", default=None)
"""
-The path on your server where Funkwhale can import files using :ref:`in-place import
-`. It must be readable by the webserver and Funkwhale
+The path on your server where Funkwhale can import files using
+:ref:`in-place import `. It must be readable by the
+webserver and Funkwhale
api and worker processes.
On docker installations, we recommend you use the default of ``/music``
@@ -1136,9 +1220,9 @@ for this value. For non-docker installation, you can use any absolute path.
.. warning::
- You need to adapt your :ref:`reverse-proxy configuration` to
- serve the directory pointed by ``MUSIC_DIRECTORY_PATH`` on
- ``/_protected/music`` URL.
+ You need to adapt your :ref:`reverse proxy configuration
+ ` to serve the directory pointed by
+ ``MUSIC_DIRECTORY_PATH`` on ``/_protected/music`` URL.
"""
MUSIC_DIRECTORY_SERVE_PATH = env(
@@ -1148,8 +1232,9 @@ MUSIC_DIRECTORY_SERVE_PATH = env(
Default: :attr:`MUSIC_DIRECTORY_PATH`
When using Docker, the value of :attr:`MUSIC_DIRECTORY_PATH` in your containers
-may differ from the real path on your host. Assuming you have the following directive
-in your :file:`docker-compose.yml` file::
+may differ from the real path on your host.
+Assuming you have the following directive in your
+:file:`docker-compose.yml` file::
volumes:
- /srv/funkwhale/data/music:/music:ro
@@ -1188,14 +1273,16 @@ VERSATILEIMAGEFIELD_RENDITION_KEY_SETS = {
}
VERSATILEIMAGEFIELD_SETTINGS = {
"create_images_on_demand": False,
- "jpeg_resize_quality": env.int("THUMBNAIL_JPEG_RESIZE_QUALITY", default=95),
+ "jpeg_resize_quality":
+ env.int("THUMBNAIL_JPEG_RESIZE_QUALITY", default=95),
}
RSA_KEY_SIZE = 2048
# for performance gain in tests, since we don't need to actually create the
# thumbnails
CREATE_IMAGE_THUMBNAILS = env.bool("CREATE_IMAGE_THUMBNAILS", default=True)
# we rotate actor keys at most every two days by default
-ACTOR_KEY_ROTATION_DELAY = env.int("ACTOR_KEY_ROTATION_DELAY", default=3600 * 48)
+ACTOR_KEY_ROTATION_DELAY = env.int(
+ "ACTOR_KEY_ROTATION_DELAY", default=3600 * 48)
SUBSONIC_DEFAULT_TRANSCODING_FORMAT = (
env("SUBSONIC_DEFAULT_TRANSCODING_FORMAT", default="mp3") or None
)
@@ -1205,13 +1292,15 @@ Default format for transcoding when using Subsonic API.
# extra tags will be ignored
TAGS_MAX_BY_OBJ = env.int("TAGS_MAX_BY_OBJ", default=30)
"""
-Maximum number of tags that can be associated with an object. Extra tags will be ignored.
+Maximum number of tags that can be associated with an object.
+Extra tags will be ignored.
"""
FEDERATION_OBJECT_FETCH_DELAY = env.int(
"FEDERATION_OBJECT_FETCH_DELAY", default=60 * 24 * 3
)
"""
-Delay, in minutes, before a remote object will be automatically refetched when accessed in the UI.
+Delay, in minutes, before a remote object will be automatically refetched
+when accessed in the UI.
"""
MODERATION_EMAIL_NOTIFICATIONS_ENABLED = env.bool(
"MODERATION_EMAIL_NOTIFICATIONS_ENABLED", default=True
@@ -1220,18 +1309,24 @@ MODERATION_EMAIL_NOTIFICATIONS_ENABLED = env.bool(
Whether to enable email notifications to moderators and pods admins.
"""
FEDERATION_AUTHENTIFY_FETCHES = True
-FEDERATION_SYNCHRONOUS_FETCH = env.bool("FEDERATION_SYNCHRONOUS_FETCH", default=True)
+FEDERATION_SYNCHRONOUS_FETCH = env.bool(
+ "FEDERATION_SYNCHRONOUS_FETCH",
+ default=True)
FEDERATION_DUPLICATE_FETCH_DELAY = env.int(
"FEDERATION_DUPLICATE_FETCH_DELAY", default=60 * 50
)
"""
Delay, in seconds, between two manual fetch of the same remote object.
"""
-INSTANCE_SUPPORT_MESSAGE_DELAY = env.int("INSTANCE_SUPPORT_MESSAGE_DELAY", default=15)
+INSTANCE_SUPPORT_MESSAGE_DELAY = env.int(
+ "INSTANCE_SUPPORT_MESSAGE_DELAY",
+ default=15)
"""
Delay after signup, in days, before the "support your pod" message is shown.
"""
-FUNKWHALE_SUPPORT_MESSAGE_DELAY = env.int("FUNKWHALE_SUPPORT_MESSAGE_DELAY", default=15)
+FUNKWHALE_SUPPORT_MESSAGE_DELAY = env.int(
+ "FUNKWHALE_SUPPORT_MESSAGE_DELAY",
+ default=15)
"""
Delay after signup, in days, before the "support Funkwhale" message is shown.
"""
@@ -1240,41 +1335,53 @@ MIN_DELAY_BETWEEN_DOWNLOADS_COUNT = env.int(
"MIN_DELAY_BETWEEN_DOWNLOADS_COUNT", default=60 * 60 * 6
)
"""
-Minimum required period, in seconds, for two downloads of the same track by the same IP
-or user to be recorded in statistics.
+Minimum required period, in seconds, for two downloads of the same track
+by the same IP or user to be recorded in statistics.
"""
-MARKDOWN_EXTENSIONS = env.list("MARKDOWN_EXTENSIONS", default=["nl2br", "extra"])
+MARKDOWN_EXTENSIONS = env.list(
+ "MARKDOWN_EXTENSIONS",
+ default=["nl2br", "extra"])
"""
List of markdown extensions to enable.
See ``_.
"""
-LINKIFIER_SUPPORTED_TLDS = ["audio"] + env.list("LINKINFIER_SUPPORTED_TLDS", default=[])
+LINKIFIER_SUPPORTED_TLDS = ["audio"] + env.list(
+ "LINKINFIER_SUPPORTED_TLDS",
+ default=[])
"""
Additional TLDs to support with our markdown linkifier.
"""
-EXTERNAL_MEDIA_PROXY_ENABLED = env.bool("EXTERNAL_MEDIA_PROXY_ENABLED", default=True)
+EXTERNAL_MEDIA_PROXY_ENABLED = env.bool(
+ "EXTERNAL_MEDIA_PROXY_ENABLED",
+ default=True)
"""
-Wether to proxy attachment files hosted on third party pods and and servers. Keeping
-this to true is recommended, to reduce leaking browsing information of your users, and
-reduce the bandwidth used on remote pods.
+Wether to proxy attachment files hosted on third party pods and and servers.
+Keeping this to true is recommended, to reduce leaking browsing information
+of your users, and reduce the bandwidth used on remote pods.
"""
-PODCASTS_THIRD_PARTY_VISIBILITY = env("PODCASTS_THIRD_PARTY_VISIBILITY", default="me")
+PODCASTS_THIRD_PARTY_VISIBILITY = env(
+ "PODCASTS_THIRD_PARTY_VISIBILITY",
+ default="me")
"""
-By default, only people who subscribe to a podcast RSS will have access to their episodes.
-switch to "instance" or "everyone" to change that.
+By default, only people who subscribe to a podcast RSS will have access to
+their episodes. Switch to "instance" or "everyone" to change that.
-Changing it only affect new podcasts.
+Changing it only affects new podcasts.
"""
PODCASTS_RSS_FEED_REFRESH_DELAY = env.int(
"PODCASTS_RSS_FEED_REFRESH_DELAY", default=60 * 60 * 24
)
"""
-Delay in seconds between two fetch of RSS feeds. Reducing this mean you'll receive new episodes faster,
-but will require more resources.
+Delay, in seconds, between two fetch of RSS feeds.
+
+Reducing this mean you'll receive new episodes faster, but will require more
+resources.
"""
# maximum items loaded through XML feed
-PODCASTS_RSS_FEED_MAX_ITEMS = env.int("PODCASTS_RSS_FEED_MAX_ITEMS", default=250)
+PODCASTS_RSS_FEED_MAX_ITEMS = env.int(
+ "PODCASTS_RSS_FEED_MAX_ITEMS",
+ default=250)
"""
Maximum number of RSS items to load in each podcast feed.
"""
@@ -1283,7 +1390,8 @@ IGNORE_FORWARDED_HOST_AND_PROTO = env.bool(
"IGNORE_FORWARDED_HOST_AND_PROTO", default=True
)
"""
-Use :attr:`FUNKWHALE_HOSTNAME` and :attr:`FUNKWHALE_PROTOCOL ` instead of request header.
+Use :attr:`FUNKWHALE_HOSTNAME` and :attr:`FUNKWHALE_PROTOCOL `
+instead of request header.
"""
HASHING_ALGORITHM = "sha256"