django-resonant-settings 0.44.0__py3-none-any.whl → 0.45.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {django_resonant_settings-0.44.0.dist-info → django_resonant_settings-0.45.0.dist-info}/METADATA +3 -2
  2. django_resonant_settings-0.45.0.dist-info/RECORD +32 -0
  3. resonant_settings/_env.py +2 -0
  4. resonant_settings/allauth.py +16 -9
  5. resonant_settings/allauth_support/adapter.py +9 -3
  6. resonant_settings/allauth_support/apps.py +2 -0
  7. resonant_settings/allauth_support/createsuperuser.py +6 -6
  8. resonant_settings/allauth_support/management/__init__.py +0 -0
  9. resonant_settings/allauth_support/management/commands/__init__.py +0 -0
  10. resonant_settings/allauth_support/management/commands/createsuperuser.py +8 -4
  11. resonant_settings/allauth_support/receiver.py +10 -5
  12. resonant_settings/allauth_support/utils.py +6 -2
  13. resonant_settings/celery.py +12 -8
  14. resonant_settings/development/celery.py +2 -0
  15. resonant_settings/development/debug_toolbar.py +5 -1
  16. resonant_settings/development/minio_storage.py +11 -6
  17. resonant_settings/django.py +4 -2
  18. resonant_settings/django_extensions.py +3 -1
  19. resonant_settings/logging.py +12 -5
  20. resonant_settings/oauth_toolkit.py +8 -1
  21. resonant_settings/production/email.py +3 -1
  22. resonant_settings/production/https.py +5 -3
  23. resonant_settings/production/s3_storage.py +7 -5
  24. resonant_settings/rest_framework.py +4 -2
  25. django_resonant_settings-0.44.0.dist-info/RECORD +0 -30
  26. {django_resonant_settings-0.44.0.dist-info → django_resonant_settings-0.45.0.dist-info}/WHEEL +0 -0
  27. {django_resonant_settings-0.44.0.dist-info → django_resonant_settings-0.45.0.dist-info}/licenses/LICENSE +0 -0
  28. {django_resonant_settings-0.44.0.dist-info → django_resonant_settings-0.45.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-resonant-settings
3
- Version: 0.44.0
3
+ Version: 0.45.0
4
4
  Summary: Shared Django settings for Resonant applications.
5
5
  Project-URL: Repository, https://github.com/kitware-resonant/cookiecutter-resonant
6
6
  Project-URL: Bug Reports, https://github.com/kitware-resonant/cookiecutter-resonant/issues
@@ -8,7 +8,7 @@ Maintainer-email: "Kitware, Inc." <kitware@kitware.com>
8
8
  License-Expression: Apache-2.0
9
9
  License-File: LICENSE
10
10
  License-File: NOTICE
11
- Keywords: django,resonant,setting,settings
11
+ Keywords: django,kitware-resonant,resonant,setting,settings
12
12
  Classifier: Development Status :: 3 - Alpha
13
13
  Classifier: Environment :: Web Environment
14
14
  Classifier: Framework :: Django
@@ -26,6 +26,7 @@ Classifier: Programming Language :: Python :: 3.13
26
26
  Classifier: Programming Language :: Python :: 3.14
27
27
  Requires-Python: >=3.10
28
28
  Requires-Dist: django-environ
29
+ Requires-Dist: django>=5.1
29
30
  Provides-Extra: allauth
30
31
  Requires-Dist: django-allauth; extra == 'allauth'
31
32
  Provides-Extra: celery
@@ -0,0 +1,32 @@
1
+ resonant_settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ resonant_settings/_env.py,sha256=ht6aI32tA7kP2V90V-64AKZfLp-9Hea6E0o_GatanzM,72
3
+ resonant_settings/allauth.py,sha256=QgAarv1PzkMZItDGJf1nC49IVnH1TvINTd0Gj3d-Pg8,2329
4
+ resonant_settings/celery.py,sha256=w5fs2JP7EuEJc_YtSF1rVivRbyNIXoh_s29lI3EeUlU,3627
5
+ resonant_settings/django.py,sha256=ai5qaFIMzO01B5kznCIw52Qhq_kCXMlWEuvvj0c8yXc,1703
6
+ resonant_settings/django_extensions.py,sha256=ZYV7D0HK6vrzocxpPuynh_Tq95UwJagORVyJYmzVHN0,365
7
+ resonant_settings/logging.py,sha256=B3SFyrZKcwBTtoQQM2SCg42WmkMILouCAoXZxebzM7s,2980
8
+ resonant_settings/oauth_toolkit.py,sha256=QRslA-Bou7cGVru8nYO3CwGRNUWX9pIzwGM9NMg0NdU,1972
9
+ resonant_settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ resonant_settings/rest_framework.py,sha256=QMrNCVIlp1NCrFTaA8nppQPPZFW6cv4pYRrmXlXaRsY,4885
11
+ resonant_settings/allauth_support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ resonant_settings/allauth_support/adapter.py,sha256=n5EgK1mtYEIMyViYD8fW0N44OVYnuDMZdwpzIwowGTc,514
13
+ resonant_settings/allauth_support/apps.py,sha256=z1kBqEIWuPydEQIC2vx8v2CoMn5HjfSGL3-eAmhT1jQ,220
14
+ resonant_settings/allauth_support/createsuperuser.py,sha256=_DDioR5UtKXkmKiRbPk7pSJvV57ugj-gYv2QMc6Q1Hw,3334
15
+ resonant_settings/allauth_support/receiver.py,sha256=jf0goMBK_3q9OuEIzGzO5qaSA9_OOhNPsYJ2P-dE4Iw,1692
16
+ resonant_settings/allauth_support/utils.py,sha256=qDIug6D76WK5sxdZZ0QG94zOIuygGftUuUgPv5fGul0,571
17
+ resonant_settings/allauth_support/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ resonant_settings/allauth_support/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ resonant_settings/allauth_support/management/commands/createsuperuser.py,sha256=gF5D5ZiDPy6hOb1Wtvm40u1McBpIhEa6sscHMA1H0Sk,1503
20
+ resonant_settings/development/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ resonant_settings/development/celery.py,sha256=_W1BREOfTrW-v0A5b-qL8YtU1x2o7etdLETqj-fTzt8,872
22
+ resonant_settings/development/debug_toolbar.py,sha256=eGwycE8nWfCKJTVcjs3EScaVlLZuvGthQiz2kAX3P20,557
23
+ resonant_settings/development/minio_storage.py,sha256=5tXfyRNe34rV9EPNu8OlLeb3lv7MJP0lh0fvUGyGt1M,1437
24
+ resonant_settings/production/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ resonant_settings/production/email.py,sha256=qnRl0DrvMEArUQ2q7g43I93vd4mL7zwfEoZFPQe3jZg,835
26
+ resonant_settings/production/https.py,sha256=CA0EJmAFSysoUKZXY5g0DJG3xWLRtU5D7oJIpleRk0Q,920
27
+ resonant_settings/production/s3_storage.py,sha256=xqV3ZzeNT5oHrfbTB4RiWDwF6OS8h_liSXBbrPYbNTo,1504
28
+ django_resonant_settings-0.45.0.dist-info/METADATA,sha256=9JxE9Io3ZxoctQDn3HXNdN0b0EnVpIObN0o5JCdfgvA,1836
29
+ django_resonant_settings-0.45.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
30
+ django_resonant_settings-0.45.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
31
+ django_resonant_settings-0.45.0.dist-info/licenses/NOTICE,sha256=NU8vSqFl-Z30QJ2VOCAkStAVQon47sNgE3wwz-7nQSo,585
32
+ django_resonant_settings-0.45.0.dist-info/RECORD,,
resonant_settings/_env.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import environ
2
4
 
3
5
  env = environ.Env()
@@ -1,5 +1,7 @@
1
1
  """
2
- Configure django-allauth with the following features:
2
+ Configure django-allauth.
3
+
4
+ This provides the following features:
3
5
  * Disable usernames for end users, using exclusively email addresses for login
4
6
  * Require email verification
5
7
  * Quality of life improvements for users
@@ -8,7 +10,12 @@ This requires the `django-allauth` package to be installed and requires
8
10
  `resonant_settings.allauth_support` to be added to INSTALLED_APPS.
9
11
  """
10
12
 
11
- from collections.abc import Sequence
13
+ from __future__ import annotations
14
+
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Sequence
12
19
 
13
20
  # The sites framework requires this to be set.
14
21
  # In the unlikely case where a database's pk sequence for the django_site table is not reset,
@@ -49,16 +56,16 @@ ACCOUNT_CONFIRM_EMAIL_ON_GET = True
49
56
  ACCOUNT_PRESERVE_USERNAME_CASING = False
50
57
 
51
58
  __all__ = [
52
- "SITE_ID",
53
- "AUTHENTICATION_BACKENDS",
59
+ "ACCOUNT_ADAPTER",
60
+ "ACCOUNT_CONFIRM_EMAIL_ON_GET",
54
61
  "ACCOUNT_EMAIL_VERIFICATION",
55
62
  "ACCOUNT_LOGIN_METHODS",
56
- "ACCOUNT_SIGNUP_FIELDS",
57
- "ACCOUNT_ADAPTER",
58
- "ACCOUNT_USER_MODEL_USERNAME_FIELD",
59
- "ACCOUNT_SESSION_REMEMBER",
60
63
  "ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION",
61
64
  "ACCOUNT_LOGIN_ON_PASSWORD_RESET",
62
- "ACCOUNT_CONFIRM_EMAIL_ON_GET",
63
65
  "ACCOUNT_PRESERVE_USERNAME_CASING",
66
+ "ACCOUNT_SESSION_REMEMBER",
67
+ "ACCOUNT_SIGNUP_FIELDS",
68
+ "ACCOUNT_USER_MODEL_USERNAME_FIELD",
69
+ "AUTHENTICATION_BACKENDS",
70
+ "SITE_ID",
64
71
  ]
@@ -1,9 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
1
5
  from allauth.account.adapter import DefaultAccountAdapter
2
- from django.contrib.auth.models import AbstractUser
3
- from django.http import HttpRequest
6
+
7
+ if TYPE_CHECKING:
8
+ from django.contrib.auth.models import AbstractUser
9
+ from django.http import HttpRequest
4
10
 
5
11
 
6
- class EmailAsUsernameAccountAdapter(DefaultAccountAdapter):
12
+ class EmailAsUsernameAccountAdapter(DefaultAccountAdapter): # type: ignore[misc]
7
13
  """Automatically populate the username as the email address."""
8
14
 
9
15
  def populate_username(self, request: HttpRequest, user: AbstractUser) -> None:
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from django.apps import AppConfig
2
4
 
3
5
 
@@ -31,12 +31,12 @@ class Command(createsuperuser.Command):
31
31
  with temporarily_change_attributes(self.username_field, _unique=True):
32
32
  # Normalize (as it would be done before saving) for better duplicate detection
33
33
  username = self.UserModel.normalize_username(username)
34
- return super()._validate_username( # type: ignore[misc]
34
+ return super()._validate_username( # type: ignore[misc,no-any-return]
35
35
  username, verbose_field_name, database
36
36
  )
37
37
 
38
38
 
39
- class EmailAsUsernameProxyUserManager(UserManager):
39
+ class EmailAsUsernameProxyUserManager(UserManager["EmailAsUsernameProxyUser"]):
40
40
  # This version of "create_superuser" makes the "username" argument optional
41
41
  def create_superuser(
42
42
  self,
@@ -46,16 +46,16 @@ class EmailAsUsernameProxyUserManager(UserManager):
46
46
  **extra_fields: Any,
47
47
  ) -> EmailAsUsernameProxyUser:
48
48
  # Practically, email will always be provided
49
- assert email
50
- user = super().create_superuser(
49
+ if email is None:
50
+ raise ValueError("Email address must be provided.")
51
+ return super().create_superuser(
51
52
  username=email, email=email, password=password, **extra_fields
52
53
  )
53
- return user
54
54
 
55
55
 
56
56
  class EmailAsUsernameProxyUser(User):
57
57
  # https://github.com/typeddjango/django-stubs/issues/2112
58
- class Meta(User.Meta): # type: ignore[name-defined]
58
+ class Meta(User.Meta): # type: ignore[misc,name-defined]
59
59
  proxy = True
60
60
 
61
61
  objects = EmailAsUsernameProxyUserManager()
@@ -1,15 +1,19 @@
1
- from typing import cast
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, cast
2
4
 
3
5
  from allauth.account import app_settings as allauth_settings
4
6
  from django.contrib.auth import get_user_model
5
7
  from django.contrib.auth.management.commands import createsuperuser as django_createsuperuser
6
- from django.contrib.auth.models import AbstractUser
7
- from django.core.management import BaseCommand
8
8
  from django.db.models.signals import post_save
9
9
 
10
10
  from resonant_settings.allauth_support import createsuperuser as allauth_support_createsuperuser
11
11
  from resonant_settings.allauth_support.receiver import verify_email_address_on_user_post_save
12
12
 
13
+ if TYPE_CHECKING:
14
+ from django.contrib.auth.models import AbstractUser
15
+ from django.core.management import BaseCommand
16
+
13
17
  """
14
18
  When Allauth is configured to use a User's `email` as the `username`, override the `createsuperuser`
15
19
  management command to only prompt for an email address.
@@ -28,7 +32,7 @@ if not username_required:
28
32
  else:
29
33
  # Expose the pristine upstream version of the command
30
34
  Command = django_createsuperuser.Command
31
- user_model = cast(type[AbstractUser], get_user_model())
35
+ user_model = cast("type[AbstractUser]", get_user_model())
32
36
 
33
37
  # Always automatically verify email addresses of newly created superusers
34
38
  post_save.connect(verify_email_address_on_user_post_save, sender=user_model)
@@ -1,13 +1,18 @@
1
+ from __future__ import annotations
2
+
1
3
  import logging
2
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
3
5
 
4
6
  from allauth.account.models import EmailAddress
5
- from django.contrib.auth.models import AbstractUser
6
7
 
7
- logger = logging.getLogger(__file__)
8
+ if TYPE_CHECKING:
9
+ from django.contrib.auth.models import AbstractUser
10
+
11
+ logger = logging.getLogger(__name__)
8
12
 
9
13
 
10
14
  def verify_email_address_on_user_post_save(
15
+ *,
11
16
  sender: type[AbstractUser],
12
17
  instance: AbstractUser,
13
18
  created: bool,
@@ -25,7 +30,7 @@ def verify_email_address_on_user_post_save(
25
30
  # uniqueness.
26
31
  # So, make a conservative effort at setting the email address as verified, since failure is
27
32
  # not critical and can be resolved by the user.
28
- email_address, created = EmailAddress.objects.get_or_create(
33
+ _email_address, created = EmailAddress.objects.get_or_create(
29
34
  email__iexact=instance.email,
30
35
  defaults={
31
36
  "user": instance,
@@ -35,4 +40,4 @@ def verify_email_address_on_user_post_save(
35
40
  },
36
41
  )
37
42
  if not created:
38
- logger.warning(f'Could not automatically verify email address "{instance.email}".')
43
+ logger.warning('Could not automatically verify email address "%s".', instance.email)
@@ -1,6 +1,10 @@
1
- from collections.abc import Generator
1
+ from __future__ import annotations
2
+
2
3
  from contextlib import contextmanager
3
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ if TYPE_CHECKING:
7
+ from collections.abc import Generator
4
8
 
5
9
 
6
10
  # From https://stackoverflow.com/a/38532086
@@ -1,5 +1,7 @@
1
1
  """
2
- Configure Celery with the following features:
2
+ Configure Celery.
3
+
4
+ This provides the following features:
3
5
  * Disable the results backend
4
6
  * Ensure that tasks will never be lost, but tasks themselves must be idempotent
5
7
  * Optimize the network connection to CloudAMQP
@@ -7,7 +9,9 @@ Configure Celery with the following features:
7
9
  This requires the `celery` package to be installed.
8
10
  """
9
11
 
10
- import celery.app.trace # type: ignore[import-not-found]
12
+ from __future__ import annotations
13
+
14
+ import celery.app.trace
11
15
 
12
16
  from resonant_settings._env import env
13
17
 
@@ -71,16 +75,16 @@ Task %(name)s[%(id)s] received: (%(args)s, %(kwargs)s)\
71
75
  """
72
76
 
73
77
  __all__ = [
78
+ "CELERY_BROKER_CONNECTION_TIMEOUT",
79
+ "CELERY_BROKER_HEARTBEAT",
80
+ "CELERY_BROKER_POOL_LIMIT",
74
81
  "CELERY_BROKER_URL",
82
+ "CELERY_EVENT_QUEUE_EXPIRES",
75
83
  "CELERY_RESULT_BACKEND",
76
84
  "CELERY_TASK_ACKS_LATE",
77
- "CELERY_TASK_REJECT_ON_WORKER_LOST",
78
85
  "CELERY_TASK_ACKS_ON_FAILURE_OR_TIMEOUT",
86
+ "CELERY_TASK_REJECT_ON_WORKER_LOST",
79
87
  "CELERY_WORKER_CANCEL_LONG_RUNNING_TASKS_ON_CONNECTION_LOSS",
80
- "CELERY_BROKER_POOL_LIMIT",
81
- "CELERY_BROKER_HEARTBEAT",
82
- "CELERY_BROKER_CONNECTION_TIMEOUT",
83
- "CELERY_EVENT_QUEUE_EXPIRES",
84
- "CELERY_WORKER_PREFETCH_MULTIPLIER",
85
88
  "CELERY_WORKER_CONCURRENCY",
89
+ "CELERY_WORKER_PREFETCH_MULTIPLIER",
86
90
  ]
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  from resonant_settings._env import env
2
4
 
3
5
  # Acknowledge early in development, which will help prevent failing or
@@ -1,10 +1,14 @@
1
1
  """
2
- Configure Django Debug Toolbar with the following features:
2
+ Configure Django Debug Toolbar.
3
+
4
+ This provides the following features:
3
5
  * Improve performance with large queries
4
6
 
5
7
  This requires the `django-debug-toolbar` package to be installed.
6
8
  """
7
9
 
10
+ from __future__ import annotations
11
+
8
12
  from typing import Any
9
13
 
10
14
  DEBUG_TOOLBAR_CONFIG: dict[str, Any] = {
@@ -4,10 +4,15 @@ Configure MinioMediaStorage.
4
4
  This requires the `django-minio-storage` package to be installed.
5
5
  """
6
6
 
7
- from urllib.parse import ParseResult
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
8
10
 
9
11
  from resonant_settings._env import env
10
12
 
13
+ if TYPE_CHECKING:
14
+ from urllib.parse import ParseResult
15
+
11
16
  minio_url: ParseResult = env.url("DJANGO_MINIO_STORAGE_URL")
12
17
  MINIO_STORAGE_USE_HTTPS = minio_url.scheme == "https"
13
18
  MINIO_STORAGE_ENDPOINT = (
@@ -28,13 +33,13 @@ MINIO_STORAGE_AUTO_CREATE_MEDIA_POLICY = "NONE"
28
33
  MINIO_STORAGE_MEDIA_USE_PRESIGNED = True
29
34
 
30
35
  __all__ = [
31
- "MINIO_STORAGE_USE_HTTPS",
32
- "MINIO_STORAGE_ENDPOINT",
33
36
  "MINIO_STORAGE_ACCESS_KEY",
34
- "MINIO_STORAGE_SECRET_KEY",
35
- "MINIO_STORAGE_MEDIA_BUCKET_NAME",
36
- "MINIO_STORAGE_MEDIA_URL",
37
37
  "MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET",
38
38
  "MINIO_STORAGE_AUTO_CREATE_MEDIA_POLICY",
39
+ "MINIO_STORAGE_ENDPOINT",
40
+ "MINIO_STORAGE_MEDIA_BUCKET_NAME",
41
+ "MINIO_STORAGE_MEDIA_URL",
39
42
  "MINIO_STORAGE_MEDIA_USE_PRESIGNED",
43
+ "MINIO_STORAGE_SECRET_KEY",
44
+ "MINIO_STORAGE_USE_HTTPS",
40
45
  ]
@@ -1,5 +1,7 @@
1
1
  """Configure a basic Django project."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from typing import Any
4
6
 
5
7
  TEMPLATES: list[dict[str, Any]] = [
@@ -37,7 +39,7 @@ AUTH_PASSWORD_VALIDATORS: list[dict[str, str]] = [
37
39
  ]
38
40
 
39
41
  __all__ = [
40
- "TEMPLATES",
41
- "PASSWORD_HASHERS",
42
42
  "AUTH_PASSWORD_VALIDATORS",
43
+ "PASSWORD_HASHERS",
44
+ "TEMPLATES",
43
45
  ]
@@ -4,12 +4,14 @@ Configure Django Extensions.
4
4
  This requires the `django-extensions` package to be installed.
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  SHELL_PLUS_PRINT_SQL = True
8
10
  SHELL_PLUS_PRINT_SQL_TRUNCATE = None
9
11
  RUNSERVER_PLUS_PRINT_SQL_TRUNCATE = None
10
12
 
11
13
  __all__ = [
14
+ "RUNSERVER_PLUS_PRINT_SQL_TRUNCATE",
12
15
  "SHELL_PLUS_PRINT_SQL",
13
16
  "SHELL_PLUS_PRINT_SQL_TRUNCATE",
14
- "RUNSERVER_PLUS_PRINT_SQL_TRUNCATE",
15
17
  ]
@@ -1,5 +1,7 @@
1
1
  """
2
- Configure Django logging with the following features:
2
+ Configure Django logging.
3
+
4
+ This provides the following features:
3
5
  * Emit all logs to stdout
4
6
  * Exclude favicons and static files from request and server logs
5
7
  * Improve log formatting and add colorization
@@ -7,9 +9,14 @@ Configure Django logging with the following features:
7
9
  This requires the `rich` package to be installed.
8
10
  """
9
11
 
10
- import logging
12
+ from __future__ import annotations
13
+
14
+ from typing import TYPE_CHECKING
15
+
16
+ if TYPE_CHECKING:
17
+ import logging
11
18
 
12
- from django.http import HttpRequest
19
+ from django.http import HttpRequest
13
20
 
14
21
 
15
22
  def _filter_favicon_requests(record: logging.LogRecord) -> bool:
@@ -18,7 +25,7 @@ def _filter_favicon_requests(record: logging.LogRecord) -> bool:
18
25
  if request and request.path == "/favicon.ico":
19
26
  return False
20
27
 
21
- if (
28
+ if ( # noqa: SIM103
22
29
  record.name == "django.server"
23
30
  and isinstance(record.args, tuple)
24
31
  and len(record.args) >= 1
@@ -30,7 +37,7 @@ def _filter_favicon_requests(record: logging.LogRecord) -> bool:
30
37
 
31
38
 
32
39
  def _filter_static_requests(record: logging.LogRecord) -> bool:
33
- if (
40
+ if ( # noqa: SIM103
34
41
  record.name == "django.server"
35
42
  and isinstance(record.args, tuple)
36
43
  and len(record.args) >= 1
@@ -1,5 +1,7 @@
1
1
  """
2
- Configure Django OAuth Toolkit with the following features:
2
+ Configure Django OAuth Toolkit.
3
+
4
+ This provides the following features:
3
5
  * Harden security
4
6
  * Improve usability of token scopes
5
7
  * Improve quality of live for out of band flows and non-refreshing clients
@@ -7,11 +9,16 @@ Configure Django OAuth Toolkit with the following features:
7
9
  This requires the `django-oauth-toolkit` package to be installed.
8
10
  """
9
11
 
12
+ from __future__ import annotations
13
+
10
14
  from datetime import timedelta
11
15
  from typing import Any
12
16
 
13
17
  OAUTH2_PROVIDER: dict[str, Any] = {
14
18
  "ALLOWED_REDIRECT_URI_SCHEMES": ["https"],
19
+ # This doesn't immediately change behavior, it just authorizes the use of wildcards in
20
+ # Application redirect URIs, which is necessary to support SPA branch previews
21
+ "ALLOW_URI_WILDCARDS": True,
15
22
  # Don't require users to re-approve scopes each time
16
23
  "REQUEST_APPROVAL_PROMPT": "auto",
17
24
  # ERROR_RESPONSE_WITH_SCOPES is only used with the "permission_classes" helpers for scopes.
@@ -8,6 +8,8 @@ The following environment variables must be externally set:
8
8
  * `DJANGO_DEFAULT_FROM_EMAIL`, as the default From address for outgoing email.
9
9
  """
10
10
 
11
+ from __future__ import annotations
12
+
11
13
  from typing import Any
12
14
 
13
15
  from resonant_settings._env import env
@@ -19,7 +21,7 @@ DEFAULT_FROM_EMAIL: str = env.str("DJANGO_DEFAULT_FROM_EMAIL")
19
21
  SERVER_EMAIL = DEFAULT_FROM_EMAIL
20
22
 
21
23
 
22
- __all__ = [
24
+ __all__ = [ # noqa: PLE0604
23
25
  *email_config.keys(),
24
26
  "DEFAULT_FROM_EMAIL",
25
27
  "SERVER_EMAIL",
@@ -1,5 +1,7 @@
1
1
  """Configure Django's security middleware to use and require HTTPS."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from datetime import timedelta
4
6
 
5
7
  SECURE_SSL_REDIRECT = True
@@ -18,10 +20,10 @@ SECURE_HSTS_INCLUDE_SUBDOMAINS = False
18
20
  SECURE_HSTS_PRELOAD = False
19
21
 
20
22
  __all__ = [
21
- "SECURE_SSL_REDIRECT",
22
- "SESSION_COOKIE_SECURE",
23
23
  "CSRF_COOKIE_SECURE",
24
- "SECURE_HSTS_SECONDS",
25
24
  "SECURE_HSTS_INCLUDE_SUBDOMAINS",
26
25
  "SECURE_HSTS_PRELOAD",
26
+ "SECURE_HSTS_SECONDS",
27
+ "SECURE_SSL_REDIRECT",
28
+ "SESSION_COOKIE_SECURE",
27
29
  ]
@@ -10,6 +10,8 @@ The following environment variables must be externally set:
10
10
  This requires the `django-storages[s3]` package to be installed.
11
11
  """
12
12
 
13
+ from __future__ import annotations
14
+
13
15
  from datetime import timedelta
14
16
 
15
17
  from resonant_settings._env import env
@@ -35,12 +37,12 @@ AWS_S3_FILE_OVERWRITE = True
35
37
  AWS_QUERYSTRING_EXPIRE = int(timedelta(hours=6).total_seconds())
36
38
 
37
39
  __all__ = [
38
- "AWS_S3_REGION_NAME",
40
+ "AWS_QUERYSTRING_EXPIRE",
39
41
  "AWS_S3_ACCESS_KEY_ID",
42
+ "AWS_S3_FILE_OVERWRITE",
43
+ "AWS_S3_MAX_MEMORY_SIZE",
44
+ "AWS_S3_REGION_NAME",
40
45
  "AWS_S3_SECRET_ACCESS_KEY",
41
- "AWS_STORAGE_BUCKET_NAME",
42
46
  "AWS_S3_SIGNATURE_VERSION",
43
- "AWS_S3_MAX_MEMORY_SIZE",
44
- "AWS_S3_FILE_OVERWRITE",
45
- "AWS_QUERYSTRING_EXPIRE",
47
+ "AWS_STORAGE_BUCKET_NAME",
46
48
  ]
@@ -4,6 +4,8 @@ Configure Django REST framework and drf-yasg.
4
4
  This requires the `django-oauth-toolkit` and `drf-yasg` packages to be installed.
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  from typing import Any
8
10
 
9
11
  # When SessionAuthentication is allowed, it's critical that the following settings
@@ -77,9 +79,9 @@ SWAGGER_SETTINGS: dict[str, Any] = {
77
79
  REDOC_SETTINGS: dict[str, Any] = {}
78
80
 
79
81
  __all__ = [
80
- "SESSION_COOKIE_SAMESITE",
81
82
  "CORS_ALLOW_CREDENTIALS",
83
+ "REDOC_SETTINGS",
82
84
  "REST_FRAMEWORK",
85
+ "SESSION_COOKIE_SAMESITE",
83
86
  "SWAGGER_SETTINGS",
84
- "REDOC_SETTINGS",
85
87
  ]
@@ -1,30 +0,0 @@
1
- resonant_settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- resonant_settings/_env.py,sha256=TA97UtDkh7tgBIPc92Osj4FtrBfzMTCmBQ6UR1dPHEk,36
3
- resonant_settings/allauth.py,sha256=V2HRE3GRHxcpXhrDPtSvhL00SLGIzQQNVhf6NTvJYiY,2226
4
- resonant_settings/celery.py,sha256=Ab2Ugv-7VORzPilCTorz_Pn9rxWBtxMcjXzDHJmgJHI,3614
5
- resonant_settings/django.py,sha256=ARxmU_nLpyAPE46MFWWRFz6iCNf4Y4KMpsTG63-YlME,1667
6
- resonant_settings/django_extensions.py,sha256=aHR6S76Et71O5-KiMapmr-UjOMm7wBHmmZ23gpGdkcs,329
7
- resonant_settings/logging.py,sha256=f9zCDedg7yKBLnkl_yHxxjolzJjlm4VERoGPcNuerE4,2841
8
- resonant_settings/oauth_toolkit.py,sha256=wgUntzfpR5pcQvtewNS8mdGK_ZE8hdw6PJWoFq-dBHI,1718
9
- resonant_settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- resonant_settings/rest_framework.py,sha256=9jNfFJ8EC-IINTVW41nR8eYtIDsMyD3Ly3k3kOsJ18M,4849
11
- resonant_settings/allauth_support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- resonant_settings/allauth_support/adapter.py,sha256=GSyublJa-2ZCIY_Adb2A0NOoVAtZUuZxB9ZkA5nl66o,395
13
- resonant_settings/allauth_support/apps.py,sha256=aMx4hSBL9xOMTr5E93rjsW5QUi6m2iNFuz_Ld4isihA,184
14
- resonant_settings/allauth_support/createsuperuser.py,sha256=OkpnGXdFLLj21KHAPQgN3Tt1g5Y5-FuEgPsC4vdTlQE,3238
15
- resonant_settings/allauth_support/receiver.py,sha256=NlMMLIIWsz-psIgaqKltsjP9H76czu1OAIseYvtDYiI,1609
16
- resonant_settings/allauth_support/utils.py,sha256=1nhH8p8-YqdUUoHQixxYIANveKAqaNE8phzvN3abNp0,497
17
- resonant_settings/allauth_support/management/commands/createsuperuser.py,sha256=61gF3oxhYXbnn49w78rl9SvZOE28tSLmBNVmGNOaexQ,1423
18
- resonant_settings/development/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- resonant_settings/development/celery.py,sha256=ryNLZcj0oKzGpaVhKJVE3wQBOXwy1jRR6o1PNsyyQAg,836
20
- resonant_settings/development/debug_toolbar.py,sha256=kIapv6Jkpf205M5i33IyqnAcijNd3ctwcv6W6B3cfsc,510
21
- resonant_settings/development/minio_storage.py,sha256=SlrnVDfm5YfjXcTpdPe2Pzbmw4wLSwWp7ryWoghk3Do,1345
22
- resonant_settings/production/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- resonant_settings/production/email.py,sha256=TkiGaMq-7db7WfBeavYvBNt2nq0G9mneTUXRb13fo4Y,782
24
- resonant_settings/production/https.py,sha256=rACQoCN0bdUFRVtr-MJmMiOmk56qieZz24atn4rqUXg,884
25
- resonant_settings/production/s3_storage.py,sha256=rL05dCx49Xszwydp8i3QuRiP8dlxK0qnX55-0zn1rCQ,1468
26
- django_resonant_settings-0.44.0.dist-info/METADATA,sha256=Hj2FT9d4uRkqpAUMIw2iyBtqUEWKX0Gm7ivYdNzs2Qc,1792
27
- django_resonant_settings-0.44.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
28
- django_resonant_settings-0.44.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
29
- django_resonant_settings-0.44.0.dist-info/licenses/NOTICE,sha256=NU8vSqFl-Z30QJ2VOCAkStAVQon47sNgE3wwz-7nQSo,585
30
- django_resonant_settings-0.44.0.dist-info/RECORD,,