django-cfg 1.4.107__py3-none-any.whl → 1.4.108__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 (130) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/views/profile.py +19 -9
  3. django_cfg/apps/centrifugo/views/admin_api.py +4 -7
  4. django_cfg/apps/centrifugo/views/monitoring.py +3 -6
  5. django_cfg/apps/centrifugo/views/testing_api.py +3 -6
  6. django_cfg/apps/dashboard/services/system_health_service.py +16 -11
  7. django_cfg/apps/dashboard/views/activity_views.py +3 -5
  8. django_cfg/apps/dashboard/views/apizones_views.py +4 -5
  9. django_cfg/apps/dashboard/views/charts_views.py +4 -5
  10. django_cfg/apps/dashboard/views/overview_views.py +4 -5
  11. django_cfg/apps/dashboard/views/statistics_views.py +4 -5
  12. django_cfg/apps/dashboard/views/system_views.py +4 -5
  13. django_cfg/apps/knowbase/__init__.py +2 -2
  14. django_cfg/apps/knowbase/apps.py +2 -8
  15. django_cfg/apps/knowbase/views/base.py +9 -4
  16. django_cfg/apps/support/views/api.py +16 -7
  17. django_cfg/apps/tasks/__init__.py +61 -2
  18. django_cfg/apps/tasks/admin/__init__.py +3 -10
  19. django_cfg/apps/tasks/admin/config.py +98 -0
  20. django_cfg/apps/tasks/admin/task_log.py +265 -0
  21. django_cfg/apps/tasks/apps.py +7 -9
  22. django_cfg/apps/tasks/filters/__init__.py +10 -0
  23. django_cfg/apps/tasks/filters/task_log.py +121 -0
  24. django_cfg/apps/tasks/migrations/0001_initial.py +196 -0
  25. django_cfg/apps/tasks/models/__init__.py +4 -0
  26. django_cfg/apps/tasks/models/task_log.py +246 -0
  27. django_cfg/apps/tasks/serializers/__init__.py +28 -0
  28. django_cfg/apps/tasks/serializers/task_log.py +249 -0
  29. django_cfg/apps/tasks/services/__init__.py +10 -0
  30. django_cfg/apps/tasks/services/client/__init__.py +7 -0
  31. django_cfg/apps/tasks/services/client/client.py +234 -0
  32. django_cfg/apps/tasks/services/config_helper.py +63 -0
  33. django_cfg/apps/tasks/services/sync.py +204 -0
  34. django_cfg/apps/tasks/urls.py +7 -13
  35. django_cfg/apps/tasks/views/__init__.py +4 -10
  36. django_cfg/apps/tasks/views/task_log.py +41 -0
  37. django_cfg/apps/tasks/views/task_log_base.py +41 -0
  38. django_cfg/apps/tasks/views/task_log_overview.py +100 -0
  39. django_cfg/apps/tasks/views/task_log_related.py +41 -0
  40. django_cfg/apps/tasks/views/task_log_stats.py +91 -0
  41. django_cfg/apps/tasks/views/task_log_timeline.py +81 -0
  42. django_cfg/apps/urls.py +0 -1
  43. django_cfg/cli/commands/info.py +1 -1
  44. django_cfg/cli/utils.py +1 -1
  45. django_cfg/core/base/config_model.py +1 -1
  46. django_cfg/core/builders/apps_builder.py +1 -1
  47. django_cfg/core/generation/integration_generators/__init__.py +1 -1
  48. django_cfg/core/generation/integration_generators/tasks.py +14 -18
  49. django_cfg/core/generation/security_generators/crypto_fields.py +2 -1
  50. django_cfg/core/integration/display/startup.py +1 -1
  51. django_cfg/mixins/__init__.py +12 -0
  52. django_cfg/mixins/admin_api.py +37 -0
  53. django_cfg/mixins/client_api.py +39 -0
  54. django_cfg/models/django/constance.py +2 -8
  55. django_cfg/models/django/crypto_fields.py +13 -48
  56. django_cfg/models/tasks/__init__.py +8 -10
  57. django_cfg/models/tasks/backends.py +76 -207
  58. django_cfg/models/tasks/config.py +20 -127
  59. django_cfg/models/tasks/utils.py +17 -29
  60. django_cfg/modules/django_client/management/commands/generate_client.py +13 -1
  61. django_cfg/modules/django_unfold/navigation.py +121 -22
  62. django_cfg/pyproject.toml +2 -2
  63. django_cfg/registry/core.py +1 -1
  64. django_cfg/static/frontend/admin.zip +0 -0
  65. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/METADATA +3 -3
  66. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/RECORD +70 -107
  67. django_cfg/apps/tasks/admin/actions.py +0 -29
  68. django_cfg/apps/tasks/admin/tasks_admin.py +0 -154
  69. django_cfg/apps/tasks/api/serializers.py +0 -82
  70. django_cfg/apps/tasks/api/views.py +0 -571
  71. django_cfg/apps/tasks/serializers.py +0 -82
  72. django_cfg/apps/tasks/static/tasks/css/dashboard-alpine.css +0 -299
  73. django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -120
  74. django_cfg/apps/tasks/static/tasks/js/alpine/README.md +0 -47
  75. django_cfg/apps/tasks/static/tasks/js/alpine/actions/index.js +0 -8
  76. django_cfg/apps/tasks/static/tasks/js/alpine/actions/management.js +0 -123
  77. django_cfg/apps/tasks/static/tasks/js/alpine/actions/pagination.js +0 -21
  78. django_cfg/apps/tasks/static/tasks/js/alpine/actions/tasks.js +0 -101
  79. django_cfg/apps/tasks/static/tasks/js/alpine/actions/workers.js +0 -59
  80. django_cfg/apps/tasks/static/tasks/js/alpine/computed.js +0 -35
  81. django_cfg/apps/tasks/static/tasks/js/alpine/index.js +0 -148
  82. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/index.js +0 -36
  83. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/overview.js +0 -37
  84. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/queues.js +0 -27
  85. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/tasks.js +0 -32
  86. django_cfg/apps/tasks/static/tasks/js/alpine/loaders/workers.js +0 -21
  87. django_cfg/apps/tasks/static/tasks/js/alpine/state.js +0 -36
  88. django_cfg/apps/tasks/static/tasks/js/alpine/utils/formatters.js +0 -42
  89. django_cfg/apps/tasks/static/tasks/js/alpine/utils/helpers.js +0 -68
  90. django_cfg/apps/tasks/static/tasks/js/dashboard-alpine.js +0 -725
  91. django_cfg/apps/tasks/tasks/__init__.py +0 -10
  92. django_cfg/apps/tasks/tasks/demo_tasks.py +0 -127
  93. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -71
  94. django_cfg/apps/tasks/templates/tasks/components/overview_content.html +0 -94
  95. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +0 -44
  96. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -45
  97. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -151
  98. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +0 -61
  99. django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +0 -269
  100. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +0 -60
  101. django_cfg/apps/tasks/templates/tasks/layout/base.html +0 -20
  102. django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +0 -168
  103. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +0 -77
  104. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +0 -40
  105. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +0 -40
  106. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +0 -86
  107. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +0 -90
  108. django_cfg/apps/tasks/urls_admin.py +0 -15
  109. django_cfg/apps/tasks/utils/__init__.py +0 -1
  110. django_cfg/apps/tasks/utils/simulator.py +0 -353
  111. django_cfg/apps/tasks/views/api.py +0 -571
  112. django_cfg/apps/tasks/views/dashboard.py +0 -89
  113. django_cfg/management/commands/rundramatiq.py +0 -24
  114. django_cfg/management/commands/rundramatiq_simulator.py +0 -22
  115. django_cfg/management/commands/task_clear.py +0 -25
  116. django_cfg/management/commands/task_status.py +0 -24
  117. django_cfg/modules/django_tasks/__init__.py +0 -29
  118. django_cfg/modules/django_tasks/dramatiq_setup.py +0 -20
  119. django_cfg/modules/django_tasks/factory.py +0 -127
  120. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  121. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +0 -253
  122. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +0 -436
  123. django_cfg/modules/django_tasks/management/commands/task_clear.py +0 -226
  124. django_cfg/modules/django_tasks/management/commands/task_status.py +0 -257
  125. django_cfg/modules/django_tasks/service.py +0 -281
  126. django_cfg/modules/django_tasks/settings.py +0 -107
  127. /django_cfg/{modules/django_tasks/management → apps/tasks/migrations}/__init__.py +0 -0
  128. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/WHEEL +0 -0
  129. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/entry_points.txt +0 -0
  130. {django_cfg-1.4.107.dist-info → django_cfg-1.4.108.dist-info}/licenses/LICENSE +0 -0
