Home

mint @main - refs - log -
-
https://git.jolheiser.com/mint.git
Budget
tree log patch
whitenoise: init Signed-off-by: jolheiser <git@jolheiser.com>
Signature
-----BEGIN SSH SIGNATURE----- U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgBTEvCQk6VqUAdN2RuH6bj1dNkY oOpbPWj+jw4ua1B1cAAAADZ2l0AAAAAAAAAAZzaGE1MTIAAABTAAAAC3NzaC1lZDI1NTE5 AAAAQMapNqeHv3RfIjZ+lITR6mMcZQ12Vcs+89/nTKuclUF8VC06ouHzRrt3R1LD/bbw/H EZSMP5pK0Nwt4ajBd8hAE= -----END SSH SIGNATURE-----
jolheiser <git@jolheiser.com>
12 hours ago
12 changed files, 119 additions(+), 21 deletions(-)
budget/migrations/0001_initial.pybudget/models.pymanage.pymint/asgi.pymint/auth.pymint/settings.pymint/urls.pymint/wsgi.pynix/pkg.nixnix/vm.nixpyproject.tomluv.lock
M budget/migrations/0001_initial.py -> budget/migrations/0001_initial.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
diff --git a/budget/migrations/0001_initial.py b/budget/migrations/0001_initial.py
index ccf99605b734a01fe8580cff7801522b8277fc37..69931e698ccedf6ab4aa9ed6daf295d852c589a0 100644
--- a/budget/migrations/0001_initial.py
+++ b/budget/migrations/0001_initial.py
@@ -4,23 +4,36 @@ from django.db import migrations, models
 
 
 class Migration(migrations.Migration):
-
     initial = True
 
-    dependencies = [
-    ]
+    dependencies = []
 
     operations = [
         migrations.CreateModel(
-            name='Transaction',
+            name="Transaction",
             fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('title', models.CharField(max_length=100)),
-                ('cents', models.BigIntegerField()),
-                ('date', models.DateField()),
-                ('recurrence', models.CharField(choices=[('M', 'Monthly'), ('W', 'Weekly')], db_comment='M (Monthly) | W (Weekly)', max_length=1)),
-                ('week', models.IntegerField()),
-                ('is_income', models.BooleanField(default=False)),
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("title", models.CharField(max_length=100)),
+                ("cents", models.BigIntegerField()),
+                ("date", models.DateField()),
+                (
+                    "recurrence",
+                    models.CharField(
+                        choices=[("M", "Monthly"), ("W", "Weekly")],
+                        db_comment="M (Monthly) | W (Weekly)",
+                        max_length=1,
+                    ),
+                ),
+                ("week", models.IntegerField()),
+                ("is_income", models.BooleanField(default=False)),
             ],
         ),
     ]
M budget/models.py -> budget/models.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
diff --git a/budget/models.py b/budget/models.py
index 57ecf52b8360a7e988b42509bdbe0ee3fddd4a1c..ec9f3a532460ff2be2bbf1a5428a4c83377709b6 100644
--- a/budget/models.py
+++ b/budget/models.py
@@ -10,11 +10,14 @@     @staticmethod
     def comment() -> str:
         return " | ".join([f"{v[0]} ({v[1]})" for v in Recurrence.choices])
 
+
 class Transaction(models.Model):
     title = models.CharField(max_length=100)
     cents = models.BigIntegerField()
     date = models.DateField()
-    recurrence = models.CharField(max_length=1, choices=Recurrence.choices, db_comment=Recurrence.comment())
+    recurrence = models.CharField(
+        max_length=1, choices=Recurrence.choices, db_comment=Recurrence.comment()
+    )
     week = models.IntegerField()
     is_income = models.BooleanField(default=False)
 
M manage.py -> manage.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
diff --git a/manage.py b/manage.py
index 1429594ccdc4fa8d588d749dadacad42c902394a..1e7864b4669a0bec83ada6dfd31c14b1f78ea77c 100755
--- a/manage.py
+++ b/manage.py
@@ -1,12 +1,13 @@
 #!/usr/bin/env python
 """Django's command-line utility for administrative tasks."""
