django-cfg 1.4.113__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.

Files changed (32) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/dashboard/serializers/__init__.py +10 -8
  3. django_cfg/apps/dashboard/serializers/django_q2.py +50 -0
  4. django_cfg/apps/dashboard/services/__init__.py +2 -2
  5. django_cfg/apps/dashboard/services/django_q2_service.py +159 -0
  6. django_cfg/apps/dashboard/services/system_health_service.py +39 -26
  7. django_cfg/apps/dashboard/urls.py +2 -2
  8. django_cfg/apps/dashboard/views/__init__.py +2 -2
  9. django_cfg/apps/dashboard/views/django_q2_views.py +79 -0
  10. django_cfg/apps/tasks/migrations/0002_delete_tasklog.py +16 -0
  11. django_cfg/core/base/config_model.py +15 -5
  12. django_cfg/core/builders/apps_builder.py +3 -3
  13. django_cfg/core/generation/data_generators/cache.py +28 -2
  14. django_cfg/core/generation/integration_generators/__init__.py +4 -3
  15. django_cfg/core/generation/integration_generators/django_q2.py +133 -0
  16. django_cfg/core/generation/orchestrator.py +7 -7
  17. django_cfg/models/__init__.py +3 -3
  18. django_cfg/models/django/__init__.py +3 -3
  19. django_cfg/models/django/django_q2.py +491 -0
  20. django_cfg/pyproject.toml +2 -2
  21. django_cfg/registry/core.py +3 -3
  22. django_cfg/static/frontend/admin.zip +0 -0
  23. {django_cfg-1.4.113.dist-info → django_cfg-1.4.114.dist-info}/METADATA +3 -2
  24. {django_cfg-1.4.113.dist-info → django_cfg-1.4.114.dist-info}/RECORD +27 -26
  25. django_cfg/apps/dashboard/serializers/crontab.py +0 -84
  26. django_cfg/apps/dashboard/services/crontab_service.py +0 -210
  27. django_cfg/apps/dashboard/views/crontab_views.py +0 -72
  28. django_cfg/core/generation/integration_generators/crontab.py +0 -64
  29. django_cfg/models/django/crontab.py +0 -303
  30. {django_cfg-1.4.113.dist-info → django_cfg-1.4.114.dist-info}/WHEEL +0 -0
  31. {django_cfg-1.4.113.dist-info → django_cfg-1.4.114.dist-info}/entry_points.txt +0 -0
  32. {django_cfg-1.4.113.dist-info → django_cfg-1.4.114.dist-info}/licenses/LICENSE +0 -0