@@ -1,29 +0,0 @@
1
- """
2
- Task admin actions.
3
- """
4
-
5
- from django.contrib import messages
6
-
7
-
8
- def retry_failed_tasks(modeladmin, request, queryset):
9
- """Retry selected failed tasks."""
10
- failed_tasks = queryset.filter(status='failed')
11
- count = failed_tasks.count()
12
-
13
- if count > 0:
14
- # Here you would implement the retry logic
15
- messages.success(request, f"Queued {count} tasks for retry.")
16
- else:
17
- messages.warning(request, "No failed tasks selected.")
18
-
19
-
20
- def cancel_pending_tasks(modeladmin, request, queryset):
21
- """Cancel selected pending tasks."""
22
- pending_tasks = queryset.filter(status='pending')
23
- count = pending_tasks.count()
24
-
25
- if count > 0:
26
- pending_tasks.update(status='cancelled')
27
- messages.success(request, f"Cancelled {count} pending tasks.")
28
- else:
29
- messages.warning(request, "No pending tasks selected.")
@@ -1,154 +0,0 @@
1
- """
2
- Tasks Admin v2.0 - NEW Declarative Pydantic Approach
3
-
4
- Enhanced Dramatiq task management with Material Icons and auto-generated displays.
5
- """
6
-
7
- import logging
8
- from django.contrib import admin, messages
9
- from django.contrib.admin.views.main import ChangeList
10
- from django.db.models import Count
11
-
12
- from django_cfg.modules.django_admin import (
13
- ActionConfig,
14
- AdminConfig,
15
- BadgeField,
16
- DateTimeField,
17
- FieldsetConfig,
18
- Icons,
19
- )
20
- from django_cfg.modules.django_admin.base import PydanticAdmin
21
- from django_cfg.modules.django_tasks import DjangoTasks
22
- from .actions import retry_failed_tasks, cancel_pending_tasks
23
-
24
- try:
25
- from django_dramatiq.admin import TaskAdmin as BaseDramatiqTaskAdmin
26
- from django_dramatiq.models import Task
27
- DRAMATIQ_AVAILABLE = True
28
- except ImportError:
29
- Task = None
30
- BaseDramatiqTaskAdmin = None
31
- DRAMATIQ_AVAILABLE = False
32
-
33
- if DRAMATIQ_AVAILABLE:
34
-
35
- class TaskQueueChangeList(ChangeList):
36
- """Custom changelist for task queue management."""
37
- def __init__(self, *args, **kwargs):
38
- super().__init__(*args, **kwargs)
39
- self.tasks_service = DjangoTasks()
40
-
41
- task_config = AdminConfig(
42
- model=Task,
43
- list_display=["id", "actor_name", "status", "queue_name", "created_at"],
44
- display_fields=[
45
- BadgeField(name="id", title="Task ID", variant="info", icon=Icons.TAG),
46
- BadgeField(name="actor_name", title="Actor", variant="secondary", icon=Icons.FUNCTIONS, empty_value="Unknown"),
47
- BadgeField(name="status", title="Status", label_map={
48
- "pending": "warning", "running": "info", "done": "success",
49
- "failed": "danger", "cancelled": "secondary"
50
- }),
51
- BadgeField(name="queue_name", title="Queue", variant="info", icon=Icons.QUEUE, empty_value="default"),
52
- DateTimeField(name="created_at", title="Created", ordering="created_at"),
53
- ],
54
- search_fields=["actor_name", "queue_name", "message_id"],
55
- list_filter=["status", "queue_name", "actor_name", "created_at", "updated_at"],
56
- readonly_fields=["id", "actor_name", "queue_name", "args_preview", "kwargs_preview",
57
- "result_preview", "created_at", "duration_display", "retries_display", "error_message_display"],
58
- fieldsets=[
59
- FieldsetConfig(title="Task Information", fields=["status", "actor_name", "queue_name"]),
60
- FieldsetConfig(title="Execution Details", fields=["args_preview", "kwargs_preview", "result_preview", "error_message_display"]),
61
- FieldsetConfig(title="Timing", fields=["created_at", "duration_display"]),
62
- FieldsetConfig(title="Retry Information", fields=["retries_display"]),
63
- ],
64
- actions=[
65
- ActionConfig(name="retry_failed_tasks", description="Retry failed tasks",
66
- variant="warning", handler=retry_failed_tasks),
67
- ActionConfig(name="cancel_pending_tasks", description="Cancel pending tasks",
68
- variant="danger", handler=cancel_pending_tasks),
69
- ],
70
- ordering=["-created_at"],
71
- )
72
-
73
- try:
74
- admin.site.unregister(Task)
75
- except admin.sites.NotRegistered:
76
- pass
77
-
78
- @admin.register(Task)
79
- class TaskAdmin(PydanticAdmin):
80
- """Enhanced admin for Dramatiq Task model."""
81
- config = task_config
82
-
83
- def has_add_permission(self, request):
84
- return False
85
-
86
- def has_delete_permission(self, request, obj=None):
87
- return False
88
-
89
- def get_changelist(self, request, **kwargs):
90
- return TaskQueueChangeList
91
-
92
- # Custom readonly methods (for detail view)
93
- def args_preview(self, obj):
94
- if hasattr(obj, 'args') and obj.args:
95
- args_text = str(obj.args)
96
- return args_text[:100] + "..." if len(args_text) > 100 else args_text
97
- return "No arguments"
98
- args_preview.short_description = "Arguments"
99
-
100
- def kwargs_preview(self, obj):
101
- if hasattr(obj, 'kwargs') and obj.kwargs:
102
- kwargs_text = str(obj.kwargs)
103
- return kwargs_text[:100] + "..." if len(kwargs_text) > 100 else kwargs_text
104
- return "No kwargs"
105
- kwargs_preview.short_description = "Keyword Arguments"
106
-
107
- def result_preview(self, obj):
108
- if hasattr(obj, 'result') and obj.result:
109
- result_text = str(obj.result)
110
- return result_text[:100] + "..." if len(result_text) > 100 else result_text
111
- return "No result"
112
- result_preview.short_description = "Result"
113
-
114
- def duration_display(self, obj):
115
- if obj.started_at and obj.finished_at:
116
- duration = obj.finished_at - obj.started_at
117
- return f"{duration.total_seconds():.2f}s"
118
- return "N/A"
119
- duration_display.short_description = "Duration"
120
-
121
- def retries_display(self, obj):
122
- return str(getattr(obj, 'retries', 0))
123
- retries_display.short_description = "Retries"
124
-
125
- def error_message_display(self, obj):
126
- if hasattr(obj, 'error') and obj.error:
127
- error_text = str(obj.error)
128
- return error_text[:100] + "..." if len(error_text) > 100 else error_text
129
- return "No error"
130
- error_message_display.short_description = "Error"
131
-
132
- def changelist_view(self, request, extra_context=None):
133
- extra_context = extra_context or {}
134
- try:
135
- total_tasks = self.get_queryset(request).count()
136
- status_stats = self.get_queryset(request).values('status').annotate(count=Count('id')).order_by('status')
137
- actor_stats = self.get_queryset(request).values('actor_name').annotate(count=Count('id')).order_by('-count')[:10]
138
- queue_stats = self.get_queryset(request).values('queue_name').annotate(count=Count('id')).order_by('-count')
139
- extra_context.update({
140
- 'task_statistics': {
141
- 'total_tasks': total_tasks,
142
- 'status_distribution': list(status_stats),
143
- 'top_actors': list(actor_stats),
144
- 'queue_distribution': list(queue_stats),
145
- }
146
- })
147
- except Exception as e:
148
- extra_context['task_error'] = str(e)
149
- return super().changelist_view(request, extra_context)
150
-
151
- else:
152
- class TaskAdmin:
153
- """Placeholder when django-dramatiq is not available."""
154
- pass
@@ -1,82 +0,0 @@
1
- """
2
- Serializers for Django CFG Tasks app.
3
-
4
- Provides DRF serializers for task management API endpoints.
5
- """
6
-
7
-
8
- from rest_framework import serializers
9
-
10
-
11
- class QueueStatusSerializer(serializers.Serializer):
12
- """Serializer for queue status data."""
13
-
14
- queues = serializers.DictField(
15
- child=serializers.DictField(
16
- child=serializers.IntegerField()
17
- ),
18
- help_text="Queue information with pending/failed counts"
19
- )
20
- workers = serializers.IntegerField(help_text="Number of active workers")
21
- redis_connected = serializers.BooleanField(help_text="Redis connection status")
22
- timestamp = serializers.CharField(help_text="Current timestamp")
23
- error = serializers.CharField(required=False, help_text="Error message if any")
24
-
25
-
26
- class TaskStatisticsSerializer(serializers.Serializer):
27
- """Serializer for task statistics data."""
28
-
29
- statistics = serializers.DictField(
30
- child=serializers.IntegerField(),
31
- help_text="Task count statistics"
32
- )
33
- recent_tasks = serializers.ListField(
34
- child=serializers.DictField(),
35
- help_text="List of recent tasks"
36
- )
37
- timestamp = serializers.CharField(help_text="Current timestamp")
38
- error = serializers.CharField(required=False, help_text="Error message if any")
39
-
40
-
41
- class WorkerActionSerializer(serializers.Serializer):
42
- """Serializer for worker management actions."""
43
-
44
- action = serializers.ChoiceField(
45
- choices=['start', 'stop', 'restart'],
46
- help_text="Action to perform on workers"
47
- )
48
- processes = serializers.IntegerField(
49
- default=1,
50
- min_value=1,
51
- max_value=10,
52
- help_text="Number of worker processes"
53
- )
54
- threads = serializers.IntegerField(
55
- default=2,
56
- min_value=1,
57
- max_value=20,
58
- help_text="Number of threads per process"
59
- )
60
-
61
-
62
- class QueueActionSerializer(serializers.Serializer):
63
- """Serializer for queue management actions."""
64
-
65
- action = serializers.ChoiceField(
66
- choices=['clear', 'clear_all', 'purge', 'purge_failed', 'flush'],
67
- help_text="Action to perform on queues"
68
- )
69
- queue_names = serializers.ListField(
70
- child=serializers.CharField(),
71
- required=False,
72
- help_text="Specific queues to target (empty = all queues)"
73
- )
74
-
75
-
76
- class APIResponseSerializer(serializers.Serializer):
77
- """Standard API response serializer."""
78
-
79
- success = serializers.BooleanField(help_text="Operation success status")
80
- message = serializers.CharField(required=False, help_text="Success message")
81
- error = serializers.CharField(required=False, help_text="Error message")
82
- data = serializers.DictField(required=False, help_text="Response data")