+
 import os
 import sys
 
 
 def main():
     """Run administrative tasks."""
-    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mint.settings')
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mint.settings")
     try:
         from django.core.management import execute_from_command_line
     except ImportError as exc:
@@ -18,5 +19,5 @@         ) from exc
     execute_from_command_line(sys.argv)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
M mint/asgi.py -> mint/asgi.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/mint/asgi.py b/mint/asgi.py
index 2a1b6fee8a9ad5fef5cb8bc2e605764659d2340d..953f0d88b5c96cf046397cc8f894747393cbfa25 100644
--- a/mint/asgi.py
+++ b/mint/asgi.py
@@ -11,6 +11,6 @@ import os
 
 from django.core.asgi import get_asgi_application
 
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mint.settings')
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mint.settings")
 
 application = get_asgi_application()
M mint/auth.py -> mint/auth.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
diff --git a/mint/auth.py b/mint/auth.py
index c0ef96793a04f36860a516b96fe9fc67bc382008..4d7917ae83582392313790be41dbd9b27bee356d 100644
--- a/mint/auth.py
+++ b/mint/auth.py
@@ -1,4 +1,8 @@
+from django.conf import settings
+from django.contrib.auth import get_user_model, login
+from django.contrib.auth.models import User, AnonymousUser
 from mozilla_django_oidc.auth import OIDCAuthenticationBackend
+from django.contrib.auth.backends import BaseBackend
 
 
 class MintOIDCBackend(OIDCAuthenticationBackend):
@@ -26,3 +30,22 @@
     def update_user(self, user, claims):
         self._check_admin(user, claims)
         return user
+
+
+class MintNoAuthMiddleware:
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):
+        if isinstance(request.user, AnonymousUser):
+            User = get_user_model()
+            user, _ = User.objects.get_or_create(
+                username="admin",
+                defaults={
+                    "email": "admin@example.com",
+                    "is_staff": True,
+                    "is_superuser": True,
+                },
+            )
+            login(request, user, backend="django.contrib.auth.backends.ModelBackend")
+        return self.get_response(request)
M mint/settings.py -> mint/settings.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
diff --git a/mint/settings.py b/mint/settings.py
index 722a005e3896f5275c4b959e6fe0c7b2390e142f..a36840bfa40cac94abc323403234b78c0f7304a5 100644
--- a/mint/settings.py
+++ b/mint/settings.py
@@ -19,6 +19,7 @@     "django.contrib.auth",
     "django.contrib.contenttypes",
     "django.contrib.sessions",
     "django.contrib.messages",
+    "whitenoise.runserver_nostatic",
     "django.contrib.staticfiles",
     "mozilla_django_oidc",
     "budget",
@@ -26,6 +27,7 @@ ]
 
 MIDDLEWARE = [
     "django.middleware.security.SecurityMiddleware",
+    "whitenoise.middleware.WhiteNoiseMiddleware",
     "django.contrib.sessions.middleware.SessionMiddleware",
     "django.middleware.common.CommonMiddleware",
     "django.middleware.csrf.CsrfViewMiddleware",
@@ -50,6 +52,12 @@             ],
         },
     },
 ]
+
+STORAGES = {
+    "staticfiles": {
+        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
+    },
+}
 
 WSGI_APPLICATION = "mint.wsgi.application"
 
@@ -109,6 +117,10 @@ OIDC_OP_USER_ENDPOINT = resp.get("userinfo_endpoint", "")
 OIDC_OP_TOKEN_ENDPOINT = resp.get("token_endpoint", "")
 OIDC_OP_JWKS_ENDPOINT = resp.get("jwks_uri", "")
 OIDC_RP_SCOPES = "openid email profile groups"
+
+NO_AUTH = env.bool("NO_AUTH", False)
+if NO_AUTH:
+    MIDDLEWARE.append("mint.auth.MintNoAuthMiddleware")
 
 if DEBUG:
     INTERNAL_IPS = ["127.0.0.1"]