@@ -1,303 +0,0 @@
1
- """
2
- Crontab Configuration for django-cfg.
3
-
4
- Type-safe configuration for django-crontab with automatic
5
- Django settings generation and support for management commands.
6
-
7
- Features:
8
- - Type-safe crontab job definitions
9
- - Django management command support
10
- - Schedule validation
11
- - Timezone support
12
- - Lock file prevention of concurrent runs
13
- - Command prefix configuration
14
- """
15
-
16
- from typing import Any, Dict, List, Literal, Optional, Union
17
-
18
- from pydantic import BaseModel, ConfigDict, Field, field_validator
19
-
20
-
21
- class CrontabJobConfig(BaseModel):
22
- """
23
- Configuration for a single crontab job.
24
-
25
- Supports both management commands and Python callables.
26
- """
27
-
28
- model_config = ConfigDict(
29
- validate_assignment=True,
30
- extra="forbid",
31
- )
32
-
33
- # Job identification
34
- name: str = Field(
35
- ...,
36
- description="Human-readable job name (for identification and logging)",
37
- min_length=1,
38
- max_length=100,
39
- )
40
-
41
- # Schedule definition (crontab format)
42
- minute: str = Field(
43
- default="*",
44
- description="Crontab minute (0-59, *, */N, or comma-separated)",
45
- )
46
-
47
- hour: str = Field(
48
- default="*",
49
- description="Crontab hour (0-23, *, */N, or comma-separated)",
50
- )
51
-
52
- day_of_week: str = Field(
53
- default="*",
54
- description="Crontab day of week (0-6, *, */N, or comma-separated)",
55
- )
56
-
57
- day_of_month: str = Field(
58
- default="*",
59
- description="Crontab day of month (1-31, *, */N, or comma-separated)",
60
- )
61
-
62
- month_of_year: str = Field(
63
- default="*",
64
- description="Crontab month (1-12, *, */N, or comma-separated)",
65
- )
66
-
67
- # Job execution configuration
68
- job_type: Literal["command", "callable"] = Field(
69
- default="command",
70
- description="Job type: 'command' for Django management commands, 'callable' for Python functions",
71
- )
72
-
73
- # For management commands
74
- command: Optional[str] = Field(
75
- default=None,
76
- description="Django management command name (e.g., 'sync_account_balances')",
77
- )
78
-
79
- command_args: List[str] = Field(
80
- default_factory=list,
81
- description="Command positional arguments",
82
- )
83
-
84
- command_kwargs: Dict[str, Any] = Field(
85
- default_factory=dict,
86
- description="Command keyword arguments (e.g., {'verbosity': 0})",
87
- )
88
-
89
- # For Python callables
90
- callable_path: Optional[str] = Field(
91
- default=None,
92
- description="Full Python path to callable (e.g., 'myapp.tasks.my_task')",
93
- pattern=r"^[\w.]+$",
94
- )
95
-
96
- callable_args: List[Any] = Field(
97
- default_factory=list,
98
- description="Callable positional arguments",
99
- )
100
-
101
- callable_kwargs: Dict[str, Any] = Field(
102
- default_factory=dict,
103
- description="Callable keyword arguments",
104
- )
105
-
106
- # Job options
107
- enabled: bool = Field(
108
- default=True,
109
- description="Whether job is enabled",
110
- )
111
-
112
- comment: Optional[str] = Field(
113
- default=None,
114
- description="Optional comment describing the job",
115
- max_length=200,
116
- )
117
-
118
- @field_validator("minute", "hour", "day_of_week", "day_of_month", "month_of_year")
119
- @classmethod
120
- def validate_crontab_field(cls, v: str) -> str:
121
- """Validate crontab field format."""
122
- if v == "*":
123
- return v
124
-
125
- # Allow */N (e.g., */15)
126
- if v.startswith("*/"):
127
- try:
128
- int(v[2:])
129
- return v
130
- except ValueError:
131
- raise ValueError(f"Invalid step value in crontab field: {v}")
132
-
133
- # Allow ranges (e.g., 1-5)
134
- if "-" in v:
135
- parts = v.split("-")
136
- if len(parts) != 2:
137
- raise ValueError(f"Invalid range format in crontab field: {v}")
138
- try:
139
- int(parts[0])
140
- int(parts[1])
141
- return v
142
- except ValueError:
143
- raise ValueError(f"Invalid range values in crontab field: {v}")
144
-
145
- # Allow comma-separated (e.g., 1,3,5)
146
- if "," in v:
147
- parts = v.split(",")
148
- try:
149
- for part in parts:
150
- int(part)
151
- return v
152
- except ValueError:
153
- raise ValueError(f"Invalid comma-separated values in crontab field: {v}")
154
-
155
- # Allow single number
156
- try:
157
- int(v)
158
- return v
159
- except ValueError:
160
- raise ValueError(f"Invalid crontab field format: {v}")
161
-
162
- def model_post_init(self, __context: Any) -> None:
163
- """Validate job configuration after initialization."""
164
- # Ensure either command or callable_path is set
165
- if self.job_type == "command" and not self.command:
166
- raise ValueError("'command' must be set when job_type is 'command'")
167
-
168
- if self.job_type == "callable" and not self.callable_path:
169
- raise ValueError("'callable_path' must be set when job_type is 'callable'")
170
-
171
- @property
172
- def schedule(self) -> str:
173
- """Get crontab schedule string."""
174
- return f"{self.minute} {self.hour} {self.day_of_month} {self.month_of_year} {self.day_of_week}"
175
-
176
- def to_django_crontab_format(self) -> tuple:
177
- """
178
- Convert to django-crontab format.
179
-
180
- Returns:
181
- Tuple for CRONJOBS list entry
182
- """
183
- if self.job_type == "command":
184
- # Format: (schedule, 'django.core.management.call_command', [command, *args], kwargs)
185
- return (
186
- self.schedule,
187
- 'django.core.management.call_command',
188
- [self.command] + self.command_args,
189
- self.command_kwargs,
190
- )
191
- else:
192
- # Format: (schedule, callable_path, args, kwargs)
193
- return (
194
- self.schedule,
195
- self.callable_path,
196
- self.callable_args,
197
- self.callable_kwargs,
198
- )
199
-
200
-
201
- class CrontabConfig(BaseModel):
202
- """
203
- Complete Crontab configuration container.
204
-
205
- Integrates with django-crontab for scheduled task execution.
206
- Automatically adds django_crontab to INSTALLED_APPS when enabled.
207
- """
208
-
209
- model_config = ConfigDict(
210
- validate_assignment=True,
211
- extra="forbid",
212
- )
213
-
214
- enabled: bool = Field(
215
- default=True,
216
- description="Enable crontab scheduling (auto-adds django_crontab to INSTALLED_APPS)",
217
- )
218
-
219
- jobs: List[CrontabJobConfig] = Field(
220
- default_factory=list,
221
- description="List of scheduled jobs",
222
- )
223
-
224
- # Django-crontab specific options
225
- command_prefix: Optional[str] = Field(
226
- default=None,
227
- description="Command prefix for all cron jobs (e.g., 'DJANGO_SETTINGS_MODULE=api.settings')",
228
- )
229
-
230
- command_suffix: Optional[str] = Field(
231
- default=None,
232
- description="Command suffix for all cron jobs",
233
- )
234
-
235
- lock_jobs: bool = Field(
236
- default=True,
237
- description="Use lock files to prevent concurrent job execution",
238
- )
239
-
240
- comment: str = Field(
241
- default="django-crontab jobs",
242
- description="Comment added to crontab file",
243
- max_length=100,
244
- )
245
-
246
- def get_enabled_jobs(self) -> List[CrontabJobConfig]:
247
- """Get list of enabled jobs."""
248
- return [job for job in self.jobs if job.enabled]
249
-
250
- def to_django_settings(self) -> Dict[str, Any]:
251
- """
252
- Convert to Django settings dictionary.
253
-
254
- Generates CRONJOBS and related settings for django-crontab.
255
- """
256
- if not self.enabled:
257
- return {}
258
-
259
- settings = {}
260
-
261
- # Build CRONJOBS list
262
- enabled_jobs = self.get_enabled_jobs()
263
- if enabled_jobs:
264
- settings["CRONJOBS"] = [
265
- job.to_django_crontab_format()
266
- for job in enabled_jobs
267
- ]
268
-
269
- # Add command prefix if configured
270
- if self.command_prefix:
271
- settings["CRONTAB_COMMAND_PREFIX"] = self.command_prefix
272
-
273
- # Add command suffix if configured
274
- if self.command_suffix:
275
- settings["CRONTAB_COMMAND_SUFFIX"] = self.command_suffix
276
-
277
- # Add lock jobs setting
278
- settings["CRONTAB_LOCK_JOBS"] = self.lock_jobs
279
-
280
- # Add comment
281
- settings["CRONTAB_COMMENT"] = self.comment
282
-
283
- return settings
284
-
285
- def get_job_by_name(self, name: str) -> Optional[CrontabJobConfig]:
286
- """Get job by name."""
287
- for job in self.jobs:
288
- if job.name == name:
289
- return job
290
- return None
291
-
292
- def get_jobs_by_command(self, command: str) -> List[CrontabJobConfig]:
293
- """Get all jobs for a specific command."""
294
- return [
295
- job for job in self.jobs
296
- if job.job_type == "command" and job.command == command
297
- ]
298
-
299
-
300
- __all__ = [
301
- "CrontabJobConfig",
302
- "CrontabConfig",
303
- ]