cardo-python-utils 0.5.dev33__tar.gz → 0.5.dev35__tar.gz
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.
- {cardo_python_utils-0.5.dev33/cardo_python_utils.egg-info → cardo_python_utils-0.5.dev35}/PKG-INFO +1 -1
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35/cardo_python_utils.egg-info}/PKG-INFO +1 -1
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/pyproject.toml +1 -1
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/README.md +21 -1
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/auth.py +12 -17
- cardo_python_utils-0.5.dev35/python_utils/django/admin/views.py +24 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/oidc_settings.py +37 -6
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/settings.py +1 -1
- cardo_python_utils-0.5.dev33/python_utils/django/admin/views.py +0 -63
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/LICENSE +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/MANIFEST.in +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/README.rst +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/cardo_python_utils.egg-info/SOURCES.txt +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/cardo_python_utils.egg-info/dependency_links.txt +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/cardo_python_utils.egg-info/requires.txt +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/cardo_python_utils.egg-info/top_level.txt +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/choices.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/data_structures.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/db.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/templates/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/templates/user_groups_changelist.html +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/user_group.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/drf.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/ninja.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/utils.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/apps.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/auth/service.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/celery/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/celery/tenant_aware_task.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/routers.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/transaction.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/utils.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/management/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/management/commands/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/management/commands/migrateall.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/management/commands/tenant_aware_command.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/middleware/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/middleware/tenant_aware_http_middleware.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/models/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/models/user_group.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/redis/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/redis/key_function.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/storage/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/storage/tenant_aware_storage.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tenant_context.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tests/__init__.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tests/conftest.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django_utils.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/esma_choices.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/exceptions.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/imports.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/math.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/text.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/time.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/types_hinting.py +0 -0
- {cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/setup.cfg +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cardo-python-utils"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.dev35"
|
|
8
8
|
description = "Python library enhanced with a wide range of functions for different scenarios."
|
|
9
9
|
readme = "README.rst"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -111,15 +111,35 @@ KEYCLOAK_USER_GROUP_MODEL = "myapp.UserGroup"
|
|
|
111
111
|
KEYCLOAK_CONFIDENTIAL_CLIENT_ID = os.getenv("KEYCLOAK_CONFIDENTIAL_CLIENT_ID", f"{JWT_AUDIENCE}_confidential")
|
|
112
112
|
|
|
113
113
|
OIDC_RP_CLIENT_ID = KEYCLOAK_CONFIDENTIAL_CLIENT_ID
|
|
114
|
-
OIDC_RP_CLIENT_SECRET = None
|
|
115
114
|
OIDC_RP_SIGN_ALGO = "RS256"
|
|
116
115
|
OIDC_CREATE_USER = True
|
|
116
|
+
OIDC_AUTHENTICATE_CLASS = "python_utils.django.admin.views.TenantAwareOIDCAuthenticationRequestView"
|
|
117
117
|
|
|
118
118
|
LOGIN_REDIRECT_URL = "/admin"
|
|
119
119
|
SESSION_COOKIE_AGE = 60 * 30 # 30 minutes
|
|
120
120
|
SESSION_SAVE_EVERY_REQUEST = True # Extend session on each request
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
## urls.py file
|
|
124
|
+
|
|
125
|
+
The views of the `mozilla-django-oidc` package need to be exposed as well, for the OIDC auth:
|
|
126
|
+
|
|
127
|
+
```python3
|
|
128
|
+
urlpatterns.append(path("oidc/", include("mozilla_django_oidc.urls")))
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## admin.py file
|
|
132
|
+
|
|
133
|
+
The Django Admin Panel needs to be configured to automatically redirect to the OIDC login page:
|
|
134
|
+
|
|
135
|
+
```python3
|
|
136
|
+
from python_utils.django.admin.auth import has_admin_site_permission
|
|
137
|
+
from python_utils.django.admin.views import TenantAwareOIDCAuthenticationRequestView
|
|
138
|
+
|
|
139
|
+
admin.site.login = TenantAwareOIDCAuthenticationRequestView.as_view()
|
|
140
|
+
admin.site.has_permission = has_admin_site_permission
|
|
141
|
+
```
|
|
142
|
+
|
|
123
143
|
## With django-ninja
|
|
124
144
|
|
|
125
145
|
If using `django-ninja`, apart from the settings configured above, auth utils are provided in the django/api/ninja.py module.
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/auth.py
RENAMED
|
@@ -18,23 +18,18 @@ class AdminAuthenticationBackend(OIDCAuthenticationBackend):
|
|
|
18
18
|
own Keycloak realm.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@property
|
|
34
|
-
def OIDC_OP_JWKS_ENDPOINT(self):
|
|
35
|
-
"""Dynamically get the JWKS endpoint for the current tenant."""
|
|
36
|
-
|
|
37
|
-
return get_oidc_op_jwks_endpoint()
|
|
21
|
+
def get_settings(self, attr, *args):
|
|
22
|
+
if attr == "OIDC_OP_TOKEN_ENDPOINT":
|
|
23
|
+
return get_oidc_op_token_endpoint()
|
|
24
|
+
if attr == "OIDC_OP_USER_ENDPOINT":
|
|
25
|
+
return get_oidc_op_user_endpoint()
|
|
26
|
+
if attr == "OIDC_OP_JWKS_ENDPOINT":
|
|
27
|
+
return get_oidc_op_jwks_endpoint()
|
|
28
|
+
if attr == "OIDC_RP_CLIENT_SECRET":
|
|
29
|
+
# The explicit return of None is needed to prevent the parent class from raising an error
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
return super().get_settings(attr, *args)
|
|
38
33
|
|
|
39
34
|
def get_token(self, payload):
|
|
40
35
|
# Instead of passing client_id and client_secret,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tenant-aware OIDC views for mozilla-django-oidc.
|
|
3
|
+
|
|
4
|
+
These views override the default mozilla-django-oidc views to dynamically
|
|
5
|
+
resolve OIDC endpoints based on the current tenant context.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from mozilla_django_oidc.views import OIDCAuthenticationRequestView
|
|
9
|
+
|
|
10
|
+
from ..oidc_settings import get_oidc_op_authorization_endpoint
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TenantAwareOIDCAuthenticationRequestView(OIDCAuthenticationRequestView):
|
|
14
|
+
"""
|
|
15
|
+
Tenant-aware OIDC authentication request view.
|
|
16
|
+
|
|
17
|
+
Dynamically resolves the authorization endpoint based on the current tenant.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def get_settings(self, attr, *args):
|
|
21
|
+
if attr == "OIDC_OP_AUTHORIZATION_ENDPOINT":
|
|
22
|
+
return get_oidc_op_authorization_endpoint()
|
|
23
|
+
|
|
24
|
+
return super().get_settings(attr, *args)
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/oidc_settings.py
RENAMED
|
@@ -8,17 +8,30 @@ import json
|
|
|
8
8
|
import os
|
|
9
9
|
import requests
|
|
10
10
|
|
|
11
|
+
from django.conf import settings
|
|
11
12
|
from .tenant_context import TenantContext
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
KEYCLOAK_SERVER_URL = os.getenv("KEYCLOAK_SERVER_URL", None)
|
|
15
16
|
KEYCLOAK_CONFIDENTIAL_CLIENT_ID = os.getenv("KEYCLOAK_CONFIDENTIAL_CLIENT_ID", None)
|
|
17
|
+
|
|
18
|
+
OIDC_CLIENT_AUTH_METHOD = getattr(settings, "OIDC_CLIENT_AUTH_METHOD", "client_assertion")
|
|
19
|
+
if OIDC_CLIENT_AUTH_METHOD not in ("client_assertion", "client_secret"):
|
|
20
|
+
raise ValueError(
|
|
21
|
+
f"Invalid OIDC_CLIENT_AUTH_METHOD: {OIDC_CLIENT_AUTH_METHOD}. "
|
|
22
|
+
f"Supported methods are 'client_assertion' and 'client_secret'."
|
|
23
|
+
)
|
|
24
|
+
|
|
16
25
|
KEYCLOAK_CONFIDENTIAL_CLIENT_SERVICE_ACCOUNT_TOKEN_FILE_PATHS: dict[str, str] = json.loads(
|
|
17
26
|
os.getenv("KEYCLOAK_CONFIDENTIAL_CLIENT_SERVICE_ACCOUNT_TOKEN_FILE_PATHS", "{}")
|
|
18
27
|
)
|
|
19
28
|
KEYCLOAK_CLIENT_CREDENTIALS_GRANT_TYPE = "client_credentials"
|
|
20
29
|
KEYCLOAK_CLIENT_ASSERTION_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
|
|
21
30
|
|
|
31
|
+
KEYCLOAK_CONFIDENTIAL_CLIENT_SECRETS: dict[str, str] = json.loads(
|
|
32
|
+
os.getenv("KEYCLOAK_CONFIDENTIAL_CLIENT_SECRETS", "{}")
|
|
33
|
+
)
|
|
34
|
+
|
|
22
35
|
|
|
23
36
|
def get_oidc_op_base_url() -> str:
|
|
24
37
|
"""Get the base URL for the OIDC provider (Keycloak realm URL)."""
|
|
@@ -65,20 +78,38 @@ def get_confidential_client_service_account_token() -> str:
|
|
|
65
78
|
return token
|
|
66
79
|
|
|
67
80
|
|
|
81
|
+
def get_confidential_client_secret() -> str:
|
|
82
|
+
"""
|
|
83
|
+
Retrieves the Keycloak confidential client secret for the current tenant.
|
|
84
|
+
"""
|
|
85
|
+
tenant = TenantContext.get()
|
|
86
|
+
client_secret = KEYCLOAK_CONFIDENTIAL_CLIENT_SECRETS.get(tenant)
|
|
87
|
+
if not client_secret:
|
|
88
|
+
raise ValueError(f"Keycloak confidential client secret for tenant {tenant} not found.")
|
|
89
|
+
|
|
90
|
+
return client_secret
|
|
91
|
+
|
|
92
|
+
|
|
68
93
|
def get_oidc_confidential_client_token(**kwargs) -> dict:
|
|
69
94
|
"""
|
|
70
95
|
Obtains token for an OIDC confidential client with the client credentials grant,
|
|
71
96
|
using a service account token for authentication.
|
|
72
97
|
"""
|
|
73
98
|
|
|
99
|
+
data = {
|
|
100
|
+
"grant_type": KEYCLOAK_CLIENT_CREDENTIALS_GRANT_TYPE,
|
|
101
|
+
**kwargs,
|
|
102
|
+
}
|
|
103
|
+
if OIDC_CLIENT_AUTH_METHOD == "client_secret":
|
|
104
|
+
data["client_id"] = KEYCLOAK_CONFIDENTIAL_CLIENT_ID
|
|
105
|
+
data["client_secret"] = get_confidential_client_secret()
|
|
106
|
+
else:
|
|
107
|
+
data["client_assertion_type"] = KEYCLOAK_CLIENT_ASSERTION_TYPE
|
|
108
|
+
data["client_assertion"] = get_confidential_client_service_account_token()
|
|
109
|
+
|
|
74
110
|
response = requests.post(
|
|
75
111
|
get_oidc_op_token_endpoint(),
|
|
76
|
-
data=
|
|
77
|
-
"grant_type": KEYCLOAK_CLIENT_CREDENTIALS_GRANT_TYPE,
|
|
78
|
-
"client_assertion_type": KEYCLOAK_CLIENT_ASSERTION_TYPE,
|
|
79
|
-
"client_assertion": get_confidential_client_service_account_token(),
|
|
80
|
-
**kwargs,
|
|
81
|
-
},
|
|
112
|
+
data=data,
|
|
82
113
|
)
|
|
83
114
|
response.raise_for_status()
|
|
84
115
|
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/settings.py
RENAMED
|
@@ -15,7 +15,7 @@ TENANT_AWARE_EXCLUDED_PATHS = (
|
|
|
15
15
|
"/mediafiles",
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
DEVELOPMENT_TENANT = getattr(settings, "DEVELOPMENT_TENANT")
|
|
18
|
+
DEVELOPMENT_TENANT = getattr(settings, "DEVELOPMENT_TENANT", None)
|
|
19
19
|
if DEVELOPMENT_TENANT is None:
|
|
20
20
|
if TENANT_DATABASES:
|
|
21
21
|
DEVELOPMENT_TENANT = list(TENANT_DATABASES)[0]
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Tenant-aware OIDC views for mozilla-django-oidc.
|
|
3
|
-
|
|
4
|
-
These views override the default mozilla-django-oidc views to dynamically
|
|
5
|
-
resolve OIDC endpoints based on the current tenant context.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from mozilla_django_oidc.views import (
|
|
9
|
-
OIDCAuthenticationCallbackView,
|
|
10
|
-
OIDCAuthenticationRequestView,
|
|
11
|
-
OIDCLogoutView,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
from ..oidc_settings import (
|
|
15
|
-
get_oidc_op_authorization_endpoint,
|
|
16
|
-
get_oidc_op_logout_endpoint,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class TenantAwareOIDCAuthenticationRequestView(OIDCAuthenticationRequestView):
|
|
21
|
-
"""
|
|
22
|
-
Tenant-aware OIDC authentication request view.
|
|
23
|
-
|
|
24
|
-
Dynamically resolves the authorization endpoint based on the current tenant.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
@property
|
|
28
|
-
def OIDC_OP_AUTH_ENDPOINT(self):
|
|
29
|
-
"""Dynamically get the authorization endpoint for the current tenant."""
|
|
30
|
-
return get_oidc_op_authorization_endpoint()
|
|
31
|
-
|
|
32
|
-
def get_settings(self, attr, *args):
|
|
33
|
-
if attr == "OIDC_OP_AUTHORIZATION_ENDPOINT":
|
|
34
|
-
return self.OIDC_OP_AUTH_ENDPOINT
|
|
35
|
-
return super().get_settings(attr, *args)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class TenantAwareOIDCAuthenticationCallbackView(OIDCAuthenticationCallbackView):
|
|
39
|
-
"""
|
|
40
|
-
Tenant-aware OIDC authentication callback view.
|
|
41
|
-
|
|
42
|
-
Uses the tenant-aware authentication backend.
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
pass
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
class TenantAwareOIDCLogoutView(OIDCLogoutView):
|
|
49
|
-
"""
|
|
50
|
-
Tenant-aware OIDC logout view.
|
|
51
|
-
|
|
52
|
-
Dynamically resolves the logout endpoint based on the current tenant.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
@property
|
|
56
|
-
def OIDC_OP_LOGOUT_ENDPOINT(self):
|
|
57
|
-
"""Dynamically get the logout endpoint for the current tenant."""
|
|
58
|
-
return get_oidc_op_logout_endpoint()
|
|
59
|
-
|
|
60
|
-
def get_settings(self, attr, *args):
|
|
61
|
-
if attr == "OIDC_OP_LOGOUT_ENDPOINT":
|
|
62
|
-
return self.OIDC_OP_LOGOUT_ENDPOINT
|
|
63
|
-
return super().get_settings(attr, *args)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/data_structures.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/admin/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/drf.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/ninja.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/api/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/auth/service.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/celery/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/routers.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/transaction.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/db/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/redis/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tenant_context.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tests/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev33 → cardo_python_utils-0.5.dev35}/python_utils/django/tests/conftest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|