django-cfg 1.4.120__py3-none-any.whl → 1.5.2__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 +8 -4
- django_cfg/apps/centrifugo/admin/centrifugo_log.py +33 -71
- django_cfg/apps/dashboard/TRANSACTION_FIX.md +73 -0
- django_cfg/apps/dashboard/serializers/__init__.py +0 -12
- django_cfg/apps/dashboard/serializers/activity.py +1 -1
- django_cfg/apps/dashboard/services/__init__.py +0 -2
- django_cfg/apps/dashboard/services/charts_service.py +4 -3
- django_cfg/apps/dashboard/services/statistics_service.py +11 -2
- django_cfg/apps/dashboard/services/system_health_service.py +64 -106
- django_cfg/apps/dashboard/urls.py +0 -2
- django_cfg/apps/dashboard/views/__init__.py +0 -2
- django_cfg/apps/dashboard/views/commands_views.py +3 -6
- django_cfg/apps/dashboard/views/overview_views.py +14 -13
- django_cfg/apps/grpc/__init__.py +9 -0
- django_cfg/apps/grpc/admin/__init__.py +11 -0
- django_cfg/apps/{tasks → grpc}/admin/config.py +32 -41
- django_cfg/apps/grpc/admin/grpc_request_log.py +252 -0
- django_cfg/apps/grpc/apps.py +28 -0
- django_cfg/apps/grpc/auth/__init__.py +9 -0
- django_cfg/apps/grpc/auth/jwt_auth.py +295 -0
- django_cfg/apps/grpc/interceptors/__init__.py +19 -0
- django_cfg/apps/grpc/interceptors/errors.py +241 -0
- django_cfg/apps/grpc/interceptors/logging.py +270 -0
- django_cfg/apps/grpc/interceptors/metrics.py +306 -0
- django_cfg/apps/grpc/interceptors/request_logger.py +515 -0
- django_cfg/apps/grpc/management/__init__.py +1 -0
- django_cfg/apps/grpc/management/commands/rungrpc.py +302 -0
- django_cfg/apps/grpc/managers/__init__.py +10 -0
- django_cfg/apps/grpc/managers/grpc_request_log.py +310 -0
- django_cfg/apps/grpc/migrations/0001_initial.py +69 -0
- django_cfg/apps/grpc/migrations/0002_rename_django_cfg__service_4c4a8e_idx_django_cfg__service_584308_idx_and_more.py +38 -0
- django_cfg/apps/grpc/models/__init__.py +9 -0
- django_cfg/apps/grpc/models/grpc_request_log.py +219 -0
- django_cfg/apps/grpc/serializers/__init__.py +23 -0
- django_cfg/apps/grpc/serializers/health.py +18 -0
- django_cfg/apps/grpc/serializers/requests.py +18 -0
- django_cfg/apps/grpc/serializers/services.py +50 -0
- django_cfg/apps/grpc/serializers/stats.py +22 -0
- django_cfg/apps/grpc/services/__init__.py +16 -0
- django_cfg/apps/grpc/services/base.py +375 -0
- django_cfg/apps/grpc/services/discovery.py +415 -0
- django_cfg/apps/grpc/urls.py +23 -0
- django_cfg/apps/grpc/utils/__init__.py +13 -0
- django_cfg/apps/grpc/utils/proto_gen.py +423 -0
- django_cfg/apps/grpc/views/__init__.py +9 -0
- django_cfg/apps/grpc/views/monitoring.py +497 -0
- django_cfg/apps/knowbase/apps.py +2 -2
- django_cfg/apps/maintenance/admin/api_key_admin.py +7 -9
- django_cfg/apps/maintenance/admin/site_admin.py +5 -4
- django_cfg/apps/newsletter/admin/newsletter_admin.py +12 -11
- django_cfg/apps/payments/admin/balance_admin.py +26 -36
- django_cfg/apps/payments/admin/payment_admin.py +65 -85
- django_cfg/apps/payments/admin/withdrawal_admin.py +65 -100
- django_cfg/apps/rq/__init__.py +9 -0
- django_cfg/apps/rq/apps.py +80 -0
- django_cfg/apps/rq/management/__init__.py +1 -0
- django_cfg/apps/rq/management/commands/__init__.py +1 -0
- django_cfg/apps/rq/management/commands/rqscheduler.py +31 -0
- django_cfg/apps/rq/management/commands/rqstats.py +33 -0
- django_cfg/apps/rq/management/commands/rqworker.py +31 -0
- django_cfg/apps/rq/management/commands/rqworker_pool.py +27 -0
- django_cfg/apps/rq/serializers/__init__.py +40 -0
- django_cfg/apps/rq/serializers/health.py +60 -0
- django_cfg/apps/rq/serializers/job.py +100 -0
- django_cfg/apps/rq/serializers/queue.py +80 -0
- django_cfg/apps/rq/serializers/schedule.py +178 -0
- django_cfg/apps/rq/serializers/testing.py +139 -0
- django_cfg/apps/rq/serializers/worker.py +58 -0
- django_cfg/apps/rq/services/__init__.py +25 -0
- django_cfg/apps/rq/services/config_helper.py +233 -0
- django_cfg/apps/rq/services/models/README.md +417 -0
- django_cfg/apps/rq/services/models/__init__.py +30 -0
- django_cfg/apps/rq/services/models/event.py +123 -0
- django_cfg/apps/rq/services/models/job.py +99 -0
- django_cfg/apps/rq/services/models/queue.py +92 -0
- django_cfg/apps/rq/services/models/worker.py +104 -0
- django_cfg/apps/rq/services/rq_converters.py +183 -0
- django_cfg/apps/rq/tasks/__init__.py +23 -0
- django_cfg/apps/rq/tasks/demo_tasks.py +284 -0
- django_cfg/apps/rq/urls.py +54 -0
- django_cfg/apps/rq/views/__init__.py +19 -0
- django_cfg/apps/rq/views/jobs.py +882 -0
- django_cfg/apps/rq/views/monitoring.py +248 -0
- django_cfg/apps/rq/views/queues.py +261 -0
- django_cfg/apps/rq/views/schedule.py +400 -0
- django_cfg/apps/rq/views/testing.py +761 -0
- django_cfg/apps/rq/views/workers.py +195 -0
- django_cfg/apps/urls.py +13 -8
- django_cfg/config.py +106 -0
- django_cfg/core/base/config_model.py +16 -26
- django_cfg/core/builders/apps_builder.py +7 -11
- django_cfg/core/generation/integration_generators/__init__.py +3 -6
- django_cfg/core/generation/integration_generators/django_rq.py +80 -0
- django_cfg/core/generation/integration_generators/grpc_generator.py +318 -0
- django_cfg/core/generation/orchestrator.py +15 -15
- django_cfg/core/integration/display/startup.py +6 -20
- django_cfg/mixins/__init__.py +2 -0
- django_cfg/mixins/superadmin_api.py +59 -0
- django_cfg/models/__init__.py +3 -3
- django_cfg/models/api/grpc/__init__.py +59 -0
- django_cfg/models/api/grpc/config.py +364 -0
- django_cfg/models/django/__init__.py +3 -3
- django_cfg/models/django/django_rq.py +621 -0
- django_cfg/models/django/revolution_legacy.py +1 -1
- django_cfg/modules/base.py +19 -6
- django_cfg/modules/django_admin/base/pydantic_admin.py +2 -2
- django_cfg/modules/django_admin/config/background_task_config.py +4 -4
- django_cfg/modules/django_admin/utils/__init__.py +41 -3
- django_cfg/modules/django_admin/utils/badges/__init__.py +13 -0
- django_cfg/modules/django_admin/utils/{badges.py → badges/status_badges.py} +3 -3
- django_cfg/modules/django_admin/utils/displays/__init__.py +13 -0
- django_cfg/modules/django_admin/utils/{displays.py → displays/data_displays.py} +2 -2
- django_cfg/modules/django_admin/utils/html/__init__.py +26 -0
- django_cfg/modules/django_admin/utils/html/badges.py +47 -0
- django_cfg/modules/django_admin/utils/html/base.py +167 -0
- django_cfg/modules/django_admin/utils/html/code.py +87 -0
- django_cfg/modules/django_admin/utils/html/composition.py +205 -0
- django_cfg/modules/django_admin/utils/html/formatting.py +231 -0
- django_cfg/modules/django_admin/utils/html/keyvalue.py +219 -0
- django_cfg/modules/django_admin/utils/html/markdown_integration.py +108 -0
- django_cfg/modules/django_admin/utils/html/progress.py +127 -0
- django_cfg/modules/django_admin/utils/html_builder.py +55 -408
- django_cfg/modules/django_admin/utils/markdown/__init__.py +21 -0
- django_cfg/modules/django_unfold/navigation.py +21 -18
- django_cfg/pyproject.toml +4 -6
- django_cfg/registry/core.py +4 -7
- django_cfg/registry/modules.py +6 -0
- django_cfg/static/frontend/admin.zip +0 -0
- django_cfg/templates/admin/constance/includes/results_list.html +73 -0
- django_cfg/templates/admin/index.html +187 -62
- django_cfg/templatetags/django_cfg.py +61 -1
- {django_cfg-1.4.120.dist-info → django_cfg-1.5.2.dist-info}/METADATA +12 -4
- {django_cfg-1.4.120.dist-info → django_cfg-1.5.2.dist-info}/RECORD +140 -96
- django_cfg/apps/dashboard/permissions.py +0 -48
- django_cfg/apps/dashboard/serializers/django_q2.py +0 -50
- django_cfg/apps/dashboard/services/django_q2_service.py +0 -159
- django_cfg/apps/dashboard/views/django_q2_views.py +0 -79
- django_cfg/apps/tasks/__init__.py +0 -64
- django_cfg/apps/tasks/admin/__init__.py +0 -4
- django_cfg/apps/tasks/admin/task_log.py +0 -265
- django_cfg/apps/tasks/apps.py +0 -15
- django_cfg/apps/tasks/filters/__init__.py +0 -10
- django_cfg/apps/tasks/filters/task_log.py +0 -121
- django_cfg/apps/tasks/migrations/0001_initial.py +0 -196
- django_cfg/apps/tasks/migrations/0002_delete_tasklog.py +0 -16
- django_cfg/apps/tasks/models/__init__.py +0 -4
- django_cfg/apps/tasks/models/task_log.py +0 -246
- django_cfg/apps/tasks/serializers/__init__.py +0 -28
- django_cfg/apps/tasks/serializers/task_log.py +0 -249
- django_cfg/apps/tasks/services/__init__.py +0 -10
- django_cfg/apps/tasks/services/client/__init__.py +0 -7
- django_cfg/apps/tasks/services/client/client.py +0 -234
- django_cfg/apps/tasks/services/config_helper.py +0 -63
- django_cfg/apps/tasks/services/sync.py +0 -204
- django_cfg/apps/tasks/urls.py +0 -16
- django_cfg/apps/tasks/views/__init__.py +0 -10
- django_cfg/apps/tasks/views/task_log.py +0 -41
- django_cfg/apps/tasks/views/task_log_base.py +0 -41
- django_cfg/apps/tasks/views/task_log_overview.py +0 -100
- django_cfg/apps/tasks/views/task_log_related.py +0 -41
- django_cfg/apps/tasks/views/task_log_stats.py +0 -91
- django_cfg/apps/tasks/views/task_log_timeline.py +0 -81
- django_cfg/core/generation/integration_generators/django_q2.py +0 -133
- django_cfg/core/generation/integration_generators/tasks.py +0 -88
- django_cfg/models/django/django_q2.py +0 -514
- django_cfg/models/tasks/__init__.py +0 -49
- django_cfg/models/tasks/backends.py +0 -122
- django_cfg/models/tasks/config.py +0 -209
- django_cfg/models/tasks/utils.py +0 -162
- django_cfg/modules/django_admin/utils/CODE_BLOCK_DOCS.md +0 -396
- django_cfg/modules/django_q2/README.md +0 -140
- django_cfg/modules/django_q2/__init__.py +0 -8
- django_cfg/modules/django_q2/apps.py +0 -107
- django_cfg/modules/django_q2/management/commands/__init__.py +0 -0
- django_cfg/modules/django_q2/management/commands/sync_django_q_schedules.py +0 -74
- /django_cfg/apps/{tasks/migrations → grpc/management/commands}/__init__.py +0 -0
- /django_cfg/{modules/django_q2/management → apps/grpc/migrations}/__init__.py +0 -0
- /django_cfg/modules/django_admin/utils/{mermaid_plugin.py → markdown/mermaid_plugin.py} +0 -0
- /django_cfg/modules/django_admin/utils/{markdown_renderer.py → markdown/renderer.py} +0 -0
- {django_cfg-1.4.120.dist-info → django_cfg-1.5.2.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.120.dist-info → django_cfg-1.5.2.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.120.dist-info → django_cfg-1.5.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Health check and configuration serializers for Django-RQ.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HealthCheckSerializer(serializers.Serializer):
|
|
9
|
+
"""
|
|
10
|
+
Health check response serializer.
|
|
11
|
+
|
|
12
|
+
Provides overall RQ cluster health status.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
status = serializers.CharField(help_text="Health status (healthy/degraded/unhealthy)")
|
|
16
|
+
worker_count = serializers.IntegerField(help_text="Total number of active workers")
|
|
17
|
+
queue_count = serializers.IntegerField(help_text="Number of configured queues")
|
|
18
|
+
total_jobs = serializers.IntegerField(help_text="Total jobs across all queues")
|
|
19
|
+
timestamp = serializers.DateTimeField(help_text="Health check timestamp")
|
|
20
|
+
enabled = serializers.BooleanField(help_text="RQ enabled status")
|
|
21
|
+
redis_connected = serializers.BooleanField(help_text="Redis connection status")
|
|
22
|
+
wrapper_url = serializers.CharField(
|
|
23
|
+
required=False,
|
|
24
|
+
allow_blank=True,
|
|
25
|
+
default="",
|
|
26
|
+
help_text="Wrapper URL (optional)"
|
|
27
|
+
)
|
|
28
|
+
has_api_key = serializers.BooleanField(
|
|
29
|
+
required=False,
|
|
30
|
+
default=False,
|
|
31
|
+
help_text="API key configured status"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RQConfigSerializer(serializers.Serializer):
|
|
36
|
+
"""
|
|
37
|
+
RQ configuration serializer.
|
|
38
|
+
|
|
39
|
+
Returns current RQ configuration from django-cfg.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
enabled = serializers.BooleanField(help_text="RQ enabled status")
|
|
43
|
+
queues = serializers.DictField(help_text="Configured queues")
|
|
44
|
+
async_mode = serializers.BooleanField(
|
|
45
|
+
default=True, help_text="Async mode enabled"
|
|
46
|
+
)
|
|
47
|
+
show_admin_link = serializers.BooleanField(
|
|
48
|
+
default=True, help_text="Show admin link"
|
|
49
|
+
)
|
|
50
|
+
prometheus_enabled = serializers.BooleanField(
|
|
51
|
+
default=True, help_text="Prometheus metrics enabled"
|
|
52
|
+
)
|
|
53
|
+
api_token_configured = serializers.BooleanField(
|
|
54
|
+
default=False, help_text="API token is configured"
|
|
55
|
+
)
|
|
56
|
+
schedules = serializers.ListField(
|
|
57
|
+
required=False,
|
|
58
|
+
default=list,
|
|
59
|
+
help_text="Scheduled tasks from django-cfg config"
|
|
60
|
+
)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Job information serializers for Django-RQ.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class JobListSerializer(serializers.Serializer):
|
|
9
|
+
"""
|
|
10
|
+
Job list item serializer.
|
|
11
|
+
|
|
12
|
+
Provides basic job information for list views.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
id = serializers.CharField(help_text="Job ID")
|
|
16
|
+
func_name = serializers.CharField(help_text="Function name")
|
|
17
|
+
created_at = serializers.DateTimeField(help_text="Job creation time")
|
|
18
|
+
status = serializers.CharField(
|
|
19
|
+
help_text="Job status (queued/started/finished/failed)"
|
|
20
|
+
)
|
|
21
|
+
queue = serializers.CharField(help_text="Queue name")
|
|
22
|
+
timeout = serializers.IntegerField(
|
|
23
|
+
allow_null=True, required=False, help_text="Job timeout in seconds"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class JobDetailSerializer(serializers.Serializer):
|
|
28
|
+
"""
|
|
29
|
+
Detailed job information serializer.
|
|
30
|
+
|
|
31
|
+
Provides comprehensive job details including result and metadata.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
id = serializers.CharField(help_text="Job ID")
|
|
35
|
+
func_name = serializers.CharField(help_text="Function name")
|
|
36
|
+
args = serializers.ListField(default=list, help_text="Function arguments")
|
|
37
|
+
kwargs = serializers.DictField(default=dict, help_text="Function keyword arguments")
|
|
38
|
+
|
|
39
|
+
# Status and timing
|
|
40
|
+
created_at = serializers.DateTimeField(help_text="Job creation time")
|
|
41
|
+
enqueued_at = serializers.DateTimeField(
|
|
42
|
+
allow_null=True, required=False, help_text="Job enqueue time"
|
|
43
|
+
)
|
|
44
|
+
started_at = serializers.DateTimeField(
|
|
45
|
+
allow_null=True, required=False, help_text="Job start time"
|
|
46
|
+
)
|
|
47
|
+
ended_at = serializers.DateTimeField(
|
|
48
|
+
allow_null=True, required=False, help_text="Job end time"
|
|
49
|
+
)
|
|
50
|
+
status = serializers.CharField(
|
|
51
|
+
help_text="Job status (queued/started/finished/failed)"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Queue and worker
|
|
55
|
+
queue = serializers.CharField(help_text="Queue name")
|
|
56
|
+
worker_name = serializers.CharField(
|
|
57
|
+
allow_null=True, required=False, help_text="Worker name if started"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Configuration
|
|
61
|
+
timeout = serializers.IntegerField(
|
|
62
|
+
allow_null=True, required=False, help_text="Job timeout in seconds"
|
|
63
|
+
)
|
|
64
|
+
result_ttl = serializers.IntegerField(
|
|
65
|
+
allow_null=True, required=False, help_text="Result TTL in seconds"
|
|
66
|
+
)
|
|
67
|
+
failure_ttl = serializers.IntegerField(
|
|
68
|
+
allow_null=True, required=False, help_text="Failure TTL in seconds"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Result and error
|
|
72
|
+
result = serializers.JSONField(
|
|
73
|
+
allow_null=True, required=False, help_text="Job result if finished"
|
|
74
|
+
)
|
|
75
|
+
exc_info = serializers.CharField(
|
|
76
|
+
allow_null=True, required=False, help_text="Exception info if failed"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Metadata
|
|
80
|
+
meta = serializers.DictField(default=dict, help_text="Job metadata")
|
|
81
|
+
dependency_ids = serializers.ListField(
|
|
82
|
+
child=serializers.CharField(),
|
|
83
|
+
default=list,
|
|
84
|
+
help_text="List of dependency job IDs",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class JobActionResponseSerializer(serializers.Serializer):
|
|
89
|
+
"""
|
|
90
|
+
Job action response serializer.
|
|
91
|
+
|
|
92
|
+
Used for job management actions (requeue, delete, etc.).
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
success = serializers.BooleanField(help_text="Action success status")
|
|
96
|
+
message = serializers.CharField(help_text="Action result message")
|
|
97
|
+
job_id = serializers.CharField(help_text="Job ID")
|
|
98
|
+
action = serializers.CharField(
|
|
99
|
+
help_text="Action performed (requeue/delete/cancel)"
|
|
100
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Queue statistics serializers for Django-RQ.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class QueueStatsSerializer(serializers.Serializer):
|
|
9
|
+
"""
|
|
10
|
+
Queue statistics serializer.
|
|
11
|
+
|
|
12
|
+
Provides basic queue statistics.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
name = serializers.CharField(help_text="Queue name")
|
|
16
|
+
count = serializers.IntegerField(help_text="Total jobs in queue")
|
|
17
|
+
queued_jobs = serializers.IntegerField(
|
|
18
|
+
default=0, help_text="Jobs waiting to be processed"
|
|
19
|
+
)
|
|
20
|
+
started_jobs = serializers.IntegerField(
|
|
21
|
+
default=0, help_text="Jobs currently being processed"
|
|
22
|
+
)
|
|
23
|
+
finished_jobs = serializers.IntegerField(default=0, help_text="Completed jobs")
|
|
24
|
+
failed_jobs = serializers.IntegerField(default=0, help_text="Failed jobs")
|
|
25
|
+
deferred_jobs = serializers.IntegerField(default=0, help_text="Deferred jobs")
|
|
26
|
+
scheduled_jobs = serializers.IntegerField(default=0, help_text="Scheduled jobs")
|
|
27
|
+
workers = serializers.IntegerField(
|
|
28
|
+
default=0, help_text="Number of workers for this queue"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class QueueDetailSerializer(serializers.Serializer):
|
|
33
|
+
"""
|
|
34
|
+
Detailed queue information serializer.
|
|
35
|
+
|
|
36
|
+
Provides comprehensive queue statistics and metadata.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
name = serializers.CharField(help_text="Queue name")
|
|
40
|
+
count = serializers.IntegerField(help_text="Total jobs in queue")
|
|
41
|
+
|
|
42
|
+
# Job counts by status
|
|
43
|
+
queued_jobs = serializers.IntegerField(
|
|
44
|
+
default=0, help_text="Jobs waiting to be processed"
|
|
45
|
+
)
|
|
46
|
+
started_jobs = serializers.IntegerField(
|
|
47
|
+
default=0, help_text="Jobs currently being processed"
|
|
48
|
+
)
|
|
49
|
+
finished_jobs = serializers.IntegerField(default=0, help_text="Completed jobs")
|
|
50
|
+
failed_jobs = serializers.IntegerField(default=0, help_text="Failed jobs")
|
|
51
|
+
deferred_jobs = serializers.IntegerField(default=0, help_text="Deferred jobs")
|
|
52
|
+
scheduled_jobs = serializers.IntegerField(default=0, help_text="Scheduled jobs")
|
|
53
|
+
|
|
54
|
+
# Worker information
|
|
55
|
+
workers = serializers.IntegerField(
|
|
56
|
+
default=0, help_text="Number of workers for this queue"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Metadata
|
|
60
|
+
oldest_job_timestamp = serializers.DateTimeField(
|
|
61
|
+
allow_null=True,
|
|
62
|
+
required=False,
|
|
63
|
+
help_text="Timestamp of oldest job in queue",
|
|
64
|
+
)
|
|
65
|
+
connection_kwargs = serializers.DictField(
|
|
66
|
+
default=dict, help_text="Redis connection parameters"
|
|
67
|
+
)
|
|
68
|
+
is_async = serializers.BooleanField(default=True, help_text="Queue is in async mode")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class QueueJobListSerializer(serializers.Serializer):
|
|
72
|
+
"""
|
|
73
|
+
List of jobs in queue (simple view).
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
queue_name = serializers.CharField(help_text="Queue name")
|
|
77
|
+
total_jobs = serializers.IntegerField(help_text="Total number of jobs")
|
|
78
|
+
jobs = serializers.ListField(
|
|
79
|
+
child=serializers.CharField(), default=list, help_text="List of job IDs"
|
|
80
|
+
)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Schedule management serializers for Django-RQ.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ScheduleCreateSerializer(serializers.Serializer):
|
|
9
|
+
"""
|
|
10
|
+
Serializer for creating a scheduled job.
|
|
11
|
+
|
|
12
|
+
Supports three scheduling methods:
|
|
13
|
+
1. scheduled_time: Schedule job at specific time
|
|
14
|
+
2. interval: Schedule job to repeat at intervals
|
|
15
|
+
3. cron: Schedule job with cron expression
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Job configuration
|
|
19
|
+
func = serializers.CharField(
|
|
20
|
+
help_text="Function path (e.g., 'myapp.tasks.my_task')"
|
|
21
|
+
)
|
|
22
|
+
args = serializers.ListField(
|
|
23
|
+
default=list,
|
|
24
|
+
required=False,
|
|
25
|
+
help_text="Function arguments"
|
|
26
|
+
)
|
|
27
|
+
kwargs = serializers.DictField(
|
|
28
|
+
default=dict,
|
|
29
|
+
required=False,
|
|
30
|
+
help_text="Function keyword arguments"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Queue configuration
|
|
34
|
+
queue_name = serializers.CharField(
|
|
35
|
+
default="default",
|
|
36
|
+
help_text="Queue name to schedule job in"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Scheduling options (choose one)
|
|
40
|
+
scheduled_time = serializers.DateTimeField(
|
|
41
|
+
required=False,
|
|
42
|
+
allow_null=True,
|
|
43
|
+
help_text="Schedule job at specific time (ISO 8601)"
|
|
44
|
+
)
|
|
45
|
+
interval = serializers.IntegerField(
|
|
46
|
+
required=False,
|
|
47
|
+
allow_null=True,
|
|
48
|
+
min_value=1,
|
|
49
|
+
help_text="Schedule job to repeat every N seconds"
|
|
50
|
+
)
|
|
51
|
+
cron = serializers.CharField(
|
|
52
|
+
required=False,
|
|
53
|
+
allow_null=True,
|
|
54
|
+
help_text="Cron expression (e.g., '0 0 * * *' for daily at midnight)"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Job options
|
|
58
|
+
timeout = serializers.IntegerField(
|
|
59
|
+
required=False,
|
|
60
|
+
allow_null=True,
|
|
61
|
+
help_text="Job timeout in seconds"
|
|
62
|
+
)
|
|
63
|
+
result_ttl = serializers.IntegerField(
|
|
64
|
+
required=False,
|
|
65
|
+
allow_null=True,
|
|
66
|
+
help_text="Result TTL in seconds"
|
|
67
|
+
)
|
|
68
|
+
repeat = serializers.IntegerField(
|
|
69
|
+
required=False,
|
|
70
|
+
allow_null=True,
|
|
71
|
+
help_text="Number of times to repeat (None = infinite)"
|
|
72
|
+
)
|
|
73
|
+
description = serializers.CharField(
|
|
74
|
+
required=False,
|
|
75
|
+
allow_null=True,
|
|
76
|
+
max_length=255,
|
|
77
|
+
help_text="Job description"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
def validate(self, attrs):
|
|
81
|
+
"""Validate that exactly one scheduling method is provided."""
|
|
82
|
+
scheduling_methods = [
|
|
83
|
+
attrs.get('scheduled_time'),
|
|
84
|
+
attrs.get('interval'),
|
|
85
|
+
attrs.get('cron'),
|
|
86
|
+
]
|
|
87
|
+
provided_methods = [m for m in scheduling_methods if m is not None]
|
|
88
|
+
|
|
89
|
+
if len(provided_methods) == 0:
|
|
90
|
+
raise serializers.ValidationError(
|
|
91
|
+
"Must provide one of: scheduled_time, interval, or cron"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if len(provided_methods) > 1:
|
|
95
|
+
raise serializers.ValidationError(
|
|
96
|
+
"Can only provide one scheduling method: scheduled_time, interval, or cron"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
return attrs
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ScheduledJobSerializer(serializers.Serializer):
|
|
103
|
+
"""
|
|
104
|
+
Serializer for scheduled job information.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
id = serializers.CharField(help_text="Job ID")
|
|
108
|
+
func = serializers.CharField(help_text="Function path")
|
|
109
|
+
args = serializers.ListField(default=list, help_text="Function arguments")
|
|
110
|
+
kwargs = serializers.DictField(default=dict, help_text="Function keyword arguments")
|
|
111
|
+
|
|
112
|
+
# Schedule info
|
|
113
|
+
queue_name = serializers.CharField(help_text="Queue name")
|
|
114
|
+
scheduled_time = serializers.DateTimeField(
|
|
115
|
+
allow_null=True,
|
|
116
|
+
required=False,
|
|
117
|
+
help_text="Next scheduled time"
|
|
118
|
+
)
|
|
119
|
+
interval = serializers.IntegerField(
|
|
120
|
+
allow_null=True,
|
|
121
|
+
required=False,
|
|
122
|
+
help_text="Repeat interval in seconds"
|
|
123
|
+
)
|
|
124
|
+
cron = serializers.CharField(
|
|
125
|
+
allow_null=True,
|
|
126
|
+
required=False,
|
|
127
|
+
help_text="Cron expression"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Job options
|
|
131
|
+
timeout = serializers.IntegerField(
|
|
132
|
+
allow_null=True,
|
|
133
|
+
required=False,
|
|
134
|
+
help_text="Job timeout in seconds"
|
|
135
|
+
)
|
|
136
|
+
result_ttl = serializers.IntegerField(
|
|
137
|
+
allow_null=True,
|
|
138
|
+
required=False,
|
|
139
|
+
help_text="Result TTL in seconds"
|
|
140
|
+
)
|
|
141
|
+
repeat = serializers.IntegerField(
|
|
142
|
+
allow_null=True,
|
|
143
|
+
required=False,
|
|
144
|
+
help_text="Times to repeat (None = infinite)"
|
|
145
|
+
)
|
|
146
|
+
description = serializers.CharField(
|
|
147
|
+
allow_null=True,
|
|
148
|
+
required=False,
|
|
149
|
+
help_text="Job description"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# Metadata
|
|
153
|
+
created_at = serializers.DateTimeField(
|
|
154
|
+
allow_null=True,
|
|
155
|
+
required=False,
|
|
156
|
+
help_text="Job creation time"
|
|
157
|
+
)
|
|
158
|
+
meta = serializers.DictField(
|
|
159
|
+
default=dict,
|
|
160
|
+
help_text="Job metadata"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class ScheduleActionResponseSerializer(serializers.Serializer):
|
|
165
|
+
"""
|
|
166
|
+
Response serializer for schedule actions (create/delete).
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
success = serializers.BooleanField(help_text="Action success status")
|
|
170
|
+
message = serializers.CharField(help_text="Action result message")
|
|
171
|
+
job_id = serializers.CharField(
|
|
172
|
+
required=False,
|
|
173
|
+
allow_null=True,
|
|
174
|
+
help_text="Job ID (for create action)"
|
|
175
|
+
)
|
|
176
|
+
action = serializers.CharField(
|
|
177
|
+
help_text="Action performed (create/delete/cancel)"
|
|
178
|
+
)
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DRF serializers for RQ testing and simulation endpoints.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestScenarioSerializer(serializers.Serializer):
|
|
9
|
+
"""Serializer for available test scenarios."""
|
|
10
|
+
|
|
11
|
+
id = serializers.CharField(help_text="Scenario ID")
|
|
12
|
+
name = serializers.CharField(help_text="Scenario name")
|
|
13
|
+
description = serializers.CharField(help_text="Scenario description")
|
|
14
|
+
task_func = serializers.CharField(help_text="Task function path")
|
|
15
|
+
default_args = serializers.ListField(
|
|
16
|
+
child=serializers.JSONField(),
|
|
17
|
+
required=False,
|
|
18
|
+
default=list,
|
|
19
|
+
help_text="Default arguments"
|
|
20
|
+
)
|
|
21
|
+
default_kwargs = serializers.DictField(
|
|
22
|
+
required=False,
|
|
23
|
+
default=dict,
|
|
24
|
+
help_text="Default keyword arguments"
|
|
25
|
+
)
|
|
26
|
+
estimated_duration = serializers.IntegerField(
|
|
27
|
+
required=False,
|
|
28
|
+
allow_null=True,
|
|
29
|
+
help_text="Estimated duration in seconds"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class RunDemoRequestSerializer(serializers.Serializer):
|
|
34
|
+
"""Serializer for running demo tasks."""
|
|
35
|
+
|
|
36
|
+
scenario = serializers.ChoiceField(
|
|
37
|
+
choices=[
|
|
38
|
+
'success',
|
|
39
|
+
'failure',
|
|
40
|
+
'slow',
|
|
41
|
+
'progress',
|
|
42
|
+
'retry',
|
|
43
|
+
'random',
|
|
44
|
+
'memory',
|
|
45
|
+
'cpu',
|
|
46
|
+
],
|
|
47
|
+
help_text="Demo scenario to run"
|
|
48
|
+
)
|
|
49
|
+
queue = serializers.CharField(
|
|
50
|
+
default='default',
|
|
51
|
+
help_text="Queue name"
|
|
52
|
+
)
|
|
53
|
+
args = serializers.ListField(
|
|
54
|
+
child=serializers.JSONField(),
|
|
55
|
+
required=False,
|
|
56
|
+
default=list,
|
|
57
|
+
help_text="Task arguments"
|
|
58
|
+
)
|
|
59
|
+
kwargs = serializers.DictField(
|
|
60
|
+
required=False,
|
|
61
|
+
default=dict,
|
|
62
|
+
help_text="Task keyword arguments"
|
|
63
|
+
)
|
|
64
|
+
timeout = serializers.IntegerField(
|
|
65
|
+
required=False,
|
|
66
|
+
allow_null=True,
|
|
67
|
+
help_text="Job timeout in seconds"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class StressTestRequestSerializer(serializers.Serializer):
|
|
72
|
+
"""Serializer for stress testing."""
|
|
73
|
+
|
|
74
|
+
num_jobs = serializers.IntegerField(
|
|
75
|
+
min_value=1,
|
|
76
|
+
max_value=1000,
|
|
77
|
+
default=10,
|
|
78
|
+
help_text="Number of jobs to create"
|
|
79
|
+
)
|
|
80
|
+
queue = serializers.CharField(
|
|
81
|
+
default='default',
|
|
82
|
+
help_text="Queue name"
|
|
83
|
+
)
|
|
84
|
+
scenario = serializers.ChoiceField(
|
|
85
|
+
choices=['success', 'failure', 'slow', 'random'],
|
|
86
|
+
default='success',
|
|
87
|
+
help_text="Task scenario"
|
|
88
|
+
)
|
|
89
|
+
duration = serializers.IntegerField(
|
|
90
|
+
min_value=1,
|
|
91
|
+
max_value=60,
|
|
92
|
+
default=2,
|
|
93
|
+
help_text="Task duration in seconds"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TestingActionResponseSerializer(serializers.Serializer):
|
|
98
|
+
"""Serializer for testing action responses."""
|
|
99
|
+
|
|
100
|
+
success = serializers.BooleanField(help_text="Action success status")
|
|
101
|
+
message = serializers.CharField(help_text="Action message")
|
|
102
|
+
job_ids = serializers.ListField(
|
|
103
|
+
child=serializers.CharField(),
|
|
104
|
+
required=False,
|
|
105
|
+
default=list,
|
|
106
|
+
help_text="Created job IDs"
|
|
107
|
+
)
|
|
108
|
+
count = serializers.IntegerField(
|
|
109
|
+
required=False,
|
|
110
|
+
allow_null=True,
|
|
111
|
+
help_text="Number of items affected"
|
|
112
|
+
)
|
|
113
|
+
metadata = serializers.DictField(
|
|
114
|
+
required=False,
|
|
115
|
+
default=dict,
|
|
116
|
+
help_text="Additional metadata"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class CleanupRequestSerializer(serializers.Serializer):
|
|
121
|
+
"""Serializer for cleanup operations."""
|
|
122
|
+
|
|
123
|
+
queue = serializers.CharField(
|
|
124
|
+
required=False,
|
|
125
|
+
allow_blank=True,
|
|
126
|
+
help_text="Queue name (empty for all queues)"
|
|
127
|
+
)
|
|
128
|
+
registries = serializers.ListField(
|
|
129
|
+
child=serializers.ChoiceField(
|
|
130
|
+
choices=['failed', 'finished', 'deferred', 'scheduled']
|
|
131
|
+
),
|
|
132
|
+
required=False,
|
|
133
|
+
default=list,
|
|
134
|
+
help_text="Registries to clean"
|
|
135
|
+
)
|
|
136
|
+
delete_demo_jobs_only = serializers.BooleanField(
|
|
137
|
+
default=True,
|
|
138
|
+
help_text="Only delete demo jobs (func starts with 'demo_')"
|
|
139
|
+
)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Worker information serializers for Django-RQ.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WorkerSerializer(serializers.Serializer):
|
|
9
|
+
"""
|
|
10
|
+
Worker information serializer.
|
|
11
|
+
|
|
12
|
+
Provides detailed information about an RQ worker.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
name = serializers.CharField(help_text="Worker name/ID")
|
|
16
|
+
queues = serializers.ListField(
|
|
17
|
+
child=serializers.CharField(), default=list, help_text="List of queue names"
|
|
18
|
+
)
|
|
19
|
+
state = serializers.CharField(help_text="Worker state (idle/busy/suspended)")
|
|
20
|
+
current_job = serializers.CharField(
|
|
21
|
+
allow_null=True, required=False, help_text="Current job ID if busy"
|
|
22
|
+
)
|
|
23
|
+
birth = serializers.DateTimeField(help_text="Worker start time")
|
|
24
|
+
last_heartbeat = serializers.DateTimeField(help_text="Last heartbeat timestamp")
|
|
25
|
+
successful_job_count = serializers.IntegerField(
|
|
26
|
+
default=0, help_text="Total successful jobs"
|
|
27
|
+
)
|
|
28
|
+
failed_job_count = serializers.IntegerField(default=0, help_text="Total failed jobs")
|
|
29
|
+
total_working_time = serializers.FloatField(
|
|
30
|
+
default=0.0, help_text="Total working time in seconds"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WorkerStatsSerializer(serializers.Serializer):
|
|
35
|
+
"""
|
|
36
|
+
Aggregated worker statistics serializer.
|
|
37
|
+
|
|
38
|
+
Provides overview of all workers across all queues.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
total_workers = serializers.IntegerField(help_text="Total number of workers")
|
|
42
|
+
busy_workers = serializers.IntegerField(default=0, help_text="Number of busy workers")
|
|
43
|
+
idle_workers = serializers.IntegerField(default=0, help_text="Number of idle workers")
|
|
44
|
+
suspended_workers = serializers.IntegerField(
|
|
45
|
+
default=0, help_text="Number of suspended workers"
|
|
46
|
+
)
|
|
47
|
+
total_successful_jobs = serializers.IntegerField(
|
|
48
|
+
default=0, help_text="Total successful jobs (all workers)"
|
|
49
|
+
)
|
|
50
|
+
total_failed_jobs = serializers.IntegerField(
|
|
51
|
+
default=0, help_text="Total failed jobs (all workers)"
|
|
52
|
+
)
|
|
53
|
+
total_working_time = serializers.FloatField(
|
|
54
|
+
default=0.0, help_text="Total working time across all workers (seconds)"
|
|
55
|
+
)
|
|
56
|
+
workers = serializers.ListField(
|
|
57
|
+
child=WorkerSerializer(), default=list, help_text="List of individual workers"
|
|
58
|
+
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Services for Django-RQ monitoring.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .config_helper import (
|
|
6
|
+
get_redis_url,
|
|
7
|
+
get_rq_config,
|
|
8
|
+
is_prometheus_enabled,
|
|
9
|
+
is_rq_enabled,
|
|
10
|
+
register_schedules_from_config,
|
|
11
|
+
)
|
|
12
|
+
from .rq_converters import job_to_model, queue_to_model, worker_to_model
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
# Converters
|
|
16
|
+
'job_to_model',
|
|
17
|
+
'queue_to_model',
|
|
18
|
+
'worker_to_model',
|
|
19
|
+
# Config helpers
|
|
20
|
+
'get_redis_url',
|
|
21
|
+
'get_rq_config',
|
|
22
|
+
'is_rq_enabled',
|
|
23
|
+
'is_prometheus_enabled',
|
|
24
|
+
'register_schedules_from_config',
|
|
25
|
+
]
|