M mint/urls.py -> mint/urls.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
diff --git a/mint/urls.py b/mint/urls.py
index 09744c736b23f5c2b659a663c485341520ca8d2b..6c9bddc903e5f71dedeca15b007a50ea4acf74a0 100644
--- a/mint/urls.py
+++ b/mint/urls.py
@@ -1,4 +1,3 @@
-
 from django.conf import settings
 from django.conf.urls.static import static
 from django.contrib import admin
@@ -10,7 +9,6 @@     path("", IndexView.as_view(), name="index"),
     path("events/", EventsView.as_view(), name="events"),
     path("transaction/", TransactionView.as_view(), name="transaction"),
     path("copy/", CopyView.as_view(), name="copy"),
-
     path("admin/", admin.site.urls),
     path("oidc/", include("mozilla_django_oidc.urls")),
 ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
@@ -18,6 +16,7 @@
 if settings.DEBUG:
     try:
         from debug_toolbar.toolbar import debug_toolbar_urls
+
         urlpatterns += debug_toolbar_urls()
     except:
         pass
M mint/wsgi.py -> mint/wsgi.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/mint/wsgi.py b/mint/wsgi.py
index 35bacd54fdb443ce992b3a2ab18d898c7020321c..49f42c6d99fc55ef1b496bddd185c7129621517f 100644
--- a/mint/wsgi.py
+++ b/mint/wsgi.py
@@ -11,6 +11,6 @@ import os
 
 from django.core.wsgi import get_wsgi_application
 
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mint.settings')
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mint.settings")
 
 application = get_wsgi_application()
M nix/pkg.nix -> nix/pkg.nix
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/nix/pkg.nix b/nix/pkg.nix
index 6b4a6d251edcf41c874e9be3ab76c7e43ec6f22d..ef0c556b4d3f7fb284ae367661610a56a05134b3 100644
--- a/nix/pkg.nix
+++ b/nix/pkg.nix
@@ -29,6 +29,7 @@
     setuptools
     environs
     requests
+    whitenoise
 
     django
     django-debug-toolbar
M nix/vm.nix -> nix/vm.nix
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/nix/vm.nix b/nix/vm.nix
index ca4bbf8b3d6c39ae735ae134ed1561a23007cae9..fdd5937b93211debd645d7d1dcd1d5d469d4c423 100644
--- a/nix/vm.nix
+++ b/nix/vm.nix
@@ -7,6 +7,7 @@     address = "0.0.0.0";
     settings = {
       MINT_OIDC_CONFIG_URL = "";
       MINT_OIDC_CLIENT_ID = "";
+      MINT_NO_AUTH = true;
     };
     environmentFile = ./vm.env;
   };
M pyproject.toml -> pyproject.toml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
diff --git a/pyproject.toml b/pyproject.toml
index 8b1ae04ce9fc9c9cb7472e5df0d6ec0afa75e1a6..231037293c2afb51521f0792c64d4ef666e154e5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -10,6 +10,7 @@     "django-debug-toolbar>=6.0.0",
     "environs>=14.3.0",
     "mozilla-django-oidc>=4.0.1",
     "requests>=2.32.4",
+    "whitenoise[brotli]>=6.9.0",
 ]
 [build-system]
 requires = ["pdm-backend"]
M uv.lock -> uv.lock
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
diff --git a/uv.lock b/uv.lock
index 1d27f5f532b3eaa5de0ac6adcd335277cdaccc78..56a8751a4e3b14b30357169c7265f91fa4ba3fef 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,5 +1,5 @@
 version = 1
-revision = 3
+revision = 2
 requires-python = ">=3.13"
 
 [[package]]
