django-cfg 1.4.107__py3-none-any.whl → 1.4.109__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/accounts/views/profile.py +19 -9
- django_cfg/apps/centrifugo/views/admin_api.py +4 -7
- django_cfg/apps/centrifugo/views/monitoring.py +3 -6
- django_cfg/apps/centrifugo/views/testing_api.py +3 -6
- django_cfg/apps/dashboard/services/system_health_service.py +16 -11
- django_cfg/apps/dashboard/views/activity_views.py +3 -5
- django_cfg/apps/dashboard/views/apizones_views.py +4 -5
- django_cfg/apps/dashboard/views/charts_views.py +4 -5
- django_cfg/apps/dashboard/views/overview_views.py +4 -5
- django_cfg/apps/dashboard/views/statistics_views.py +4 -5
- django_cfg/apps/dashboard/views/system_views.py +4 -5
- django_cfg/apps/knowbase/__init__.py +2 -2
- django_cfg/apps/knowbase/apps.py +2 -8
- django_cfg/apps/knowbase/views/base.py +9 -4
- django_cfg/apps/support/views/api.py +16 -7
- django_cfg/apps/tasks/__init__.py +61 -2
- django_cfg/apps/tasks/admin/__init__.py +3 -10
- django_cfg/apps/tasks/admin/config.py +98 -0
- django_cfg/apps/tasks/admin/task_log.py +265 -0
- django_cfg/apps/tasks/apps.py +7 -9
- django_cfg/apps/tasks/filters/__init__.py +10 -0
- django_cfg/apps/tasks/filters/task_log.py +121 -0
- django_cfg/apps/tasks/migrations/0001_initial.py +196 -0
- django_cfg/apps/tasks/models/__init__.py +4 -0
- django_cfg/apps/tasks/models/task_log.py +246 -0
- django_cfg/apps/tasks/serializers/__init__.py +28 -0
- django_cfg/apps/tasks/serializers/task_log.py +249 -0
- django_cfg/apps/tasks/services/__init__.py +10 -0
- django_cfg/apps/tasks/services/client/__init__.py +7 -0
- django_cfg/apps/tasks/services/client/client.py +234 -0
- django_cfg/apps/tasks/services/config_helper.py +63 -0
- django_cfg/apps/tasks/services/sync.py +204 -0
- django_cfg/apps/tasks/urls.py +7 -13
- django_cfg/apps/tasks/views/__init__.py +4 -10
- django_cfg/apps/tasks/views/task_log.py +41 -0
- django_cfg/apps/tasks/views/task_log_base.py +41 -0
- django_cfg/apps/tasks/views/task_log_overview.py +100 -0
- django_cfg/apps/tasks/views/task_log_related.py +41 -0
- django_cfg/apps/tasks/views/task_log_stats.py +91 -0
- django_cfg/apps/tasks/views/task_log_timeline.py +81 -0
- django_cfg/apps/urls.py +0 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/utils.py +1 -1
- django_cfg/core/base/config_model.py +1 -1
- django_cfg/core/builders/apps_builder.py +1 -1
- django_cfg/core/generation/integration_generators/__init__.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +14 -18
- django_cfg/core/generation/security_generators/crypto_fields.py +2 -1
- django_cfg/core/integration/display/startup.py +1 -1
- django_cfg/mixins/__init__.py +12 -0
- django_cfg/mixins/admin_api.py +37 -0
- django_cfg/mixins/client_api.py +39 -0
- django_cfg/models/django/constance.py +2 -8
- django_cfg/models/django/crypto_fields.py +13 -48
- django_cfg/models/tasks/__init__.py +8 -10
- django_cfg/models/tasks/backends.py +76 -207
- django_cfg/models/tasks/config.py +20 -127
- django_cfg/models/tasks/utils.py +17 -29
- django_cfg/modules/django_client/management/commands/generate_client.py +13 -1
- django_cfg/modules/django_unfold/navigation.py +121 -22
- django_cfg/pyproject.toml +2 -2
- django_cfg/registry/core.py +1 -1
- django_cfg/static/frontend/admin.zip +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/METADATA +3 -3
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/RECORD +70 -117
- django_cfg/apps/tasks/admin/actions.py +0 -29
- django_cfg/apps/tasks/admin/tasks_admin.py +0 -154
- django_cfg/apps/tasks/api/serializers.py +0 -82
- django_cfg/apps/tasks/api/views.py +0 -571
- django_cfg/apps/tasks/serializers.py +0 -82
- django_cfg/apps/tasks/static/tasks/css/dashboard-alpine.css +0 -299
- django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -120
- django_cfg/apps/tasks/static/tasks/js/alpine/README.md +0 -47
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/index.js +0 -8
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/management.js +0 -123
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/pagination.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/tasks.js +0 -101
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/workers.js +0 -59
- django_cfg/apps/tasks/static/tasks/js/alpine/computed.js +0 -35
- django_cfg/apps/tasks/static/tasks/js/alpine/index.js +0 -148
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/index.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/overview.js +0 -37
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/queues.js +0 -27
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/tasks.js +0 -32
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/workers.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/state.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/formatters.js +0 -42
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/helpers.js +0 -68
- django_cfg/apps/tasks/static/tasks/js/dashboard-alpine.js +0 -725
- django_cfg/apps/tasks/tasks/__init__.py +0 -10
- django_cfg/apps/tasks/tasks/demo_tasks.py +0 -127
- django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -71
- django_cfg/apps/tasks/templates/tasks/components/overview_content.html +0 -94
- django_cfg/apps/tasks/templates/tasks/components/queues_content.html +0 -44
- django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -45
- django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -151
- django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +0 -61
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +0 -269
- django_cfg/apps/tasks/templates/tasks/components/workers_content.html +0 -60
- django_cfg/apps/tasks/templates/tasks/layout/base.html +0 -20
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +0 -168
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +0 -77
- django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +0 -86
- django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +0 -90
- django_cfg/apps/tasks/urls_admin.py +0 -15
- django_cfg/apps/tasks/utils/__init__.py +0 -1
- django_cfg/apps/tasks/utils/simulator.py +0 -353
- django_cfg/apps/tasks/views/api.py +0 -571
- django_cfg/apps/tasks/views/dashboard.py +0 -89
- django_cfg/management/commands/rundramatiq.py +0 -24
- django_cfg/management/commands/rundramatiq_simulator.py +0 -22
- django_cfg/management/commands/task_clear.py +0 -25
- django_cfg/management/commands/task_status.py +0 -24
- django_cfg/modules/django_client/system/__init__.py +0 -24
- django_cfg/modules/django_client/system/base_generator.py +0 -123
- django_cfg/modules/django_client/system/generate_mjs_clients.py +0 -176
- django_cfg/modules/django_client/system/mjs_generator.py +0 -219
- django_cfg/modules/django_client/system/schema_parser.py +0 -199
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +0 -87
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +0 -13
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +0 -166
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +0 -80
- django_cfg/modules/django_client/system/templates/types.js.j2 +0 -24
- django_cfg/modules/django_tasks/__init__.py +0 -29
- django_cfg/modules/django_tasks/dramatiq_setup.py +0 -20
- django_cfg/modules/django_tasks/factory.py +0 -127
- django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +0 -253
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +0 -436
- django_cfg/modules/django_tasks/management/commands/task_clear.py +0 -226
- django_cfg/modules/django_tasks/management/commands/task_status.py +0 -257
- django_cfg/modules/django_tasks/service.py +0 -281
- django_cfg/modules/django_tasks/settings.py +0 -107
- /django_cfg/{modules/django_tasks/management → apps/tasks/migrations}/__init__.py +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.107.dist-info → django_cfg-1.4.109.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from rest_framework import generics, permissions, status
|
|
|
4
4
|
from rest_framework.decorators import api_view, permission_classes
|
|
5
5
|
from rest_framework.response import Response
|
|
6
6
|
|
|
7
|
+
from django_cfg.mixins import ClientAPIMixin
|
|
7
8
|
from ..serializers.profile import (
|
|
8
9
|
AvatarUploadSerializer,
|
|
9
10
|
UserProfileUpdateSerializer,
|
|
@@ -22,10 +23,13 @@ User = get_user_model()
|
|
|
22
23
|
401: {"description": "Authentication credentials were not provided."}
|
|
23
24
|
}
|
|
24
25
|
)
|
|
25
|
-
class UserProfileView(generics.RetrieveAPIView):
|
|
26
|
-
"""
|
|
26
|
+
class UserProfileView(ClientAPIMixin, generics.RetrieveAPIView):
|
|
27
|
+
"""
|
|
28
|
+
Get current user profile details.
|
|
29
|
+
|
|
30
|
+
Requires authenticated user (JWT or Session).
|
|
31
|
+
"""
|
|
27
32
|
serializer_class = UserSerializer
|
|
28
|
-
permission_classes = [permissions.IsAuthenticated]
|
|
29
33
|
|
|
30
34
|
def get_object(self):
|
|
31
35
|
return self.request.user
|
|
@@ -56,10 +60,13 @@ class UserProfileView(generics.RetrieveAPIView):
|
|
|
56
60
|
)
|
|
57
61
|
]
|
|
58
62
|
)
|
|
59
|
-
class UserProfileUpdateView(generics.UpdateAPIView):
|
|
60
|
-
"""
|
|
63
|
+
class UserProfileUpdateView(ClientAPIMixin, generics.UpdateAPIView):
|
|
64
|
+
"""
|
|
65
|
+
Update current user profile.
|
|
66
|
+
|
|
67
|
+
Requires authenticated user (JWT or Session).
|
|
68
|
+
"""
|
|
61
69
|
serializer_class = UserProfileUpdateSerializer
|
|
62
|
-
permission_classes = [permissions.IsAuthenticated]
|
|
63
70
|
|
|
64
71
|
def get_object(self):
|
|
65
72
|
return self.request.user
|
|
@@ -102,10 +109,13 @@ class UserProfileUpdateView(generics.UpdateAPIView):
|
|
|
102
109
|
)
|
|
103
110
|
]
|
|
104
111
|
)
|
|
105
|
-
class UserProfilePartialUpdateView(generics.UpdateAPIView):
|
|
106
|
-
"""
|
|
112
|
+
class UserProfilePartialUpdateView(ClientAPIMixin, generics.UpdateAPIView):
|
|
113
|
+
"""
|
|
114
|
+
Partially update current user profile.
|
|
115
|
+
|
|
116
|
+
Requires authenticated user (JWT or Session).
|
|
117
|
+
"""
|
|
107
118
|
serializer_class = UserProfileUpdateSerializer
|
|
108
|
-
permission_classes = [permissions.IsAuthenticated]
|
|
109
119
|
|
|
110
120
|
def get_object(self):
|
|
111
121
|
return self.request.user
|
|
@@ -11,11 +11,10 @@ from django.http import JsonResponse
|
|
|
11
11
|
from django_cfg.modules.django_logging import get_logger
|
|
12
12
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
|
13
13
|
from rest_framework import status, viewsets
|
|
14
|
-
from rest_framework.authentication import SessionAuthentication
|
|
15
14
|
from rest_framework.decorators import action
|
|
16
|
-
from rest_framework.permissions import IsAdminUser
|
|
17
15
|
from rest_framework.response import Response
|
|
18
16
|
|
|
17
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
19
18
|
from ..serializers import (
|
|
20
19
|
CentrifugoInfoRequest,
|
|
21
20
|
CentrifugoInfoResponse,
|
|
@@ -33,17 +32,15 @@ from ..services import get_centrifugo_config
|
|
|
33
32
|
logger = get_logger("centrifugo.admin_api")
|
|
34
33
|
|
|
35
34
|
|
|
36
|
-
class CentrifugoAdminAPIViewSet(viewsets.ViewSet):
|
|
35
|
+
class CentrifugoAdminAPIViewSet(AdminAPIMixin, viewsets.ViewSet):
|
|
37
36
|
"""
|
|
38
37
|
Centrifugo Admin API Proxy ViewSet.
|
|
39
38
|
|
|
40
39
|
Provides type-safe proxy endpoints to Centrifugo server API.
|
|
41
|
-
All requests are authenticated via Django session and proxied to Centrifugo.
|
|
40
|
+
All requests are authenticated via Django session/JWT and proxied to Centrifugo.
|
|
41
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
|
-
# authentication_classes = [SessionAuthentication]
|
|
45
|
-
permission_classes = [IsAdminUser]
|
|
46
|
-
|
|
47
44
|
def __init__(self, *args, **kwargs):
|
|
48
45
|
super().__init__(*args, **kwargs)
|
|
49
46
|
self._http_client = None
|
|
@@ -13,11 +13,10 @@ from django_cfg.modules.django_logging import get_logger
|
|
|
13
13
|
from drf_spectacular.types import OpenApiTypes
|
|
14
14
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
|
15
15
|
from rest_framework import status, viewsets
|
|
16
|
-
from rest_framework.authentication import SessionAuthentication
|
|
17
16
|
from rest_framework.decorators import action
|
|
18
|
-
from rest_framework.permissions import IsAdminUser
|
|
19
17
|
from rest_framework.response import Response
|
|
20
18
|
|
|
19
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
21
20
|
from ..models import CentrifugoLog
|
|
22
21
|
from ..serializers import (
|
|
23
22
|
ChannelListSerializer,
|
|
@@ -31,7 +30,7 @@ from ..services import get_centrifugo_config
|
|
|
31
30
|
logger = get_logger("centrifugo.monitoring")
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
class CentrifugoMonitorViewSet(viewsets.ViewSet):
|
|
33
|
+
class CentrifugoMonitorViewSet(AdminAPIMixin, viewsets.ViewSet):
|
|
35
34
|
"""
|
|
36
35
|
ViewSet for Centrifugo monitoring and statistics.
|
|
37
36
|
|
|
@@ -40,11 +39,9 @@ class CentrifugoMonitorViewSet(viewsets.ViewSet):
|
|
|
40
39
|
- Overview statistics
|
|
41
40
|
- Recent publishes
|
|
42
41
|
- Channel-level statistics
|
|
42
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
43
43
|
"""
|
|
44
44
|
|
|
45
|
-
# authentication_classes = [SessionAuthentication]
|
|
46
|
-
permission_classes = [IsAdminUser]
|
|
47
|
-
|
|
48
45
|
@extend_schema(
|
|
49
46
|
tags=["Centrifugo Monitoring"],
|
|
50
47
|
summary="Get Centrifugo health status",
|
|
@@ -17,11 +17,10 @@ from django_cfg.modules.django_logging import get_logger
|
|
|
17
17
|
from drf_spectacular.utils import extend_schema
|
|
18
18
|
from pydantic import BaseModel, Field
|
|
19
19
|
from rest_framework import status, viewsets
|
|
20
|
-
from rest_framework.authentication import SessionAuthentication
|
|
21
20
|
from rest_framework.decorators import action
|
|
22
|
-
from rest_framework.permissions import IsAdminUser
|
|
23
21
|
from rest_framework.response import Response
|
|
24
22
|
|
|
23
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
25
24
|
from ..services import get_centrifugo_config
|
|
26
25
|
from ..services.client import CentrifugoClient
|
|
27
26
|
|
|
@@ -94,18 +93,16 @@ class ManualAckResponse(BaseModel):
|
|
|
94
93
|
# ========================================================================
|
|
95
94
|
|
|
96
95
|
|
|
97
|
-
class CentrifugoTestingAPIViewSet(viewsets.ViewSet):
|
|
96
|
+
class CentrifugoTestingAPIViewSet(AdminAPIMixin, viewsets.ViewSet):
|
|
98
97
|
"""
|
|
99
98
|
Centrifugo Testing API ViewSet.
|
|
100
99
|
|
|
101
100
|
Provides endpoints for interactive testing of Centrifugo integration
|
|
102
101
|
from the dashboard. Includes connection token generation, test message
|
|
103
102
|
publishing, and manual ACK management.
|
|
103
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
104
104
|
"""
|
|
105
105
|
|
|
106
|
-
# authentication_classes = [SessionAuthentication]
|
|
107
|
-
permission_classes = [IsAdminUser]
|
|
108
|
-
|
|
109
106
|
def __init__(self, *args, **kwargs):
|
|
110
107
|
super().__init__(*args, **kwargs)
|
|
111
108
|
self._http_client = None
|
|
@@ -105,34 +105,39 @@ class SystemHealthService:
|
|
|
105
105
|
|
|
106
106
|
def check_queue_health(self) -> Dict[str, Any]:
|
|
107
107
|
"""
|
|
108
|
-
Check task queue (
|
|
108
|
+
Check task queue (ReArq) health via Redis connection.
|
|
109
109
|
|
|
110
110
|
Returns:
|
|
111
111
|
Health status dictionary
|
|
112
112
|
"""
|
|
113
113
|
try:
|
|
114
|
-
#
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
# Check Redis connection directly (used by task queue)
|
|
115
|
+
from django.core.cache import cache
|
|
116
|
+
|
|
117
|
+
# Try to ping Redis through cache backend
|
|
118
|
+
cache_backend = cache._cache if hasattr(cache, '_cache') else cache
|
|
117
119
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
# Simple check - if cache works, Redis is available
|
|
121
|
+
test_key = 'queue_health_check'
|
|
122
|
+
cache.set(test_key, 'ok', timeout=5)
|
|
123
|
+
result = cache.get(test_key)
|
|
120
124
|
|
|
121
|
-
if
|
|
125
|
+
if result == 'ok':
|
|
126
|
+
cache.delete(test_key)
|
|
122
127
|
return {
|
|
123
128
|
'component': 'queue',
|
|
124
129
|
'status': 'healthy',
|
|
125
|
-
'description': 'Queue system is operational',
|
|
130
|
+
'description': 'Queue system (Redis) is operational',
|
|
126
131
|
'last_check': datetime.now().isoformat(),
|
|
127
132
|
'health_percentage': 100,
|
|
128
133
|
}
|
|
129
134
|
else:
|
|
130
135
|
return {
|
|
131
136
|
'component': 'queue',
|
|
132
|
-
'status': '
|
|
133
|
-
'description': 'Queue system
|
|
137
|
+
'status': 'warning',
|
|
138
|
+
'description': 'Queue system check inconclusive',
|
|
134
139
|
'last_check': datetime.now().isoformat(),
|
|
135
|
-
'health_percentage':
|
|
140
|
+
'health_percentage': 50,
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
except Exception as e:
|
|
@@ -10,26 +10,24 @@ import logging
|
|
|
10
10
|
|
|
11
11
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
|
12
12
|
from rest_framework import status, viewsets
|
|
13
|
-
from rest_framework.authentication import BasicAuthentication, SessionAuthentication
|
|
14
13
|
from rest_framework.decorators import action
|
|
15
|
-
from rest_framework.permissions import IsAdminUser
|
|
16
14
|
from rest_framework.response import Response
|
|
17
15
|
|
|
16
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
18
17
|
from ..services import StatisticsService, SystemHealthService
|
|
19
18
|
from ..serializers import ActivityEntrySerializer, QuickActionSerializer
|
|
20
19
|
|
|
21
20
|
logger = logging.getLogger(__name__)
|
|
22
21
|
|
|
23
22
|
|
|
24
|
-
class ActivityViewSet(viewsets.GenericViewSet):
|
|
23
|
+
class ActivityViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
25
24
|
"""
|
|
26
25
|
Activity Tracking ViewSet
|
|
27
26
|
|
|
28
27
|
Provides endpoints for recent activity and quick actions.
|
|
28
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
32
|
-
permission_classes = [IsAdminUser]
|
|
33
31
|
serializer_class = ActivityEntrySerializer
|
|
34
32
|
|
|
35
33
|
@extend_schema(
|
|
@@ -10,9 +10,9 @@ import logging
|
|
|
10
10
|
|
|
11
11
|
from drf_spectacular.utils import extend_schema
|
|
12
12
|
from rest_framework import status, viewsets
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
14
15
|
from rest_framework.decorators import action
|
|
15
|
-
from rest_framework.permissions import IsAdminUser
|
|
16
16
|
from rest_framework.response import Response
|
|
17
17
|
|
|
18
18
|
from ..services import APIZonesService
|
|
@@ -21,15 +21,14 @@ from ..serializers import APIZoneSerializer, APIZonesSummarySerializer
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class APIZonesViewSet(viewsets.GenericViewSet):
|
|
24
|
+
class APIZonesViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
25
25
|
"""
|
|
26
26
|
API Zones ViewSet
|
|
27
27
|
|
|
28
28
|
Provides endpoints for OpenAPI zones (groups) management.
|
|
29
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
32
|
-
permission_classes = [IsAdminUser]
|
|
33
32
|
serializer_class = APIZoneSerializer
|
|
34
33
|
pagination_class = None # Disable pagination for zones list
|
|
35
34
|
|
|
@@ -12,9 +12,9 @@ import logging
|
|
|
12
12
|
|
|
13
13
|
from drf_spectacular.utils import OpenApiParameter, extend_schema
|
|
14
14
|
from rest_framework import status, viewsets
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
16
17
|
from rest_framework.decorators import action
|
|
17
|
-
from rest_framework.permissions import IsAdminUser
|
|
18
18
|
from rest_framework.response import Response
|
|
19
19
|
|
|
20
20
|
from ..services import ChartsService, StatisticsService
|
|
@@ -27,15 +27,14 @@ from ..serializers import (
|
|
|
27
27
|
logger = logging.getLogger(__name__)
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
class ChartsViewSet(viewsets.GenericViewSet):
|
|
30
|
+
class ChartsViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
31
31
|
"""
|
|
32
32
|
Charts ViewSet
|
|
33
33
|
|
|
34
34
|
Provides endpoints for dashboard charts and analytics.
|
|
35
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
35
36
|
"""
|
|
36
37
|
|
|
37
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
38
|
-
permission_classes = [IsAdminUser]
|
|
39
38
|
serializer_class = ChartDataSerializer
|
|
40
39
|
|
|
41
40
|
@extend_schema(
|
|
@@ -10,9 +10,9 @@ from datetime import datetime
|
|
|
10
10
|
|
|
11
11
|
from drf_spectacular.utils import extend_schema
|
|
12
12
|
from rest_framework import status, viewsets
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
14
15
|
from rest_framework.decorators import action
|
|
15
|
-
from rest_framework.permissions import IsAdminUser
|
|
16
16
|
from rest_framework.response import Response
|
|
17
17
|
|
|
18
18
|
from ..services import StatisticsService, SystemHealthService, ChartsService
|
|
@@ -21,16 +21,15 @@ from ..serializers import DashboardOverviewSerializer
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class OverviewViewSet(viewsets.GenericViewSet):
|
|
24
|
+
class OverviewViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
25
25
|
"""
|
|
26
26
|
Dashboard Overview ViewSet
|
|
27
27
|
|
|
28
28
|
Provides a single endpoint that returns all dashboard data at once.
|
|
29
29
|
Useful for initial page load.
|
|
30
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
30
31
|
"""
|
|
31
32
|
|
|
32
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
33
|
-
permission_classes = [IsAdminUser]
|
|
34
33
|
serializer_class = DashboardOverviewSerializer
|
|
35
34
|
|
|
36
35
|
@extend_schema(
|
|
@@ -11,9 +11,9 @@ import logging
|
|
|
11
11
|
|
|
12
12
|
from drf_spectacular.utils import extend_schema
|
|
13
13
|
from rest_framework import status, viewsets
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
15
16
|
from rest_framework.decorators import action
|
|
16
|
-
from rest_framework.permissions import IsAdminUser
|
|
17
17
|
from rest_framework.response import Response
|
|
18
18
|
|
|
19
19
|
from ..services import StatisticsService
|
|
@@ -26,15 +26,14 @@ from ..serializers import (
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
class StatisticsViewSet(viewsets.GenericViewSet):
|
|
29
|
+
class StatisticsViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
30
30
|
"""
|
|
31
31
|
Statistics ViewSet
|
|
32
32
|
|
|
33
33
|
Provides endpoints for retrieving various dashboard statistics.
|
|
34
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
34
35
|
"""
|
|
35
36
|
|
|
36
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
37
|
-
permission_classes = [IsAdminUser]
|
|
38
37
|
serializer_class = StatCardSerializer
|
|
39
38
|
|
|
40
39
|
@extend_schema(
|
|
@@ -10,9 +10,9 @@ import logging
|
|
|
10
10
|
|
|
11
11
|
from drf_spectacular.utils import extend_schema
|
|
12
12
|
from rest_framework import status, viewsets
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
from django_cfg.mixins import AdminAPIMixin
|
|
14
15
|
from rest_framework.decorators import action
|
|
15
|
-
from rest_framework.permissions import IsAdminUser
|
|
16
16
|
from rest_framework.response import Response
|
|
17
17
|
|
|
18
18
|
from ..services import SystemHealthService, StatisticsService
|
|
@@ -21,15 +21,14 @@ from ..serializers import SystemHealthSerializer, SystemMetricsSerializer
|
|
|
21
21
|
logger = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
class SystemViewSet(viewsets.GenericViewSet):
|
|
24
|
+
class SystemViewSet(AdminAPIMixin, viewsets.GenericViewSet):
|
|
25
25
|
"""
|
|
26
26
|
System Monitoring ViewSet
|
|
27
27
|
|
|
28
28
|
Provides endpoints for system health and performance metrics.
|
|
29
|
+
Requires admin authentication (JWT, Session, or Basic Auth).
|
|
29
30
|
"""
|
|
30
31
|
|
|
31
|
-
authentication_classes = [SessionAuthentication, BasicAuthentication]
|
|
32
|
-
permission_classes = [IsAdminUser]
|
|
33
32
|
serializer_class = SystemHealthSerializer
|
|
34
33
|
|
|
35
34
|
@extend_schema(
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Django SaaS Knowledge Assistant
|
|
3
3
|
|
|
4
4
|
Enterprise-grade RAG (Retrieval-Augmented Generation) application built on Django 5.2
|
|
5
|
-
with pgvector semantic search,
|
|
5
|
+
with pgvector semantic search, ReArq background processing, and comprehensive
|
|
6
6
|
API endpoints for document management and AI-powered chat.
|
|
7
7
|
|
|
8
8
|
Key Features:
|
|
@@ -10,7 +10,7 @@ Key Features:
|
|
|
10
10
|
- Semantic search using pgvector cosine similarity
|
|
11
11
|
- RAG-powered chat with context retrieval
|
|
12
12
|
- Multi-tenant user isolation
|
|
13
|
-
- Background processing with
|
|
13
|
+
- Background processing with ReArq
|
|
14
14
|
- Cost tracking for LLM usage monitoring
|
|
15
15
|
- Comprehensive admin interface with Unfold styling
|
|
16
16
|
- Type-safe APIs with Pydantic v2 validation
|
django_cfg/apps/knowbase/apps.py
CHANGED
|
@@ -21,14 +21,8 @@ class KnowbaseConfig(AppConfig):
|
|
|
21
21
|
# Connect post-migrate signal for database setup
|
|
22
22
|
post_migrate.connect(self.create_pgvector_extension, sender=self)
|
|
23
23
|
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
from django_cfg.modules.django_tasks import initialize_task_system
|
|
27
|
-
initialize_task_system()
|
|
28
|
-
except Exception as e:
|
|
29
|
-
import logging
|
|
30
|
-
logger = logging.getLogger(__name__)
|
|
31
|
-
logger.warning(f"Failed to initialize task system: {e}")
|
|
24
|
+
# Note: Task system initialization removed - ReArq doesn't need it
|
|
25
|
+
# Tasks are auto-discovered from decorated functions
|
|
32
26
|
|
|
33
27
|
def create_pgvector_extension(self, sender, **kwargs):
|
|
34
28
|
"""Create pgvector extension and indexes if they don't exist."""
|
|
@@ -5,15 +5,20 @@ Base views for knowledge base API.
|
|
|
5
5
|
import logging
|
|
6
6
|
|
|
7
7
|
from rest_framework import viewsets
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
from django_cfg.mixins import ClientAPIMixin
|
|
9
10
|
|
|
10
11
|
logger = logging.getLogger(__name__)
|
|
11
12
|
|
|
12
13
|
|
|
13
|
-
class BaseKnowledgeViewSet(viewsets.ModelViewSet):
|
|
14
|
-
"""
|
|
14
|
+
class BaseKnowledgeViewSet(ClientAPIMixin, viewsets.ModelViewSet):
|
|
15
|
+
"""
|
|
16
|
+
Base ViewSet with common knowledge base functionality.
|
|
17
|
+
|
|
18
|
+
Requires authenticated user (JWT or Session).
|
|
19
|
+
Automatically filters queryset by user and sets user on creation.
|
|
20
|
+
"""
|
|
15
21
|
|
|
16
|
-
permission_classes = [IsAuthenticated]
|
|
17
22
|
lookup_field = 'pk'
|
|
18
23
|
|
|
19
24
|
def get_queryset(self):
|
|
@@ -5,17 +5,22 @@ REST API ViewSets for tickets and messages.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from drf_spectacular.utils import OpenApiParameter, OpenApiTypes, extend_schema
|
|
8
|
-
from rest_framework import
|
|
8
|
+
from rest_framework import viewsets
|
|
9
9
|
|
|
10
|
+
from django_cfg.mixins import ClientAPIMixin
|
|
10
11
|
from ..models import Message, Ticket
|
|
11
12
|
from ..serializers import MessageCreateSerializer, MessageSerializer, TicketSerializer
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
class TicketViewSet(viewsets.ModelViewSet):
|
|
15
|
-
"""
|
|
15
|
+
class TicketViewSet(ClientAPIMixin, viewsets.ModelViewSet):
|
|
16
|
+
"""
|
|
17
|
+
ViewSet for managing support tickets.
|
|
18
|
+
|
|
19
|
+
Requires authenticated user (JWT or Session).
|
|
20
|
+
Staff users can see all tickets, regular users see only their own.
|
|
21
|
+
"""
|
|
16
22
|
|
|
17
23
|
serializer_class = TicketSerializer
|
|
18
|
-
permission_classes = [permissions.IsAuthenticated]
|
|
19
24
|
lookup_field = 'uuid'
|
|
20
25
|
lookup_url_kwarg = 'uuid'
|
|
21
26
|
|
|
@@ -32,11 +37,15 @@ class TicketViewSet(viewsets.ModelViewSet):
|
|
|
32
37
|
serializer.save(user=self.request.user)
|
|
33
38
|
|
|
34
39
|
|
|
35
|
-
class MessageViewSet(viewsets.ModelViewSet):
|
|
36
|
-
"""
|
|
40
|
+
class MessageViewSet(ClientAPIMixin, viewsets.ModelViewSet):
|
|
41
|
+
"""
|
|
42
|
+
ViewSet for managing support messages.
|
|
43
|
+
|
|
44
|
+
Requires authenticated user (JWT or Session).
|
|
45
|
+
Users can only access messages for their own tickets.
|
|
46
|
+
"""
|
|
37
47
|
|
|
38
48
|
serializer_class = MessageSerializer
|
|
39
|
-
permission_classes = [permissions.IsAuthenticated]
|
|
40
49
|
lookup_field = 'uuid'
|
|
41
50
|
lookup_url_kwarg = 'uuid'
|
|
42
51
|
|
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
ReArq tasks app for Django-CFG.
|
|
3
3
|
|
|
4
|
-
Provides
|
|
4
|
+
Provides async background task processing with Redis queue.
|
|
5
5
|
"""
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"ReArqClient",
|
|
9
|
+
"get_rearq_client",
|
|
10
|
+
"get_tasks_config",
|
|
11
|
+
"get_tasks_config_or_default",
|
|
12
|
+
"task",
|
|
13
|
+
"cron_task",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def __getattr__(name):
|
|
18
|
+
"""Lazy imports to avoid loading ReArq at Django startup."""
|
|
19
|
+
if name in ("ReArqClient", "get_rearq_client"):
|
|
20
|
+
from .services.client import ReArqClient, get_rearq_client
|
|
21
|
+
return ReArqClient if name == "ReArqClient" else get_rearq_client
|
|
22
|
+
elif name in ("get_tasks_config", "get_tasks_config_or_default"):
|
|
23
|
+
from .services.config_helper import get_tasks_config, get_tasks_config_or_default
|
|
24
|
+
return get_tasks_config if name == "get_tasks_config" else get_tasks_config_or_default
|
|
25
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def task(queue: str = "default", **kwargs):
|
|
29
|
+
"""
|
|
30
|
+
Task decorator shortcut.
|
|
31
|
+
|
|
32
|
+
Example:
|
|
33
|
+
>>> from django_cfg.apps.tasks import task
|
|
34
|
+
>>>
|
|
35
|
+
>>> @task(queue="default")
|
|
36
|
+
>>> async def my_task(data: str):
|
|
37
|
+
... return f"Processed {data}"
|
|
38
|
+
>>>
|
|
39
|
+
>>> # Execute task
|
|
40
|
+
>>> job = await my_task.delay(data="test")
|
|
41
|
+
>>> result = await job.result(timeout=30)
|
|
42
|
+
"""
|
|
43
|
+
from .services.client import get_rearq_client
|
|
44
|
+
client = get_rearq_client()
|
|
45
|
+
return client.task(queue=queue, **kwargs)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def cron_task(cron: str, **kwargs):
|
|
49
|
+
"""
|
|
50
|
+
Cron task decorator shortcut.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
cron: Cron expression (e.g., "0 * * * *" for hourly)
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
>>> from django_cfg.apps.tasks import cron_task
|
|
57
|
+
>>>
|
|
58
|
+
>>> @cron_task(cron="0 0 * * *") # Daily at midnight
|
|
59
|
+
>>> async def daily_cleanup():
|
|
60
|
+
... return "Cleanup complete"
|
|
61
|
+
"""
|
|
62
|
+
from .services.client import get_rearq_client
|
|
63
|
+
client = get_rearq_client()
|
|
64
|
+
return client.cron_task(cron=cron, **kwargs)
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""Admin configuration for tasks app."""
|
|
2
|
+
from .config import tasklog_config
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from .tasks_admin import TaskAdmin
|
|
8
|
-
|
|
9
|
-
__all__ = [
|
|
10
|
-
'TaskAdmin',
|
|
11
|
-
]
|
|
4
|
+
__all__ = ["tasklog_config"]
|