django-cfg 1.4.111__py3-none-any.whl → 1.4.114__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.
Potentially problematic release.
This version of django-cfg might be problematic. Click here for more details.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/dashboard/serializers/__init__.py +12 -0
- django_cfg/apps/dashboard/serializers/django_q2.py +50 -0
- django_cfg/apps/dashboard/serializers/overview.py +22 -11
- django_cfg/apps/dashboard/services/__init__.py +2 -0
- django_cfg/apps/dashboard/services/django_q2_service.py +159 -0
- django_cfg/apps/dashboard/services/system_health_service.py +85 -0
- django_cfg/apps/dashboard/urls.py +2 -0
- django_cfg/apps/dashboard/views/__init__.py +2 -0
- django_cfg/apps/dashboard/views/django_q2_views.py +79 -0
- django_cfg/apps/dashboard/views/overview_views.py +16 -2
- django_cfg/apps/tasks/migrations/0002_delete_tasklog.py +16 -0
- django_cfg/config.py +3 -4
- django_cfg/core/base/config_model.py +18 -1
- django_cfg/core/builders/apps_builder.py +4 -0
- django_cfg/core/generation/data_generators/cache.py +28 -2
- django_cfg/core/generation/integration_generators/__init__.py +4 -0
- django_cfg/core/generation/integration_generators/django_q2.py +133 -0
- django_cfg/core/generation/orchestrator.py +13 -0
- django_cfg/core/integration/display/startup.py +2 -2
- django_cfg/core/integration/url_integration.py +2 -2
- django_cfg/models/__init__.py +3 -0
- django_cfg/models/django/__init__.py +3 -0
- django_cfg/models/django/django_q2.py +491 -0
- django_cfg/modules/django_admin/utils/html_builder.py +50 -2
- django_cfg/pyproject.toml +2 -2
- django_cfg/registry/core.py +4 -0
- django_cfg/static/frontend/admin.zip +0 -0
- django_cfg/templates/admin/index.html +389 -166
- django_cfg/templatetags/django_cfg.py +8 -0
- {django_cfg-1.4.111.dist-info → django_cfg-1.4.114.dist-info}/METADATA +3 -1
- {django_cfg-1.4.111.dist-info → django_cfg-1.4.114.dist-info}/RECORD +35 -29
- {django_cfg-1.4.111.dist-info → django_cfg-1.4.114.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.111.dist-info → django_cfg-1.4.114.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.111.dist-info → django_cfg-1.4.114.dist-info}/licenses/LICENSE +0 -0
|
@@ -58,13 +58,18 @@ class CacheSettingsGenerator:
|
|
|
58
58
|
|
|
59
59
|
# Default cache - always provide one
|
|
60
60
|
if self.config.cache_default:
|
|
61
|
+
# User explicitly configured cache_default
|
|
61
62
|
caches["default"] = self.config.cache_default.to_django_config(
|
|
62
63
|
self.config.env_mode,
|
|
63
64
|
self.config.debug,
|
|
64
65
|
"default"
|
|
65
66
|
)
|
|
67
|
+
elif self.config.redis_url:
|
|
68
|
+
# Auto-create Redis cache from redis_url
|
|
69
|
+
logger.info(f"Auto-creating Redis cache from redis_url: {self.config.redis_url}")
|
|
70
|
+
caches["default"] = self._get_redis_cache_config()
|
|
66
71
|
else:
|
|
67
|
-
#
|
|
72
|
+
# Fallback to default cache backend (LocMem/FileBased depending on env)
|
|
68
73
|
caches["default"] = self._get_default_cache_config()
|
|
69
74
|
|
|
70
75
|
# Sessions cache
|
|
@@ -88,9 +93,30 @@ class CacheSettingsGenerator:
|
|
|
88
93
|
|
|
89
94
|
return settings
|
|
90
95
|
|
|
96
|
+
def _get_redis_cache_config(self) -> Dict[str, Any]:
|
|
97
|
+
"""
|
|
98
|
+
Auto-create Redis cache from config.redis_url.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Dictionary with Redis cache backend configuration
|
|
102
|
+
"""
|
|
103
|
+
from ....models.infrastructure.cache import CacheConfig
|
|
104
|
+
|
|
105
|
+
redis_cache = CacheConfig(
|
|
106
|
+
redis_url=self.config.redis_url,
|
|
107
|
+
timeout=300, # 5 minutes default
|
|
108
|
+
max_connections=50,
|
|
109
|
+
key_prefix=self.config.project_name.lower().replace(" ", "_") if self.config.project_name else "django",
|
|
110
|
+
)
|
|
111
|
+
return redis_cache.to_django_config(
|
|
112
|
+
self.config.env_mode,
|
|
113
|
+
self.config.debug,
|
|
114
|
+
"default"
|
|
115
|
+
)
|
|
116
|
+
|
|
91
117
|
def _get_default_cache_config(self) -> Dict[str, Any]:
|
|
92
118
|
"""
|
|
93
|
-
Get default cache configuration.
|
|
119
|
+
Get default cache configuration (fallback when no redis_url).
|
|
94
120
|
|
|
95
121
|
Returns:
|
|
96
122
|
Dictionary with default cache backend configuration
|
|
@@ -6,9 +6,12 @@ Contains generators for third-party integrations and frameworks:
|
|
|
6
6
|
- External services (Telegram, Unfold, Constance)
|
|
7
7
|
- API frameworks (JWT, DRF, Spectacular, OpenAPI Client)
|
|
8
8
|
- Background tasks (ReArq)
|
|
9
|
+
- Task scheduling (django-q2)
|
|
10
|
+
- Tailwind CSS configuration
|
|
9
11
|
"""
|
|
10
12
|
|
|
11
13
|
from .api import APIFrameworksGenerator
|
|
14
|
+
from .django_q2 import DjangoQ2SettingsGenerator
|
|
12
15
|
from .sessions import SessionSettingsGenerator
|
|
13
16
|
from .tasks import TasksSettingsGenerator
|
|
14
17
|
from .third_party import ThirdPartyIntegrationsGenerator
|
|
@@ -18,4 +21,5 @@ __all__ = [
|
|
|
18
21
|
"ThirdPartyIntegrationsGenerator",
|
|
19
22
|
"APIFrameworksGenerator",
|
|
20
23
|
"TasksSettingsGenerator",
|
|
24
|
+
"DjangoQ2SettingsGenerator",
|
|
21
25
|
]
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Django-Q2 settings generator for django-cfg.
|
|
3
|
+
|
|
4
|
+
Generates django-q2 settings and handles INSTALLED_APPS integration.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional
|
|
8
|
+
|
|
9
|
+
from django_cfg.modules.django_logging import logger
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from django_cfg.models.django.django_q import DjangoQ2Config
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DjangoQ2SettingsGenerator:
|
|
16
|
+
"""
|
|
17
|
+
Generates task scheduling settings for django-q2.
|
|
18
|
+
|
|
19
|
+
Automatically:
|
|
20
|
+
- Generates Q_CLUSTER configuration
|
|
21
|
+
- Adds django_q to INSTALLED_APPS if enabled
|
|
22
|
+
- Configures broker, workers, and task settings
|
|
23
|
+
- Provides schedule management via Django ORM
|
|
24
|
+
|
|
25
|
+
Django-Q2 vs django-crontab:
|
|
26
|
+
- No need to run 'crontab add' - schedules in database
|
|
27
|
+
- Built-in admin interface for monitoring
|
|
28
|
+
- Support for both cron and interval scheduling
|
|
29
|
+
- Task retries and hooks
|
|
30
|
+
- Async task support
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, config: "DjangoQ2Config", parent_config: Optional[Any] = None):
|
|
34
|
+
"""
|
|
35
|
+
Initialize with Django-Q2 configuration.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
config: DjangoQ2Config instance
|
|
39
|
+
parent_config: Optional parent DjangoConfig for accessing redis_url
|
|
40
|
+
"""
|
|
41
|
+
self.config = config
|
|
42
|
+
self.parent_config = parent_config
|
|
43
|
+
|
|
44
|
+
def generate(self) -> Dict[str, Any]:
|
|
45
|
+
"""
|
|
46
|
+
Generate Django-Q2 settings.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dictionary with Q_CLUSTER configuration
|
|
50
|
+
"""
|
|
51
|
+
if not self.config or not self.config.enabled:
|
|
52
|
+
return {}
|
|
53
|
+
|
|
54
|
+
settings = self.config.to_django_settings(parent_config=self.parent_config)
|
|
55
|
+
|
|
56
|
+
# Log configuration
|
|
57
|
+
logger.info(
|
|
58
|
+
f"✓ Configured Django-Q2 task queue "
|
|
59
|
+
f"[broker: {self.config.broker_class}, workers: {self.config.workers}]"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
enabled_schedules = self.config.get_enabled_schedules()
|
|
63
|
+
if enabled_schedules:
|
|
64
|
+
logger.info(
|
|
65
|
+
f"✓ Found {len(enabled_schedules)} scheduled task(s) "
|
|
66
|
+
f"[use admin or management commands to create schedules]"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Log individual schedules in debug mode
|
|
70
|
+
for schedule in enabled_schedules:
|
|
71
|
+
logger.debug(
|
|
72
|
+
f" - {schedule.name}: {schedule.schedule_type} → "
|
|
73
|
+
f"{schedule.command if schedule.command else schedule.func}"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
logger.info(
|
|
77
|
+
"📝 To create schedules: python manage.py qcluster "
|
|
78
|
+
"or use Django admin at /admin/django_q/schedule/"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return settings
|
|
82
|
+
|
|
83
|
+
def generate_schedule_creation_code(self) -> str:
|
|
84
|
+
"""
|
|
85
|
+
Generate Python code to create schedules programmatically.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Python code string for creating schedules
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
```python
|
|
92
|
+
code = generator.generate_schedule_creation_code()
|
|
93
|
+
# Use in management command or startup script
|
|
94
|
+
```
|
|
95
|
+
"""
|
|
96
|
+
if not self.config or not self.config.enabled:
|
|
97
|
+
return ""
|
|
98
|
+
|
|
99
|
+
enabled_schedules = self.config.get_enabled_schedules()
|
|
100
|
+
if not enabled_schedules:
|
|
101
|
+
return ""
|
|
102
|
+
|
|
103
|
+
lines = [
|
|
104
|
+
"# Auto-generated Django-Q2 schedule creation",
|
|
105
|
+
"from django_q.models import Schedule",
|
|
106
|
+
"",
|
|
107
|
+
"# Create or update schedules",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
for schedule in enabled_schedules:
|
|
111
|
+
schedule_dict = schedule.to_django_q_format()
|
|
112
|
+
|
|
113
|
+
lines.append("")
|
|
114
|
+
lines.append(f"# {schedule.name}")
|
|
115
|
+
lines.append("Schedule.objects.update_or_create(")
|
|
116
|
+
lines.append(f" name='{schedule.name}',")
|
|
117
|
+
lines.append(" defaults={")
|
|
118
|
+
|
|
119
|
+
for key, value in schedule_dict.items():
|
|
120
|
+
if key == "name":
|
|
121
|
+
continue
|
|
122
|
+
if isinstance(value, str):
|
|
123
|
+
lines.append(f" '{key}': '{value}',")
|
|
124
|
+
else:
|
|
125
|
+
lines.append(f" '{key}': {value},")
|
|
126
|
+
|
|
127
|
+
lines.append(" }")
|
|
128
|
+
lines.append(")")
|
|
129
|
+
|
|
130
|
+
return "\n".join(lines)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
__all__ = ["DjangoQ2SettingsGenerator"]
|
|
@@ -78,6 +78,7 @@ class SettingsOrchestrator:
|
|
|
78
78
|
settings.update(self._generate_third_party_settings())
|
|
79
79
|
settings.update(self._generate_api_settings())
|
|
80
80
|
settings.update(self._generate_tasks_settings())
|
|
81
|
+
settings.update(self._generate_django_q2_settings())
|
|
81
82
|
settings.update(self._generate_tailwind_settings())
|
|
82
83
|
|
|
83
84
|
# Apply additional settings (user overrides)
|
|
@@ -223,6 +224,18 @@ class SettingsOrchestrator:
|
|
|
223
224
|
except Exception as e:
|
|
224
225
|
raise ConfigurationError(f"Failed to generate tasks settings: {e}") from e
|
|
225
226
|
|
|
227
|
+
def _generate_django_q2_settings(self) -> Dict[str, Any]:
|
|
228
|
+
"""Generate Django-Q2 task scheduling settings."""
|
|
229
|
+
if not hasattr(self.config, "django_q2") or not self.config.django_q2:
|
|
230
|
+
return {}
|
|
231
|
+
|
|
232
|
+
try:
|
|
233
|
+
from .integration_generators.django_q2 import DjangoQ2SettingsGenerator
|
|
234
|
+
generator = DjangoQ2SettingsGenerator(self.config.django_q2, parent_config=self.config)
|
|
235
|
+
return generator.generate()
|
|
236
|
+
except Exception as e:
|
|
237
|
+
raise ConfigurationError(f"Failed to generate Django-Q2 settings: {e}") from e
|
|
238
|
+
|
|
226
239
|
def _generate_tailwind_settings(self) -> Dict[str, Any]:
|
|
227
240
|
"""Generate Tailwind CSS settings."""
|
|
228
241
|
try:
|
|
@@ -116,7 +116,7 @@ class StartupDisplayManager(BaseDisplayManager):
|
|
|
116
116
|
|
|
117
117
|
# Get library info
|
|
118
118
|
from django_cfg.config import (
|
|
119
|
-
|
|
119
|
+
LIB_SITE_URL,
|
|
120
120
|
LIB_GITHUB_URL,
|
|
121
121
|
LIB_SITE_URL,
|
|
122
122
|
LIB_SUPPORT_URL,
|
|
@@ -138,7 +138,7 @@ class StartupDisplayManager(BaseDisplayManager):
|
|
|
138
138
|
info_table.add_row("🔍 Env Source", env_source)
|
|
139
139
|
|
|
140
140
|
info_table.add_row("🌐 Site", LIB_SITE_URL)
|
|
141
|
-
info_table.add_row("📚 Docs",
|
|
141
|
+
info_table.add_row("📚 Docs", LIB_SITE_URL)
|
|
142
142
|
info_table.add_row("🐙 GitHub", LIB_GITHUB_URL)
|
|
143
143
|
info_table.add_row("🆘 Support", LIB_SUPPORT_URL)
|
|
144
144
|
|
|
@@ -176,7 +176,7 @@ def get_django_cfg_urls_info() -> dict:
|
|
|
176
176
|
Dictionary with complete URL integration info
|
|
177
177
|
"""
|
|
178
178
|
from django_cfg.config import (
|
|
179
|
-
|
|
179
|
+
LIB_SITE_URL,
|
|
180
180
|
LIB_GITHUB_URL,
|
|
181
181
|
LIB_HEALTH_URL,
|
|
182
182
|
LIB_NAME,
|
|
@@ -205,7 +205,7 @@ def get_django_cfg_urls_info() -> dict:
|
|
|
205
205
|
"prefix": "cfg/",
|
|
206
206
|
"description": LIB_NAME,
|
|
207
207
|
"site_url": LIB_SITE_URL,
|
|
208
|
-
"docs_url":
|
|
208
|
+
"docs_url": LIB_SITE_URL,
|
|
209
209
|
"github_url": LIB_GITHUB_URL,
|
|
210
210
|
"support_url": LIB_SUPPORT_URL,
|
|
211
211
|
"health_url": LIB_HEALTH_URL,
|
django_cfg/models/__init__.py
CHANGED
|
@@ -35,6 +35,7 @@ from .base.module import BaseCfgAutoModule
|
|
|
35
35
|
from .django.axes import AxesConfig
|
|
36
36
|
from .django.constance import ConstanceConfig, ConstanceField
|
|
37
37
|
from .django.crypto_fields import CryptoFieldsConfig
|
|
38
|
+
from .django.django_q2 import DjangoQ2Config, DjangoQ2ScheduleConfig
|
|
38
39
|
from .django.environment import EnvironmentConfig
|
|
39
40
|
from .django.openapi import OpenAPIClientConfig
|
|
40
41
|
from .infrastructure.cache import CacheConfig
|
|
@@ -79,6 +80,8 @@ __all__ = [
|
|
|
79
80
|
"EnvironmentConfig",
|
|
80
81
|
"ConstanceConfig",
|
|
81
82
|
"ConstanceField",
|
|
83
|
+
"DjangoQ2Config",
|
|
84
|
+
"DjangoQ2ScheduleConfig",
|
|
82
85
|
"OpenAPIClientConfig",
|
|
83
86
|
"UnfoldConfig",
|
|
84
87
|
"AxesConfig",
|
|
@@ -6,6 +6,7 @@ Django integrations and extensions.
|
|
|
6
6
|
|
|
7
7
|
from .axes import AxesConfig
|
|
8
8
|
from .constance import ConstanceConfig, ConstanceField
|
|
9
|
+
from .django_q2 import DjangoQ2Config, DjangoQ2ScheduleConfig
|
|
9
10
|
from .environment import EnvironmentConfig
|
|
10
11
|
from .openapi import OpenAPIClientConfig
|
|
11
12
|
|
|
@@ -13,6 +14,8 @@ __all__ = [
|
|
|
13
14
|
"EnvironmentConfig",
|
|
14
15
|
"ConstanceConfig",
|
|
15
16
|
"ConstanceField",
|
|
17
|
+
"DjangoQ2Config",
|
|
18
|
+
"DjangoQ2ScheduleConfig",
|
|
16
19
|
"OpenAPIClientConfig",
|
|
17
20
|
"AxesConfig",
|
|
18
21
|
]
|