cardo-python-utils 0.5.dev47__tar.gz → 0.5.dev49__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.dev47/cardo_python_utils.egg-info → cardo_python_utils-0.5.dev49}/PKG-INFO +1 -1
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49/cardo_python_utils.egg-info}/PKG-INFO +1 -1
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/cardo_python_utils.egg-info/SOURCES.txt +1 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/pyproject.toml +1 -1
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/README.md +24 -0
- cardo_python_utils-0.5.dev49/python_utils/django/management/commands/shell.py +32 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/oidc_settings.py +7 -7
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/LICENSE +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/MANIFEST.in +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/README.rst +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/cardo_python_utils.egg-info/dependency_links.txt +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/cardo_python_utils.egg-info/requires.txt +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/cardo_python_utils.egg-info/top_level.txt +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/choices.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/data_structures.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/db.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/auth.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/templates/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/templates/user_groups_changelist.html +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/user_group.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/views.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/drf.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/ninja.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/utils.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/apps.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/auth/service.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/celery/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/celery/tenant_aware_database_scheduler.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/celery/tenant_aware_task.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/alias.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/routers.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/transaction.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/utils.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/management/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/management/commands/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/management/commands/migrateall.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/management/commands/tenant_aware_command.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/middleware/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/middleware/tenant_aware_http_middleware.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/middleware/tenant_aware_websocket_middleware.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0001_initial.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0001_initial_squashed_0005_alter_userrole_id.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0002_auto_20220120_1617.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0003_auto_20220513_1025.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0004_auto_20220817_1526.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0005_alter_userrole_id.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0006_userrole_organization_and_more.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0007_user_demo.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/0008_delete_userrole.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/migrations/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/models/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/models/user.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/models/user_group.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/redis/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/redis/key_function.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/settings.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/storage/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/storage/tenant_aware_storage.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/tenant_context.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/tests/__init__.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/tests/conftest.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django_utils.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/esma_choices.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/exceptions.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/imports.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/math.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/text.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/time.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/types_hinting.py +0 -0
- {cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/setup.cfg +0 -0
|
@@ -47,6 +47,7 @@ python_utils/django/db/utils.py
|
|
|
47
47
|
python_utils/django/management/__init__.py
|
|
48
48
|
python_utils/django/management/commands/__init__.py
|
|
49
49
|
python_utils/django/management/commands/migrateall.py
|
|
50
|
+
python_utils/django/management/commands/shell.py
|
|
50
51
|
python_utils/django/management/commands/tenant_aware_command.py
|
|
51
52
|
python_utils/django/middleware/__init__.py
|
|
52
53
|
python_utils/django/middleware/tenant_aware_http_middleware.py
|
|
@@ -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.dev49"
|
|
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"
|
|
@@ -155,6 +155,30 @@ admin.site.has_permission = has_admin_site_permission
|
|
|
155
155
|
|
|
156
156
|
If using `django-ninja`, apart from the settings configured above, auth utils are provided in the django/api/ninja.py module.
|
|
157
157
|
|
|
158
|
+
## Atomic Transactions
|
|
159
|
+
|
|
160
|
+
Django's `transaction.atomic` uses the default database. To make it tenant-aware, use `tenant_atomic`
|
|
161
|
+
|
|
162
|
+
```python3
|
|
163
|
+
from python_utils.django.db.transaction import tenant_atomic
|
|
164
|
+
|
|
165
|
+
@tenant_atomic
|
|
166
|
+
def my_function():
|
|
167
|
+
...
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Django Shell
|
|
171
|
+
|
|
172
|
+
This library overrides the shell command of Django, so that it requires the `tenant` arg.
|
|
173
|
+
This way, the shell is automatically initialized with the context set to the tenant.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
./manage.py shell --tenant=tenant1
|
|
177
|
+
|
|
178
|
+
Starting shell for tenant: -tenant=tenant
|
|
179
|
+
>>>
|
|
180
|
+
```
|
|
181
|
+
|
|
158
182
|
## Testing
|
|
159
183
|
|
|
160
184
|
In order for tests to work, create the following autouse fixtures:
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from django.core.management.commands.shell import Command as ShellCommand
|
|
2
|
+
|
|
3
|
+
from ...settings import TENANT_DATABASES
|
|
4
|
+
from ...tenant_context import TenantContext
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Command(ShellCommand):
|
|
8
|
+
help = "Runs a Python interactive interpreter for a specific tenant."
|
|
9
|
+
|
|
10
|
+
def add_arguments(self, parser):
|
|
11
|
+
super().add_arguments(parser)
|
|
12
|
+
|
|
13
|
+
parser.add_argument(
|
|
14
|
+
"--tenant",
|
|
15
|
+
action="store",
|
|
16
|
+
dest="tenant",
|
|
17
|
+
help="Specify the tenant to run the shell for.",
|
|
18
|
+
required=True,
|
|
19
|
+
type=str,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def handle(self, **options):
|
|
23
|
+
tenant = options["tenant"]
|
|
24
|
+
|
|
25
|
+
if tenant not in TENANT_DATABASES:
|
|
26
|
+
self.stdout.write(self.style.ERROR(f"Tenant '{tenant}' not found in DATABASES settings."))
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
self.stdout.write(self.style.SUCCESS(f"Starting shell for tenant: {tenant}"))
|
|
30
|
+
|
|
31
|
+
with TenantContext(tenant):
|
|
32
|
+
super().handle(**options)
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/oidc_settings.py
RENAMED
|
@@ -76,16 +76,16 @@ def get_confidential_client_service_account_token() -> str:
|
|
|
76
76
|
"""
|
|
77
77
|
Reads the Keycloak confidential client service account token for the current tenant from a file.
|
|
78
78
|
"""
|
|
79
|
-
|
|
80
|
-
token_file_path = KEYCLOAK_CONFIDENTIAL_CLIENT_SERVICE_ACCOUNT_TOKEN_FILE_PATHS.get(
|
|
79
|
+
realm = get_realm_for_tenant(TenantContext.get())
|
|
80
|
+
token_file_path = KEYCLOAK_CONFIDENTIAL_CLIENT_SERVICE_ACCOUNT_TOKEN_FILE_PATHS.get(realm)
|
|
81
81
|
if not token_file_path or not os.path.isfile(token_file_path):
|
|
82
|
-
raise FileNotFoundError(f"Keycloak service account token file for tenant {
|
|
82
|
+
raise FileNotFoundError(f"Keycloak service account token file for tenant {realm} not found: {token_file_path}")
|
|
83
83
|
|
|
84
84
|
with open(token_file_path, "r") as f:
|
|
85
85
|
token = f.read().strip()
|
|
86
86
|
|
|
87
87
|
if not token:
|
|
88
|
-
raise ValueError(f"Keycloak service account token for tenant {
|
|
88
|
+
raise ValueError(f"Keycloak service account token for tenant {realm} is empty.")
|
|
89
89
|
|
|
90
90
|
return token
|
|
91
91
|
|
|
@@ -94,10 +94,10 @@ def get_confidential_client_secret() -> str:
|
|
|
94
94
|
"""
|
|
95
95
|
Retrieves the Keycloak confidential client secret for the current tenant.
|
|
96
96
|
"""
|
|
97
|
-
|
|
98
|
-
client_secret = KEYCLOAK_CONFIDENTIAL_CLIENT_SECRETS.get(
|
|
97
|
+
realm = get_realm_for_tenant(TenantContext.get())
|
|
98
|
+
client_secret = KEYCLOAK_CONFIDENTIAL_CLIENT_SECRETS.get(realm)
|
|
99
99
|
if not client_secret:
|
|
100
|
-
raise ValueError(f"Keycloak confidential client secret for tenant {
|
|
100
|
+
raise ValueError(f"Keycloak confidential client secret for tenant {realm} not found.")
|
|
101
101
|
|
|
102
102
|
return client_secret
|
|
103
103
|
|
|
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.dev47 → cardo_python_utils-0.5.dev49}/python_utils/data_structures.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/admin/views.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/drf.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/ninja.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/api/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/auth/service.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/celery/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/alias.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/routers.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/db/transaction.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/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
|
|
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
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/models/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/models/user.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/redis/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/tenant_context.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/python_utils/django/tests/__init__.py
RENAMED
|
File without changes
|
{cardo_python_utils-0.5.dev47 → cardo_python_utils-0.5.dev49}/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
|