@@ -9,6 +9,34 @@ source = { registry = "https://pypi.org/simple" }
 sdist = { url = "https://files.pythonhosted.org/packages/90/61/0aa957eec22ff70b830b22ff91f825e70e1ef732c06666a805730f28b36b/asgiref-3.9.1.tar.gz", hash = "sha256:a5ab6582236218e5ef1648f242fd9f10626cfd4de8dc377db215d5d5098e3142", size = 36870, upload-time = "2025-07-08T09:07:43.344Z" }
 wheels = [
     { url = "https://files.pythonhosted.org/packages/7c/3c/0464dcada90d5da0e71018c04a140ad6349558afb30b3051b4264cc5b965/asgiref-3.9.1-py3-none-any.whl", hash = "sha256:f3bba7092a48005b5f5bacd747d36ee4a5a61f4a269a6df590b43144355ebd2c", size = 23790, upload-time = "2025-07-08T09:07:41.548Z" },
+]
+
+[[package]]
+name = "brotli"
+version = "1.2.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632, upload-time = "2025-11-05T18:39:42.86Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/6c/d4/4ad5432ac98c73096159d9ce7ffeb82d151c2ac84adcc6168e476bb54674/brotli-1.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab", size = 861523, upload-time = "2025-11-05T18:38:34.67Z" },
+    { url = "https://files.pythonhosted.org/packages/91/9f/9cc5bd03ee68a85dc4bc89114f7067c056a3c14b3d95f171918c088bf88d/brotli-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c", size = 444289, upload-time = "2025-11-05T18:38:35.6Z" },
+    { url = "https://files.pythonhosted.org/packages/2e/b6/fe84227c56a865d16a6614e2c4722864b380cb14b13f3e6bef441e73a85a/brotli-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f", size = 1528076, upload-time = "2025-11-05T18:38:36.639Z" },
+    { url = "https://files.pythonhosted.org/packages/55/de/de4ae0aaca06c790371cf6e7ee93a024f6b4bb0568727da8c3de112e726c/brotli-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6", size = 1626880, upload-time = "2025-11-05T18:38:37.623Z" },
+    { url = "https://files.pythonhosted.org/packages/5f/16/a1b22cbea436642e071adcaf8d4b350a2ad02f5e0ad0da879a1be16188a0/brotli-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c", size = 1419737, upload-time = "2025-11-05T18:38:38.729Z" },
+    { url = "https://files.pythonhosted.org/packages/46/63/c968a97cbb3bdbf7f974ef5a6ab467a2879b82afbc5ffb65b8acbb744f95/brotli-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48", size = 1484440, upload-time = "2025-11-05T18:38:39.916Z" },
+    { url = "https://files.pythonhosted.org/packages/06/9d/102c67ea5c9fc171f423e8399e585dabea29b5bc79b05572891e70013cdd/brotli-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18", size = 1593313, upload-time = "2025-11-05T18:38:41.24Z" },
+    { url = "https://files.pythonhosted.org/packages/9e/4a/9526d14fa6b87bc827ba1755a8440e214ff90de03095cacd78a64abe2b7d/brotli-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5", size = 1487945, upload-time = "2025-11-05T18:38:42.277Z" },
+    { url = "https://files.pythonhosted.org/packages/5b/e8/3fe1ffed70cbef83c5236166acaed7bb9c766509b157854c80e2f766b38c/brotli-1.2.0-cp313-cp313-win32.whl", hash = "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a", size = 334368, upload-time = "2025-11-05T18:38:43.345Z" },
+    { url = "https://files.pythonhosted.org/packages/ff/91/e739587be970a113b37b821eae8097aac5a48e5f0eca438c22e4c7dd8648/brotli-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8", size = 369116, upload-time = "2025-11-05T18:38:44.609Z" },
+    { url = "https://files.pythonhosted.org/packages/17/e1/298c2ddf786bb7347a1cd71d63a347a79e5712a7c0cba9e3c3458ebd976f/brotli-1.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21", size = 863080, upload-time = "2025-11-05T18:38:45.503Z" },
+    { url = "https://files.pythonhosted.org/packages/84/0c/aac98e286ba66868b2b3b50338ffbd85a35c7122e9531a73a37a29763d38/brotli-1.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac", size = 445453, upload-time = "2025-11-05T18:38:46.433Z" },
+    { url = "https://files.pythonhosted.org/packages/ec/f1/0ca1f3f99ae300372635ab3fe2f7a79fa335fee3d874fa7f9e68575e0e62/brotli-1.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e", size = 1528168, upload-time = "2025-11-05T18:38:47.371Z" },
+    { url = "https://files.pythonhosted.org/packages/d6/a6/2ebfc8f766d46df8d3e65b880a2e220732395e6d7dc312c1e1244b0f074a/brotli-1.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7", size = 1627098, upload-time = "2025-11-05T18:38:48.385Z" },
+    { url = "https://files.pythonhosted.org/packages/f3/2f/0976d5b097ff8a22163b10617f76b2557f15f0f39d6a0fe1f02b1a53e92b/brotli-1.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63", size = 1419861, upload-time = "2025-11-05T18:38:49.372Z" },
+    { url = "https://files.pythonhosted.org/packages/9c/97/d76df7176a2ce7616ff94c1fb72d307c9a30d2189fe877f3dd99af00ea5a/brotli-1.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b", size = 1484594, upload-time = "2025-11-05T18:38:50.655Z" },
+    { url = "https://files.pythonhosted.org/packages/d3/93/14cf0b1216f43df5609f5b272050b0abd219e0b54ea80b47cef9867b45e7/brotli-1.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361", size = 1593455, upload-time = "2025-11-05T18:38:51.624Z" },
+    { url = "https://files.pythonhosted.org/packages/b3/73/3183c9e41ca755713bdf2cc1d0810df742c09484e2e1ddd693bee53877c1/brotli-1.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888", size = 1488164, upload-time = "2025-11-05T18:38:53.079Z" },
+    { url = "https://files.pythonhosted.org/packages/64/6a/0c78d8f3a582859236482fd9fa86a65a60328a00983006bcf6d83b7b2253/brotli-1.2.0-cp314-cp314-win32.whl", hash = "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d", size = 339280, upload-time = "2025-11-05T18:38:54.02Z" },
+    { url = "https://files.pythonhosted.org/packages/f5/10/56978295c14794b2c12007b07f3e41ba26acda9257457d7085b0bb3bb90c/brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3", size = 375639, upload-time = "2025-11-05T18:38:55.67Z" },
 ]
 
 [[package]]
