django-cfg 1.4.59__py3-none-any.whl → 1.4.60__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/ipc/RPC_LOGGING.md +321 -0
- django_cfg/apps/ipc/TESTING.md +539 -0
- django_cfg/apps/ipc/__init__.py +12 -3
- django_cfg/apps/ipc/admin.py +212 -0
- django_cfg/apps/ipc/migrations/0001_initial.py +137 -0
- django_cfg/apps/ipc/migrations/__init__.py +0 -0
- django_cfg/apps/ipc/models.py +221 -0
- django_cfg/apps/ipc/serializers/__init__.py +10 -0
- django_cfg/apps/ipc/serializers/serializers.py +114 -0
- django_cfg/apps/ipc/services/client/client.py +83 -4
- django_cfg/apps/ipc/services/logging.py +239 -0
- django_cfg/apps/ipc/services/monitor.py +5 -3
- django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/main.mjs +269 -0
- django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/overview.mjs +259 -0
- django_cfg/apps/ipc/static/django_cfg_ipc/js/dashboard/testing.mjs +375 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/methods_content.html +22 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/notifications_content.html +9 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/overview_content.html +9 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/requests_content.html +23 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/stat_cards.html +50 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/system_status.html +47 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/tab_navigation.html +29 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/components/testing_tools.html +184 -0
- django_cfg/apps/ipc/templates/django_cfg_ipc/pages/dashboard.html +56 -0
- django_cfg/apps/ipc/urls.py +4 -2
- django_cfg/apps/ipc/views/__init__.py +7 -2
- django_cfg/apps/ipc/views/dashboard.py +1 -1
- django_cfg/apps/ipc/views/{viewsets.py → monitoring.py} +17 -11
- django_cfg/apps/ipc/views/testing.py +285 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +1 -1
- django_cfg/modules/django_dashboard/sections/widgets.py +209 -0
- django_cfg/modules/django_unfold/callbacks/main.py +43 -18
- django_cfg/modules/django_unfold/dashboard.py +41 -4
- django_cfg/pyproject.toml +1 -1
- django_cfg/static/js/api/index.mjs +8 -3
- django_cfg/static/js/api/ipc/client.mjs +40 -0
- django_cfg/static/js/api/knowbase/client.mjs +309 -0
- django_cfg/static/js/api/knowbase/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +46 -1215
- django_cfg/static/js/api/types.mjs +164 -337
- django_cfg/templates/admin/index.html +8 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +13 -1
- django_cfg/templates/admin/sections/widgets_section.html +129 -0
- django_cfg/templates/admin/snippets/tabs/widgets_tab.html +38 -0
- {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/METADATA +1 -1
- {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/RECORD +52 -28
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +0 -202
- /django_cfg/apps/ipc/static/django_cfg_ipc/js/{dashboard.mjs → dashboard.mjs.old} +0 -0
- /django_cfg/apps/ipc/templates/django_cfg_ipc/{base.html → layout/base.html} +0 -0
- {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.59.dist-info → django_cfg-1.4.60.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""Widgets section for dashboard.
|
|
2
|
+
|
|
3
|
+
Automatically renders widgets from DashboardManager.get_widgets_config()
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from datetime import timedelta
|
|
7
|
+
from typing import Any, Dict, List
|
|
8
|
+
|
|
9
|
+
import psutil
|
|
10
|
+
from django.db.models import Avg
|
|
11
|
+
from django.template import Context, Template
|
|
12
|
+
from django.utils import timezone
|
|
13
|
+
|
|
14
|
+
from .base import DataSection
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class WidgetsSection(DataSection):
|
|
18
|
+
"""
|
|
19
|
+
Widgets section showing automatically generated dashboard widgets.
|
|
20
|
+
|
|
21
|
+
Widgets are defined in DashboardManager.get_widgets_config() and
|
|
22
|
+
can include:
|
|
23
|
+
- System metrics (CPU, Memory, Disk)
|
|
24
|
+
- RPC monitoring stats
|
|
25
|
+
- Custom application widgets
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
template_name = "admin/sections/widgets_section.html"
|
|
29
|
+
title = "Dashboard Widgets"
|
|
30
|
+
icon = "widgets"
|
|
31
|
+
|
|
32
|
+
def get_data(self) -> Dict[str, Any]:
|
|
33
|
+
"""Get widgets configuration from DashboardManager."""
|
|
34
|
+
from django_cfg.modules.django_unfold.dashboard import get_dashboard_manager
|
|
35
|
+
|
|
36
|
+
dashboard_manager = get_dashboard_manager()
|
|
37
|
+
|
|
38
|
+
# Get widgets from dashboard manager (base system widgets)
|
|
39
|
+
widgets = dashboard_manager.get_widgets_config()
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
'widgets': widgets,
|
|
43
|
+
'widgets_count': len(widgets),
|
|
44
|
+
'has_widgets': len(widgets) > 0,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
def merge_custom_widgets(self, widgets: List[Dict], custom_widgets: List[Any]) -> List[Dict]:
|
|
48
|
+
"""
|
|
49
|
+
Merge custom widgets from dashboard_callback.
|
|
50
|
+
|
|
51
|
+
Allows projects to add widgets via dashboard_callback:
|
|
52
|
+
context["custom_widgets"] = [
|
|
53
|
+
StatsCardsWidget(...),
|
|
54
|
+
...
|
|
55
|
+
]
|
|
56
|
+
"""
|
|
57
|
+
if not custom_widgets:
|
|
58
|
+
return widgets
|
|
59
|
+
|
|
60
|
+
# Convert custom widgets to dicts if they are Pydantic models
|
|
61
|
+
for widget in custom_widgets:
|
|
62
|
+
if hasattr(widget, 'to_dict'):
|
|
63
|
+
widgets.append(widget.to_dict())
|
|
64
|
+
elif hasattr(widget, 'model_dump'):
|
|
65
|
+
widgets.append(widget.model_dump())
|
|
66
|
+
elif isinstance(widget, dict):
|
|
67
|
+
widgets.append(widget)
|
|
68
|
+
|
|
69
|
+
return widgets
|
|
70
|
+
|
|
71
|
+
def get_context_data(self, **kwargs) -> Dict[str, Any]:
|
|
72
|
+
"""Add additional context for widget rendering."""
|
|
73
|
+
context = super().get_context_data(**kwargs)
|
|
74
|
+
|
|
75
|
+
# Get base widgets from DashboardManager
|
|
76
|
+
widgets = context['data']['widgets']
|
|
77
|
+
|
|
78
|
+
# Merge custom widgets from dashboard_callback if provided
|
|
79
|
+
custom_widgets_from_callback = kwargs.get('custom_widgets', [])
|
|
80
|
+
if custom_widgets_from_callback:
|
|
81
|
+
widgets = self.merge_custom_widgets(widgets, custom_widgets_from_callback)
|
|
82
|
+
# Update count
|
|
83
|
+
context['data']['widgets_count'] = len(widgets)
|
|
84
|
+
context['data']['has_widgets'] = len(widgets) > 0
|
|
85
|
+
|
|
86
|
+
# Get metrics data first
|
|
87
|
+
metrics_data = {}
|
|
88
|
+
metrics_data.update(self.get_system_metrics())
|
|
89
|
+
|
|
90
|
+
# Add RPC metrics if enabled
|
|
91
|
+
dashboard_manager = self._get_dashboard_manager()
|
|
92
|
+
if dashboard_manager.is_rpc_enabled():
|
|
93
|
+
metrics_data.update(self.get_rpc_metrics())
|
|
94
|
+
|
|
95
|
+
# Also merge any custom metrics from kwargs
|
|
96
|
+
custom_metrics = kwargs.get('custom_metrics', {})
|
|
97
|
+
if custom_metrics:
|
|
98
|
+
metrics_data.update(custom_metrics)
|
|
99
|
+
|
|
100
|
+
# Process widgets and resolve template variables
|
|
101
|
+
processed_stats_widgets = []
|
|
102
|
+
for widget in widgets:
|
|
103
|
+
if widget.get('type') == 'stats_cards':
|
|
104
|
+
processed_widget = self._process_stats_widget(widget, metrics_data)
|
|
105
|
+
processed_stats_widgets.append(processed_widget)
|
|
106
|
+
|
|
107
|
+
chart_widgets = [w for w in widgets if w.get('type') == 'chart']
|
|
108
|
+
custom_widgets = [w for w in widgets if w.get('type') not in ['stats_cards', 'chart']]
|
|
109
|
+
|
|
110
|
+
# Add processed widgets
|
|
111
|
+
context.update({
|
|
112
|
+
'stats_widgets': processed_stats_widgets,
|
|
113
|
+
'chart_widgets': chart_widgets,
|
|
114
|
+
'custom_widgets': custom_widgets,
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
# Also add metrics for direct access
|
|
118
|
+
context.update(metrics_data)
|
|
119
|
+
|
|
120
|
+
return context
|
|
121
|
+
|
|
122
|
+
def _get_dashboard_manager(self):
|
|
123
|
+
"""Get dashboard manager instance (lazy import to avoid circular dependencies)."""
|
|
124
|
+
from django_cfg.modules.django_unfold.dashboard import get_dashboard_manager
|
|
125
|
+
return get_dashboard_manager()
|
|
126
|
+
|
|
127
|
+
def _process_stats_widget(self, widget: Dict[str, Any], context_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
128
|
+
"""Process StatsCardsWidget and resolve template variables in cards."""
|
|
129
|
+
processed_widget = widget.copy()
|
|
130
|
+
processed_cards = []
|
|
131
|
+
|
|
132
|
+
for card in widget.get('cards', []):
|
|
133
|
+
processed_card = card.copy()
|
|
134
|
+
|
|
135
|
+
# Resolve value_template using Django template engine
|
|
136
|
+
value_template = card.get('value_template', '')
|
|
137
|
+
if '{{' in value_template:
|
|
138
|
+
try:
|
|
139
|
+
template = Template(value_template)
|
|
140
|
+
context = Context(context_data)
|
|
141
|
+
resolved_value = template.render(context)
|
|
142
|
+
processed_card['value_template'] = resolved_value
|
|
143
|
+
except Exception:
|
|
144
|
+
# Keep original if rendering fails
|
|
145
|
+
pass
|
|
146
|
+
|
|
147
|
+
# Also resolve change field if it has template variables
|
|
148
|
+
change_template = card.get('change', '')
|
|
149
|
+
if change_template and '{{' in change_template:
|
|
150
|
+
try:
|
|
151
|
+
template = Template(change_template)
|
|
152
|
+
context = Context(context_data)
|
|
153
|
+
resolved_change = template.render(context)
|
|
154
|
+
processed_card['change'] = resolved_change
|
|
155
|
+
except Exception:
|
|
156
|
+
# Keep original if rendering fails
|
|
157
|
+
pass
|
|
158
|
+
|
|
159
|
+
processed_cards.append(processed_card)
|
|
160
|
+
|
|
161
|
+
processed_widget['cards'] = processed_cards
|
|
162
|
+
return processed_widget
|
|
163
|
+
|
|
164
|
+
def get_system_metrics(self) -> Dict[str, Any]:
|
|
165
|
+
"""Get system metrics for widgets."""
|
|
166
|
+
return {
|
|
167
|
+
'cpu_percent': round(psutil.cpu_percent(interval=0.1), 1),
|
|
168
|
+
'memory_percent': round(psutil.virtual_memory().percent, 1),
|
|
169
|
+
'disk_percent': round(psutil.disk_usage('/').percent, 1),
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
def get_rpc_metrics(self) -> Dict[str, Any]:
|
|
173
|
+
"""Get RPC metrics for widgets."""
|
|
174
|
+
try:
|
|
175
|
+
from django_cfg.apps.ipc.models import RPCLog
|
|
176
|
+
|
|
177
|
+
# Get stats for last 24 hours
|
|
178
|
+
since = timezone.now() - timedelta(hours=24)
|
|
179
|
+
|
|
180
|
+
logs = RPCLog.objects.filter(timestamp__gte=since)
|
|
181
|
+
|
|
182
|
+
total_calls = logs.count()
|
|
183
|
+
successful_calls = logs.filter(status='success').count()
|
|
184
|
+
failed_calls = logs.filter(status='error').count()
|
|
185
|
+
|
|
186
|
+
success_rate = round((successful_calls / total_calls * 100) if total_calls > 0 else 0, 1)
|
|
187
|
+
|
|
188
|
+
avg_duration = logs.filter(
|
|
189
|
+
duration__isnull=False
|
|
190
|
+
).aggregate(
|
|
191
|
+
avg=Avg('duration')
|
|
192
|
+
)['avg']
|
|
193
|
+
|
|
194
|
+
avg_duration = round(avg_duration * 1000, 1) if avg_duration else 0 # Convert to ms
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
'rpc_total_calls': total_calls,
|
|
198
|
+
'rpc_success_rate': success_rate,
|
|
199
|
+
'rpc_avg_duration': avg_duration,
|
|
200
|
+
'rpc_failed_calls': failed_calls,
|
|
201
|
+
}
|
|
202
|
+
except Exception as e:
|
|
203
|
+
# Return zeros if RPC models not available
|
|
204
|
+
return {
|
|
205
|
+
'rpc_total_calls': 0,
|
|
206
|
+
'rpc_success_rate': 0,
|
|
207
|
+
'rpc_avg_duration': 0,
|
|
208
|
+
'rpc_failed_calls': 0,
|
|
209
|
+
}
|
|
@@ -19,6 +19,7 @@ from django_cfg.modules.django_dashboard.sections.documentation import Documenta
|
|
|
19
19
|
from django_cfg.modules.django_dashboard.sections.overview import OverviewSection
|
|
20
20
|
from django_cfg.modules.django_dashboard.sections.stats import StatsSection
|
|
21
21
|
from django_cfg.modules.django_dashboard.sections.system import SystemSection
|
|
22
|
+
from django_cfg.modules.django_dashboard.sections.widgets import WidgetsSection
|
|
22
23
|
|
|
23
24
|
from ...base import BaseCfgModule
|
|
24
25
|
from ..models.dashboard import DashboardData
|
|
@@ -155,6 +156,29 @@ class UnfoldCallbacks(
|
|
|
155
156
|
logger.error(f"Failed to render documentation section: {e}", exc_info=True)
|
|
156
157
|
documentation_section = None
|
|
157
158
|
|
|
159
|
+
# Extract custom widgets from context if provided by project's dashboard_callback
|
|
160
|
+
custom_widgets = context.get('custom_widgets', [])
|
|
161
|
+
custom_metrics = {}
|
|
162
|
+
|
|
163
|
+
# Extract all metric-like variables from context for widget template resolution
|
|
164
|
+
# This allows dashboard_callback to add metrics like: context['total_users'] = 123
|
|
165
|
+
for key, value in context.items():
|
|
166
|
+
if key not in ['request', 'cards', 'system_health', 'quick_actions'] and isinstance(value, (int, float, str)):
|
|
167
|
+
custom_metrics[key] = value
|
|
168
|
+
|
|
169
|
+
try:
|
|
170
|
+
# Render widgets section with custom widgets and metrics from callback
|
|
171
|
+
widgets_section = WidgetsSection(request).render(
|
|
172
|
+
custom_widgets=custom_widgets,
|
|
173
|
+
custom_metrics=custom_metrics
|
|
174
|
+
)
|
|
175
|
+
# Debug: save render (only in debug mode)
|
|
176
|
+
if config and config.debug:
|
|
177
|
+
save_section_render('widgets', widgets_section)
|
|
178
|
+
except Exception as e:
|
|
179
|
+
logger.error(f"Failed to render widgets section: {e}", exc_info=True)
|
|
180
|
+
widgets_section = None
|
|
181
|
+
|
|
158
182
|
# Combine all stat cards (data already loaded above)
|
|
159
183
|
all_stats = user_stats + support_stats
|
|
160
184
|
|
|
@@ -176,6 +200,7 @@ class UnfoldCallbacks(
|
|
|
176
200
|
"system_section": system_section,
|
|
177
201
|
"commands_section": commands_section,
|
|
178
202
|
"documentation_section": documentation_section,
|
|
203
|
+
"widgets_section": widgets_section,
|
|
179
204
|
|
|
180
205
|
# Statistics cards
|
|
181
206
|
"cards": cards_data,
|
|
@@ -252,24 +277,24 @@ class UnfoldCallbacks(
|
|
|
252
277
|
})
|
|
253
278
|
|
|
254
279
|
# Log charts data for debugging
|
|
255
|
-
charts_data = context.get('charts', {})
|
|
256
|
-
logger.info(f"Charts data added to context: {list(charts_data.keys())}")
|
|
257
|
-
if 'user_registrations' in charts_data:
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if 'user_activity' in charts_data:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
# Log recent users data for debugging
|
|
265
|
-
recent_users_data = context.get('recent_users', [])
|
|
266
|
-
logger.info(f"Recent users data count: {len(recent_users_data)}")
|
|
267
|
-
if recent_users_data:
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
# Log activity tracker data for debugging
|
|
271
|
-
activity_tracker_data = context.get('activity_tracker', [])
|
|
272
|
-
logger.info(f"Activity tracker data count: {len(activity_tracker_data)}")
|
|
280
|
+
# charts_data = context.get('charts', {})
|
|
281
|
+
# # logger.info(f"Charts data added to context: {list(charts_data.keys())}")
|
|
282
|
+
# if 'user_registrations' in charts_data:
|
|
283
|
+
# reg_data = charts_data['user_registrations']
|
|
284
|
+
# logger.info(f"Registration chart labels: {reg_data.get('labels', [])}")
|
|
285
|
+
# if 'user_activity' in charts_data:
|
|
286
|
+
# act_data = charts_data['user_activity']
|
|
287
|
+
# logger.info(f"Activity chart labels: {act_data.get('labels', [])}")
|
|
288
|
+
|
|
289
|
+
# # Log recent users data for debugging
|
|
290
|
+
# recent_users_data = context.get('recent_users', [])
|
|
291
|
+
# logger.info(f"Recent users data count: {len(recent_users_data)}")
|
|
292
|
+
# if recent_users_data:
|
|
293
|
+
# logger.info(f"First user: {recent_users_data[0].get('username', 'N/A')}")
|
|
294
|
+
|
|
295
|
+
# # Log activity tracker data for debugging
|
|
296
|
+
# activity_tracker_data = context.get('activity_tracker', [])
|
|
297
|
+
# logger.info(f"Activity tracker data count: {len(activity_tracker_data)}")
|
|
273
298
|
|
|
274
299
|
return context
|
|
275
300
|
|
|
@@ -73,9 +73,10 @@ class DashboardManager(BaseCfgModule):
|
|
|
73
73
|
|
|
74
74
|
# RPC Dashboard (if enabled)
|
|
75
75
|
if self.is_rpc_enabled():
|
|
76
|
-
operations_items.
|
|
77
|
-
NavigationItem(title="IPC/RPC Dashboard", icon=Icons.MONITOR_HEART, link="/cfg/ipc/admin/")
|
|
78
|
-
|
|
76
|
+
operations_items.extend([
|
|
77
|
+
NavigationItem(title="IPC/RPC Dashboard", icon=Icons.MONITOR_HEART, link="/cfg/ipc/admin/"),
|
|
78
|
+
NavigationItem(title="RPC Logs", icon=Icons.LIST_ALT, link=str(reverse_lazy("admin:django_cfg_ipc_rpclog_changelist"))),
|
|
79
|
+
])
|
|
79
80
|
|
|
80
81
|
# Background Tasks (if enabled)
|
|
81
82
|
if self.should_enable_tasks():
|
|
@@ -298,6 +299,8 @@ class DashboardManager(BaseCfgModule):
|
|
|
298
299
|
|
|
299
300
|
def get_widgets_config(self) -> List[Dict[str, Any]]:
|
|
300
301
|
"""Get dashboard widgets configuration using Pydantic models."""
|
|
302
|
+
widgets = []
|
|
303
|
+
|
|
301
304
|
# Create system overview widget with StatCard models
|
|
302
305
|
system_overview_widget = StatsCardsWidget(
|
|
303
306
|
title="System Overview",
|
|
@@ -322,9 +325,43 @@ class DashboardManager(BaseCfgModule):
|
|
|
322
325
|
),
|
|
323
326
|
]
|
|
324
327
|
)
|
|
328
|
+
widgets.append(system_overview_widget.to_dict())
|
|
329
|
+
|
|
330
|
+
# Add RPC monitoring widget if IPC is enabled
|
|
331
|
+
if self.is_rpc_enabled():
|
|
332
|
+
rpc_monitoring_widget = StatsCardsWidget(
|
|
333
|
+
title="IPC/RPC Monitoring",
|
|
334
|
+
cards=[
|
|
335
|
+
StatCard(
|
|
336
|
+
title="Total Calls",
|
|
337
|
+
value="{{ rpc_total_calls }}",
|
|
338
|
+
icon=Icons.API,
|
|
339
|
+
color="blue",
|
|
340
|
+
),
|
|
341
|
+
StatCard(
|
|
342
|
+
title="Success Rate",
|
|
343
|
+
value="{{ rpc_success_rate }}%",
|
|
344
|
+
icon=Icons.CHECK_CIRCLE,
|
|
345
|
+
color="green",
|
|
346
|
+
),
|
|
347
|
+
StatCard(
|
|
348
|
+
title="Avg Response Time",
|
|
349
|
+
value="{{ rpc_avg_duration }}ms",
|
|
350
|
+
icon=Icons.SPEED,
|
|
351
|
+
color="purple",
|
|
352
|
+
),
|
|
353
|
+
StatCard(
|
|
354
|
+
title="Failed Calls",
|
|
355
|
+
value="{{ rpc_failed_calls }}",
|
|
356
|
+
icon=Icons.ERROR,
|
|
357
|
+
color="red",
|
|
358
|
+
),
|
|
359
|
+
]
|
|
360
|
+
)
|
|
361
|
+
widgets.append(rpc_monitoring_widget.to_dict())
|
|
325
362
|
|
|
326
363
|
# Convert to dictionaries for Unfold
|
|
327
|
-
return
|
|
364
|
+
return widgets
|
|
328
365
|
|
|
329
366
|
|
|
330
367
|
# Lazy initialization to avoid circular imports
|
django_cfg/pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "django-cfg"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.60"
|
|
8
8
|
description = "Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "ai-agents", "enterprise-django", "django-settings", "type-safe-config",]
|
|
@@ -7,22 +7,23 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* // Import specific app API
|
|
10
|
-
* import { tasksAPI } from '/static/
|
|
10
|
+
* import { tasksAPI } from '/static/api/tasks/index.mjs';
|
|
11
11
|
* const stats = await tasksAPI.cfgTasksApiTasksStatsRetrieve();
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* // Import multiple APIs from main index
|
|
15
|
-
* import { tasksAPI, paymentsAPI } from '/static/
|
|
15
|
+
* import { tasksAPI, paymentsAPI } from '/static/api/index.mjs';
|
|
16
16
|
*
|
|
17
17
|
* @example
|
|
18
18
|
* // Import with custom base URL
|
|
19
|
-
* import { TasksAPI } from '/static/
|
|
19
|
+
* import { TasksAPI } from '/static/api/tasks/index.mjs';
|
|
20
20
|
* const api = new TasksAPI('https://api.example.com');
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { BaseAPIClient } from './base.mjs';
|
|
24
24
|
import { AccountsAPI, accountsAPI } from './accounts/index.mjs';
|
|
25
25
|
import { IpcAPI, ipcAPI } from './ipc/index.mjs';
|
|
26
|
+
import { KnowbaseAPI, knowbaseAPI } from './knowbase/index.mjs';
|
|
26
27
|
import { LeadsAPI, leadsAPI } from './leads/index.mjs';
|
|
27
28
|
import { NewsletterAPI, newsletterAPI } from './newsletter/index.mjs';
|
|
28
29
|
import { PaymentsAPI, paymentsAPI } from './payments/index.mjs';
|
|
@@ -37,6 +38,7 @@ export {
|
|
|
37
38
|
BaseAPIClient,
|
|
38
39
|
AccountsAPI,
|
|
39
40
|
IpcAPI,
|
|
41
|
+
KnowbaseAPI,
|
|
40
42
|
LeadsAPI,
|
|
41
43
|
NewsletterAPI,
|
|
42
44
|
PaymentsAPI,
|
|
@@ -52,6 +54,7 @@ export {
|
|
|
52
54
|
export {
|
|
53
55
|
accountsAPI,
|
|
54
56
|
ipcAPI,
|
|
57
|
+
knowbaseAPI,
|
|
55
58
|
leadsAPI,
|
|
56
59
|
newsletterAPI,
|
|
57
60
|
paymentsAPI,
|
|
@@ -67,6 +70,7 @@ export {
|
|
|
67
70
|
export const apis = {
|
|
68
71
|
accounts: accountsAPI,
|
|
69
72
|
ipc: ipcAPI,
|
|
73
|
+
knowbase: knowbaseAPI,
|
|
70
74
|
leads: leadsAPI,
|
|
71
75
|
newsletter: newsletterAPI,
|
|
72
76
|
payments: paymentsAPI,
|
|
@@ -92,6 +96,7 @@ export function getAPI(appName) {
|
|
|
92
96
|
export const availableApps = [
|
|
93
97
|
'accounts',
|
|
94
98
|
'ipc',
|
|
99
|
+
'knowbase',
|
|
95
100
|
'leads',
|
|
96
101
|
'newsletter',
|
|
97
102
|
'payments',
|
|
@@ -40,6 +40,26 @@ export class IpcAPI extends BaseAPIClient {
|
|
|
40
40
|
*/
|
|
41
41
|
async ipcAdminApiMonitorRequestsRetrieve(params = {}) {
|
|
42
42
|
const path = `/cfg/ipc/admin/api/monitor/requests/`; return this.get(path, params); }
|
|
43
|
+
/**
|
|
44
|
+
* Start load test * Start a load test by sending multiple concurrent RPC requests. * @param {LoadTestRequestRequest} data - Request body * @returns {Promise<LoadTestResponse>} Response data
|
|
45
|
+
*/
|
|
46
|
+
async ipcAdminApiTestLoadStartCreate(data) {
|
|
47
|
+
const path = `/cfg/ipc/admin/api/test/load/start/`; return this.post(path, data); }
|
|
48
|
+
/**
|
|
49
|
+
* Get load test status * Get current status of running or completed load test. * @returns {Promise<LoadTestStatus>} Response data
|
|
50
|
+
*/
|
|
51
|
+
async ipcAdminApiTestLoadStatusRetrieve() {
|
|
52
|
+
const path = `/cfg/ipc/admin/api/test/load/status/`; return this.get(path); }
|
|
53
|
+
/**
|
|
54
|
+
* Stop load test * Stop currently running load test. * @param {TestRPCRequestRequest} data - Request body * @returns {Promise<any>} Response data
|
|
55
|
+
*/
|
|
56
|
+
async ipcAdminApiTestLoadStopCreate(data) {
|
|
57
|
+
const path = `/cfg/ipc/admin/api/test/load/stop/`; return this.post(path, data); }
|
|
58
|
+
/**
|
|
59
|
+
* Send test RPC request * Send a single RPC request for testing purposes and measure response time. * @param {TestRPCRequestRequest} data - Request body * @returns {Promise<TestRPCResponse>} Response data
|
|
60
|
+
*/
|
|
61
|
+
async ipcAdminApiTestSendCreate(data) {
|
|
62
|
+
const path = `/cfg/ipc/admin/api/test/send/`; return this.post(path, data); }
|
|
43
63
|
/**
|
|
44
64
|
* Get RPC health status * Returns the current health status of the RPC monitoring system. * @returns {Promise<HealthCheck>} Response data
|
|
45
65
|
*/
|
|
@@ -65,6 +85,26 @@ export class IpcAPI extends BaseAPIClient {
|
|
|
65
85
|
*/
|
|
66
86
|
async ipcMonitorRequestsRetrieve(params = {}) {
|
|
67
87
|
const path = `/cfg/ipc/monitor/requests/`; return this.get(path, params); }
|
|
88
|
+
/**
|
|
89
|
+
* Start load test * Start a load test by sending multiple concurrent RPC requests. * @param {LoadTestRequestRequest} data - Request body * @returns {Promise<LoadTestResponse>} Response data
|
|
90
|
+
*/
|
|
91
|
+
async ipcTestLoadStartCreate(data) {
|
|
92
|
+
const path = `/cfg/ipc/test/load/start/`; return this.post(path, data); }
|
|
93
|
+
/**
|
|
94
|
+
* Get load test status * Get current status of running or completed load test. * @returns {Promise<LoadTestStatus>} Response data
|
|
95
|
+
*/
|
|
96
|
+
async ipcTestLoadStatusRetrieve() {
|
|
97
|
+
const path = `/cfg/ipc/test/load/status/`; return this.get(path); }
|
|
98
|
+
/**
|
|
99
|
+
* Stop load test * Stop currently running load test. * @param {TestRPCRequestRequest} data - Request body * @returns {Promise<any>} Response data
|
|
100
|
+
*/
|
|
101
|
+
async ipcTestLoadStopCreate(data) {
|
|
102
|
+
const path = `/cfg/ipc/test/load/stop/`; return this.post(path, data); }
|
|
103
|
+
/**
|
|
104
|
+
* Send test RPC request * Send a single RPC request for testing purposes and measure response time. * @param {TestRPCRequestRequest} data - Request body * @returns {Promise<TestRPCResponse>} Response data
|
|
105
|
+
*/
|
|
106
|
+
async ipcTestSendCreate(data) {
|
|
107
|
+
const path = `/cfg/ipc/test/send/`; return this.post(path, data); }
|
|
68
108
|
}
|
|
69
109
|
|
|
70
110
|
// Default instance for convenience
|