diff --git a/kobo/settings/base.py b/kobo/settings/base.py index af112352d2..c160849b3c 100644 --- a/kobo/settings/base.py +++ b/kobo/settings/base.py @@ -18,6 +18,7 @@ from kpi.constants import PERM_DELETE_ASSET, PERM_MANAGE_ASSET from ..static_lists import EXTRA_LANG_INFO, SECTOR_CHOICE_DEFAULTS +from .utils import constance_env, dj_stripe_request_callback_method env = environ.Env() @@ -225,21 +226,39 @@ 'in the user interface', ), 'SUPPORT_EMAIL': ( - env.str('KOBO_SUPPORT_EMAIL', env.str('DEFAULT_FROM_EMAIL', 'help@kobotoolbox.org')), + constance_env( + env.str, + 'CONSTANCE_SUPPORT_EMAIL', + 'KOBO_SUPPORT_EMAIL', + env.str('DEFAULT_FROM_EMAIL', 'help@kobotoolbox.org'), + ), 'Email address for users to contact, e.g. when they encounter ' 'unhandled errors in the application', ), 'SUPPORT_URL': ( - env.str('KOBO_SUPPORT_URL', 'https://support.kobotoolbox.org/'), + constance_env( + env.str, + 'CONSTANCE_SUPPORT_URL', + 'KOBO_SUPPORT_URL', + 'https://support.kobotoolbox.org/', + ), 'URL for "KoboToolbox Help Center"', ), 'ACADEMY_URL': ( - env.str('KOBO_ACADEMY_URL', 'https://academy.kobotoolbox.org/'), + constance_env( + env.str, + 'CONSTANCE_ACADEMY_URL', + 'KOBO_ACADEMY_URL', + 'https://academy.kobotoolbox.org/', + ), 'URL for "KoboToolbox Community Forum"', ), 'COMMUNITY_URL': ( - env.str( - 'KOBO_COMMUNITY_URL', 'https://community.kobotoolbox.org/' + constance_env( + env.str, + 'CONSTANCE_COMMUNITY_URL', + 'KOBO_COMMUNITY_URL', + 'https://community.kobotoolbox.org/', ), 'URL for "KoboToolbox Community Forum"', ), @@ -328,7 +347,12 @@ 'Require MFA for superusers with a usable password', ), 'USAGE_LIMIT_ENFORCEMENT': ( - env.bool('USAGE_LIMIT_ENFORCEMENT', False), + constance_env( + env.bool, + 'CONSTANCE_USAGE_LIMIT_ENFORCEMENT', + 'USAGE_LIMIT_ENFORCEMENT', + False, + ), 'For Stripe-enabled instances, determines whether usage limits will be enforced' 'by blocking submissions/NLP actions or deleting stored files.', ), @@ -345,10 +369,6 @@ ' the operations API. ' ) ), - # We are adopting the `CONSTANCE_` prefix as the new standard for all env - # variables that override Constance defaults. Legacy variables (e.g., KOBO_*) - # will be deprecated and migrated to this new pattern after the upcoming - # migration to Constance 4.x 'ASR_MT_GOOGLE_PROJECT_ID': ( env.str('CONSTANCE_ASR_MT_GOOGLE_PROJECT_ID', 'kobo-asr-mt'), 'ID of the Google Cloud project used to access ASR/MT APIs', @@ -1255,16 +1275,6 @@ def __init__(self, *args, **kwargs): STRIPE_ENABLED = env.bool('STRIPE_ENABLED', False) -def dj_stripe_request_callback_method(): - # This method exists because dj-stripe's documentation doesn't reflect reality. - # It claims that DJSTRIPE_SUBSCRIBER_MODEL no longer needs a request callback but - # this error occurs without it: `DJSTRIPE_SUBSCRIBER_MODEL_REQUEST_CALLBACK must - # be implemented if a DJSTRIPE_SUBSCRIBER_MODEL is defined` - # It doesn't need to do anything other than exist - # https://github.com/dj-stripe/dj-stripe/issues/1900 - pass - - BULK_ACTION_RATE_LIMITS = { 'automatic_google_transcription': { 'max_jobs_per_minute': 120, diff --git a/kobo/settings/utils.py b/kobo/settings/utils.py new file mode 100644 index 0000000000..7d04d4bef7 --- /dev/null +++ b/kobo/settings/utils.py @@ -0,0 +1,35 @@ +import os +import warnings +from typing import Any, Callable + + +def constance_env( + getter: Callable, + new_key: str, + deprecated_key: str, + default: Any, +) -> Any: + """ + Read a Constance override from the `CONSTANCE_`-prefixed environment + variable, falling back to its deprecated (unprefixed / `KOBO_`) name. + + Emit a `DeprecationWarning` when the deprecated name is still set so + deployments know to migrate to the `CONSTANCE_` prefix. + """ + if deprecated_key in os.environ: + warnings.warn( + f'{deprecated_key} is renamed {new_key}, ' + f'update the environment variable.', + DeprecationWarning, + ) + return getter(new_key, getter(deprecated_key, default)) + + +def dj_stripe_request_callback_method(): + # This method exists because dj-stripe's documentation doesn't reflect reality. + # It claims that DJSTRIPE_SUBSCRIBER_MODEL no longer needs a request callback but + # this error occurs without it: `DJSTRIPE_SUBSCRIBER_MODEL_REQUEST_CALLBACK must + # be implemented if a DJSTRIPE_SUBSCRIBER_MODEL is defined` + # It doesn't need to do anything other than exist + # https://github.com/dj-stripe/dj-stripe/issues/1900 + pass diff --git a/pyproject.toml b/pyproject.toml index 5bb6812954..86199b39e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,11 +57,11 @@ testpaths = [ 'kpi', 'hub', ] -# Add USAGE_LIMIT_ENFORCEMENT here because setting it in +# Add CONSTANCE_USAGE_LIMIT_ENFORCEMENT here because setting it in # test module doesn't get registered by constance env = [ 'DJANGO_SETTINGS_MODULE=kobo.settings.testing', - 'USAGE_LIMIT_ENFORCEMENT=True', + 'CONSTANCE_USAGE_LIMIT_ENFORCEMENT=True', ] addopts = [ '-m not performance',