@@ -204,13 +232,14 @@
 [[package]]
 name = "mint"
 version = "0.1.0"
-source = { virtual = "." }
+source = { editable = "." }
 dependencies = [
     { name = "django" },
     { name = "django-debug-toolbar" },
     { name = "environs" },
     { name = "mozilla-django-oidc" },
     { name = "requests" },
+    { name = "whitenoise", extra = ["brotli"] },
 ]
 
 [package.metadata]
@@ -219,7 +248,8 @@     { name = "django", specifier = ">=5.2.6" },
     { name = "django-debug-toolbar", specifier = ">=6.0.0" },
     { name = "environs", specifier = ">=14.3.0" },
     { name = "mozilla-django-oidc", specifier = ">=4.0.1" },
-    { name = "requests", specifier = ">=2.32.5" },
+    { name = "requests", specifier = ">=2.32.4" },
+    { name = "whitenoise", extras = ["brotli"], specifier = ">=6.9.0" },
 ]
 
 [[package]]
@@ -296,3 +326,17 @@ sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" }
 wheels = [
     { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
 ]
+
+[[package]]
+name = "whitenoise"
+version = "6.9.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/b9/cf/c15c2f21aee6b22a9f6fc9be3f7e477e2442ec22848273db7f4eb73d6162/whitenoise-6.9.0.tar.gz", hash = "sha256:8c4a7c9d384694990c26f3047e118c691557481d624f069b7f7752a2f735d609", size = 25920, upload-time = "2025-02-06T22:16:34.957Z" }
+wheels = [
+    { url = "https://files.pythonhosted.org/packages/64/b2/2ce9263149fbde9701d352bda24ea1362c154e196d2fda2201f18fc585d7/whitenoise-6.9.0-py3-none-any.whl", hash = "sha256:c8a489049b7ee9889617bb4c274a153f3d979e8f51d2efd0f5b403caf41c57df", size = 20161, upload-time = "2025-02-06T22:16:32.589Z" },
+]
+
+[package.optional-dependencies]
+brotli = [
+    { name = "brotli" },
+]