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
|
@@ -1,419 +1,66 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
"""
|
|
2
|
+
HtmlBuilder - Facade class for backward compatibility.
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import re
|
|
4
|
+
This class provides the old `self.html.*` API by delegating to new modular components.
|
|
5
|
+
All existing admin code using `self.html.badge()`, `self.html.inline()`, etc. will continue to work.
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
from
|
|
7
|
+
New code should import and use the specific modules directly:
|
|
8
|
+
from django_cfg.modules.django_admin.utils import BaseElements, FormattingElements, etc.
|
|
9
|
+
"""
|
|
11
10
|
|
|
12
|
-
from
|
|
13
|
-
|
|
11
|
+
from .html import (
|
|
12
|
+
BadgeElements,
|
|
13
|
+
BaseElements,
|
|
14
|
+
CodeElements,
|
|
15
|
+
CompositionElements,
|
|
16
|
+
FormattingElements,
|
|
17
|
+
KeyValueElements,
|
|
18
|
+
MarkdownIntegration,
|
|
19
|
+
ProgressElements,
|
|
20
|
+
)
|
|
14
21
|
|
|
15
22
|
|
|
16
23
|
class HtmlBuilder:
|
|
17
24
|
"""
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Usage in admin methods:
|
|
21
|
-
def stats(self, obj):
|
|
22
|
-
return self.html.inline([
|
|
23
|
-
self.html.icon_text(Icons.EDIT, obj.posts_count),
|
|
24
|
-
self.html.icon_text(Icons.CHAT, obj.comments_count),
|
|
25
|
-
])
|
|
25
|
+
Facade class that delegates to modular HTML utilities.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
return self.html.markdown_docs(obj.docs_path)
|
|
27
|
+
Provides backward compatibility for `self.html.*` API in admin classes.
|
|
29
28
|
"""
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
html.icon_text(Icons.EDIT, 5) # Icon with number
|
|
69
|
-
html.icon_text("📝", 5) # Emoji with number
|
|
70
|
-
html.icon_text("Active") # Just text
|
|
71
|
-
"""
|
|
72
|
-
if text is None:
|
|
73
|
-
# Just text
|
|
74
|
-
return format_html('<span>{}</span>', escape(str(icon_or_text)))
|
|
75
|
-
|
|
76
|
-
# Check if it's a Material Icon (from Icons class) or emoji
|
|
77
|
-
icon_str = str(icon_or_text)
|
|
78
|
-
|
|
79
|
-
# Detect if it's emoji by checking for non-ASCII characters
|
|
80
|
-
is_emoji = any(ord(c) > 127 for c in icon_str)
|
|
81
|
-
|
|
82
|
-
if is_emoji or icon_str in ['📝', '💬', '🛒', '👤', '📧', '🔔', '⚙️', '🔧', '📊', '🎯']:
|
|
83
|
-
# Emoji
|
|
84
|
-
icon_html = escape(icon_str)
|
|
85
|
-
else:
|
|
86
|
-
# Material Icon
|
|
87
|
-
icon_html = HtmlBuilder.icon(icon_str, size=icon_size)
|
|
88
|
-
|
|
89
|
-
return format_html('{}{}<span>{}</span>', icon_html, separator, escape(str(text)))
|
|
90
|
-
|
|
91
|
-
@staticmethod
|
|
92
|
-
def inline(items: List[Any], separator: str = " | ",
|
|
93
|
-
size: str = "small", css_class: str = "") -> SafeString:
|
|
94
|
-
"""
|
|
95
|
-
Render items inline with separator.
|
|
96
|
-
|
|
97
|
-
Args:
|
|
98
|
-
items: List of SafeString/str items to join
|
|
99
|
-
separator: Separator between items
|
|
100
|
-
size: small, medium, large
|
|
101
|
-
css_class: Additional CSS classes
|
|
102
|
-
|
|
103
|
-
Usage:
|
|
104
|
-
html.inline([
|
|
105
|
-
html.icon_text(Icons.EDIT, 5),
|
|
106
|
-
html.icon_text(Icons.CHAT, 10),
|
|
107
|
-
])
|
|
108
|
-
"""
|
|
109
|
-
if not items:
|
|
110
|
-
return format_html('<span class="text-font-subtle-light dark:text-font-subtle-dark">—</span>')
|
|
111
|
-
|
|
112
|
-
size_classes = {
|
|
113
|
-
'small': 'text-xs',
|
|
114
|
-
'medium': 'text-sm',
|
|
115
|
-
'large': 'text-base'
|
|
116
|
-
}
|
|
117
|
-
size_class = size_classes.get(size, 'text-xs')
|
|
118
|
-
|
|
119
|
-
classes = size_class
|
|
120
|
-
if css_class:
|
|
121
|
-
classes += f" {css_class}"
|
|
122
|
-
|
|
123
|
-
# Convert items to strings, keeping SafeString as-is
|
|
124
|
-
from django.utils.safestring import SafeString, mark_safe
|
|
125
|
-
processed_items = []
|
|
126
|
-
for item in items:
|
|
127
|
-
if isinstance(item, (SafeString, str)):
|
|
128
|
-
processed_items.append(item)
|
|
129
|
-
else:
|
|
130
|
-
processed_items.append(escape(str(item)))
|
|
131
|
-
|
|
132
|
-
# Join with separator
|
|
133
|
-
joined = mark_safe(separator.join(str(item) for item in processed_items))
|
|
134
|
-
|
|
135
|
-
return format_html('<span class="{}">{}</span>', classes, joined)
|
|
136
|
-
|
|
137
|
-
@staticmethod
|
|
138
|
-
def span(text: Any, css_class: str = "") -> SafeString:
|
|
139
|
-
"""
|
|
140
|
-
Render text in span with optional CSS class.
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
text: Text to display
|
|
144
|
-
css_class: CSS classes
|
|
145
|
-
"""
|
|
146
|
-
if css_class:
|
|
147
|
-
return format_html('<span class="{}">{}</span>', css_class, escape(str(text)))
|
|
148
|
-
return format_html('<span>{}</span>', escape(str(text)))
|
|
149
|
-
|
|
150
|
-
@staticmethod
|
|
151
|
-
def div(content: Any, css_class: str = "") -> SafeString:
|
|
152
|
-
"""
|
|
153
|
-
Render content in div with optional CSS class.
|
|
154
|
-
|
|
155
|
-
Args:
|
|
156
|
-
content: Content to display (can be SafeString)
|
|
157
|
-
css_class: CSS classes
|
|
158
|
-
"""
|
|
159
|
-
if css_class:
|
|
160
|
-
return format_html('<div class="{}">{}</div>', css_class, content)
|
|
161
|
-
return format_html('<div>{}</div>', content)
|
|
162
|
-
|
|
163
|
-
@staticmethod
|
|
164
|
-
def link(url: str, text: str, css_class: str = "", target: str = "") -> SafeString:
|
|
165
|
-
"""
|
|
166
|
-
Render link.
|
|
167
|
-
|
|
168
|
-
Args:
|
|
169
|
-
url: URL
|
|
170
|
-
text: Link text
|
|
171
|
-
css_class: CSS classes
|
|
172
|
-
target: Target attribute (_blank, _self, etc)
|
|
173
|
-
"""
|
|
174
|
-
if target:
|
|
175
|
-
return format_html(
|
|
176
|
-
'<a href="{}" class="{}" target="{}">{}</a>',
|
|
177
|
-
url, css_class, target, escape(text)
|
|
178
|
-
)
|
|
179
|
-
return format_html('<a href="{}" class="{}">{}</a>', url, css_class, escape(text))
|
|
180
|
-
|
|
181
|
-
@staticmethod
|
|
182
|
-
def badge(text: Any, variant: str = "primary", icon: Optional[str] = None) -> SafeString:
|
|
183
|
-
"""
|
|
184
|
-
Render badge with optional icon.
|
|
185
|
-
|
|
186
|
-
Args:
|
|
187
|
-
text: Badge text
|
|
188
|
-
variant: primary, success, warning, danger, info, secondary
|
|
189
|
-
icon: Optional Material Icon
|
|
190
|
-
|
|
191
|
-
Usage:
|
|
192
|
-
html.badge("Active", variant="success", icon=Icons.CHECK_CIRCLE)
|
|
193
|
-
"""
|
|
194
|
-
variant_classes = {
|
|
195
|
-
'success': 'bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-200',
|
|
196
|
-
'warning': 'bg-warning-100 text-warning-800 dark:bg-warning-900 dark:text-warning-200',
|
|
197
|
-
'danger': 'bg-danger-100 text-danger-800 dark:bg-danger-900 dark:text-danger-200',
|
|
198
|
-
'info': 'bg-info-100 text-info-800 dark:bg-info-900 dark:text-info-200',
|
|
199
|
-
'primary': 'bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-200',
|
|
200
|
-
'secondary': 'bg-base-100 text-font-default-light dark:bg-base-800 dark:text-font-default-dark',
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
css_classes = variant_classes.get(variant, variant_classes['primary'])
|
|
204
|
-
|
|
205
|
-
icon_html = ""
|
|
206
|
-
if icon:
|
|
207
|
-
icon_html = format_html('<span class="material-symbols-outlined text-xs mr-1">{}</span>', icon)
|
|
208
|
-
|
|
209
|
-
return format_html(
|
|
210
|
-
'<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium {}">{}{}</span>',
|
|
211
|
-
css_classes, icon_html, escape(str(text))
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
@staticmethod
|
|
215
|
-
def empty(text: str = "—") -> SafeString:
|
|
216
|
-
"""Render empty/placeholder value."""
|
|
217
|
-
return format_html(
|
|
218
|
-
'<span class="text-font-subtle-light dark:text-font-subtle-dark">{}</span>',
|
|
219
|
-
escape(text)
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
@staticmethod
|
|
223
|
-
def code(text: Any, css_class: str = "") -> SafeString:
|
|
224
|
-
"""
|
|
225
|
-
Render inline code.
|
|
226
|
-
|
|
227
|
-
Args:
|
|
228
|
-
text: Code text
|
|
229
|
-
css_class: Additional CSS classes
|
|
230
|
-
|
|
231
|
-
Usage:
|
|
232
|
-
html.code("/path/to/file")
|
|
233
|
-
html.code("command --arg value")
|
|
234
|
-
"""
|
|
235
|
-
base_classes = "font-mono text-xs bg-base-100 dark:bg-base-800 px-1.5 py-0.5 rounded"
|
|
236
|
-
classes = f"{base_classes} {css_class}".strip()
|
|
237
|
-
|
|
238
|
-
return format_html(
|
|
239
|
-
'<code class="{}">{}</code>',
|
|
240
|
-
classes,
|
|
241
|
-
escape(str(text))
|
|
242
|
-
)
|
|
243
|
-
|
|
244
|
-
@staticmethod
|
|
245
|
-
def code_block(
|
|
246
|
-
text: Any,
|
|
247
|
-
language: Optional[str] = None,
|
|
248
|
-
max_height: Optional[str] = None,
|
|
249
|
-
variant: str = "default"
|
|
250
|
-
) -> SafeString:
|
|
251
|
-
"""
|
|
252
|
-
Render code block with optional syntax highlighting and scrolling.
|
|
253
|
-
|
|
254
|
-
Args:
|
|
255
|
-
text: Code content
|
|
256
|
-
language: Programming language (json, python, bash, etc.) - for future syntax highlighting
|
|
257
|
-
max_height: Max height with scrolling (e.g., "400px", "20rem")
|
|
258
|
-
variant: Color variant - default, warning, danger, success, info
|
|
259
|
-
|
|
260
|
-
Usage:
|
|
261
|
-
html.code_block(json.dumps(data, indent=2), language="json")
|
|
262
|
-
html.code_block(stdout, max_height="400px")
|
|
263
|
-
html.code_block(stderr, max_height="400px", variant="warning")
|
|
264
|
-
"""
|
|
265
|
-
# Variant-specific styles
|
|
266
|
-
variant_classes = {
|
|
267
|
-
'default': 'bg-base-50 dark:bg-base-900 border-base-200 dark:border-base-700',
|
|
268
|
-
'warning': 'bg-warning-50 dark:bg-warning-900/20 border-warning-200 dark:border-warning-700',
|
|
269
|
-
'danger': 'bg-danger-50 dark:bg-danger-900/20 border-danger-200 dark:border-danger-700',
|
|
270
|
-
'success': 'bg-success-50 dark:bg-success-900/20 border-success-200 dark:border-success-700',
|
|
271
|
-
'info': 'bg-info-50 dark:bg-info-900/20 border-info-200 dark:border-info-700',
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
variant_class = variant_classes.get(variant, variant_classes['default'])
|
|
275
|
-
|
|
276
|
-
# Base styles
|
|
277
|
-
base_classes = f"font-mono text-xs whitespace-pre-wrap break-words border rounded-md p-3 {variant_class}"
|
|
278
|
-
|
|
279
|
-
# Add max-height and overflow if specified
|
|
280
|
-
style = ""
|
|
281
|
-
if max_height:
|
|
282
|
-
style = f'style="max-height: {max_height}; overflow-y: auto;"'
|
|
283
|
-
|
|
284
|
-
# Add language class for potential syntax highlighting
|
|
285
|
-
lang_class = f"language-{language}" if language else ""
|
|
286
|
-
|
|
287
|
-
return format_html(
|
|
288
|
-
'<pre class="{} {}" {}><code>{}</code></pre>',
|
|
289
|
-
base_classes,
|
|
290
|
-
lang_class,
|
|
291
|
-
style,
|
|
292
|
-
escape(str(text))
|
|
293
|
-
)
|
|
294
|
-
|
|
295
|
-
@staticmethod
|
|
296
|
-
def markdown(
|
|
297
|
-
text: str,
|
|
298
|
-
css_class: str = "",
|
|
299
|
-
max_height: Optional[str] = None,
|
|
300
|
-
enable_plugins: bool = True
|
|
301
|
-
) -> SafeString:
|
|
302
|
-
"""
|
|
303
|
-
Render markdown text to beautifully styled HTML.
|
|
304
|
-
|
|
305
|
-
Delegates to MarkdownRenderer.render_markdown() for actual rendering.
|
|
306
|
-
|
|
307
|
-
Args:
|
|
308
|
-
text: Markdown content
|
|
309
|
-
css_class: Additional CSS classes
|
|
310
|
-
max_height: Max height with scrolling (e.g., "400px", "20rem")
|
|
311
|
-
enable_plugins: Enable mistune plugins (tables, strikethrough, etc.)
|
|
312
|
-
|
|
313
|
-
Usage:
|
|
314
|
-
# Simple markdown rendering
|
|
315
|
-
html.markdown("# Hello\\n\\nThis is **bold** text")
|
|
316
|
-
|
|
317
|
-
# With custom styling
|
|
318
|
-
html.markdown(obj.description, css_class="my-custom-class")
|
|
319
|
-
|
|
320
|
-
# With max height for long content
|
|
321
|
-
html.markdown(obj.documentation, max_height="500px")
|
|
322
|
-
|
|
323
|
-
Returns:
|
|
324
|
-
SafeString with rendered HTML
|
|
325
|
-
"""
|
|
326
|
-
return MarkdownRenderer.render_markdown(
|
|
327
|
-
text=text,
|
|
328
|
-
css_class=css_class,
|
|
329
|
-
max_height=max_height,
|
|
330
|
-
enable_plugins=enable_plugins
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
@staticmethod
|
|
334
|
-
def uuid_short(uuid_value: Any, length: int = 6, show_tooltip: bool = True) -> SafeString:
|
|
335
|
-
"""
|
|
336
|
-
Shorten UUID to first N characters with optional tooltip.
|
|
337
|
-
|
|
338
|
-
Args:
|
|
339
|
-
uuid_value: UUID string or UUID object
|
|
340
|
-
length: Number of characters to show (default: 6)
|
|
341
|
-
show_tooltip: Show full UUID on hover (default: True)
|
|
342
|
-
|
|
343
|
-
Usage:
|
|
344
|
-
html.uuid_short(obj.id) # "a1b2c3..."
|
|
345
|
-
html.uuid_short(obj.id, length=8) # "a1b2c3d4..."
|
|
346
|
-
html.uuid_short(obj.id, show_tooltip=False) # Just short version
|
|
347
|
-
|
|
348
|
-
Returns:
|
|
349
|
-
SafeString with shortened UUID
|
|
350
|
-
"""
|
|
351
|
-
uuid_str = str(uuid_value)
|
|
352
|
-
|
|
353
|
-
# Remove dashes for cleaner display
|
|
354
|
-
uuid_clean = uuid_str.replace('-', '')
|
|
355
|
-
|
|
356
|
-
# Take first N characters
|
|
357
|
-
short_uuid = uuid_clean[:length]
|
|
358
|
-
|
|
359
|
-
if show_tooltip:
|
|
360
|
-
return format_html(
|
|
361
|
-
'<code class="font-mono text-xs bg-base-100 dark:bg-base-800 px-1.5 py-0.5 rounded cursor-help" title="{}">{}</code>',
|
|
362
|
-
uuid_str,
|
|
363
|
-
short_uuid
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
return format_html(
|
|
367
|
-
'<code class="font-mono text-xs bg-base-100 dark:bg-base-800 px-1.5 py-0.5 rounded">{}</code>',
|
|
368
|
-
short_uuid
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
@staticmethod
|
|
372
|
-
def markdown_docs(
|
|
373
|
-
content: Union[str, Path],
|
|
374
|
-
collapsible: bool = True,
|
|
375
|
-
title: str = "Documentation",
|
|
376
|
-
icon: str = "description",
|
|
377
|
-
max_height: Optional[str] = "500px",
|
|
378
|
-
enable_plugins: bool = True,
|
|
379
|
-
default_open: bool = False
|
|
380
|
-
) -> SafeString:
|
|
381
|
-
"""
|
|
382
|
-
Render markdown documentation from string or file with collapsible UI.
|
|
383
|
-
|
|
384
|
-
Auto-detects whether content is a file path or markdown string.
|
|
385
|
-
|
|
386
|
-
Args:
|
|
387
|
-
content: Markdown string or path to .md file
|
|
388
|
-
collapsible: Wrap in collapsible details/summary
|
|
389
|
-
title: Title for collapsible section
|
|
390
|
-
icon: Material icon name for title
|
|
391
|
-
max_height: Max height for scrolling
|
|
392
|
-
enable_plugins: Enable markdown plugins
|
|
393
|
-
default_open: Open by default if collapsible
|
|
394
|
-
|
|
395
|
-
Usage:
|
|
396
|
-
# From string with collapse
|
|
397
|
-
html.markdown_docs(obj.description, title="Description")
|
|
398
|
-
|
|
399
|
-
# From file
|
|
400
|
-
html.markdown_docs("docs/api.md", title="API Documentation")
|
|
401
|
-
|
|
402
|
-
# Simple, no collapse
|
|
403
|
-
html.markdown_docs(obj.notes, collapsible=False)
|
|
404
|
-
|
|
405
|
-
# Open by default
|
|
406
|
-
html.markdown_docs(obj.readme, default_open=True)
|
|
407
|
-
|
|
408
|
-
Returns:
|
|
409
|
-
Rendered markdown with beautiful Tailwind styling
|
|
410
|
-
"""
|
|
411
|
-
return MarkdownRenderer.render(
|
|
412
|
-
content=content,
|
|
413
|
-
collapsible=collapsible,
|
|
414
|
-
title=title,
|
|
415
|
-
icon=icon,
|
|
416
|
-
max_height=max_height,
|
|
417
|
-
enable_plugins=enable_plugins,
|
|
418
|
-
default_open=default_open
|
|
419
|
-
)
|
|
30
|
+
# === BaseElements ===
|
|
31
|
+
icon = staticmethod(BaseElements.icon)
|
|
32
|
+
span = staticmethod(BaseElements.span)
|
|
33
|
+
text = staticmethod(BaseElements.text)
|
|
34
|
+
div = staticmethod(BaseElements.div)
|
|
35
|
+
link = staticmethod(BaseElements.link)
|
|
36
|
+
empty = staticmethod(BaseElements.empty)
|
|
37
|
+
|
|
38
|
+
# === CodeElements ===
|
|
39
|
+
code = staticmethod(CodeElements.code)
|
|
40
|
+
code_block = staticmethod(CodeElements.code_block)
|
|
41
|
+
|
|
42
|
+
# === BadgeElements ===
|
|
43
|
+
badge = staticmethod(BadgeElements.badge)
|
|
44
|
+
|
|
45
|
+
# === CompositionElements ===
|
|
46
|
+
inline = staticmethod(CompositionElements.inline)
|
|
47
|
+
icon_text = staticmethod(CompositionElements.icon_text)
|
|
48
|
+
header = staticmethod(CompositionElements.header)
|
|
49
|
+
|
|
50
|
+
# === FormattingElements ===
|
|
51
|
+
number = staticmethod(FormattingElements.number)
|
|
52
|
+
uuid_short = staticmethod(FormattingElements.uuid_short)
|
|
53
|
+
|
|
54
|
+
# === KeyValueElements ===
|
|
55
|
+
key_value = staticmethod(KeyValueElements.key_value)
|
|
56
|
+
breakdown = staticmethod(KeyValueElements.breakdown)
|
|
57
|
+
divider = staticmethod(KeyValueElements.divider)
|
|
58
|
+
key_value_list = staticmethod(KeyValueElements.key_value_list)
|
|
59
|
+
|
|
60
|
+
# === ProgressElements ===
|
|
61
|
+
segment = staticmethod(ProgressElements.segment)
|
|
62
|
+
progress_bar = staticmethod(ProgressElements.progress_bar)
|
|
63
|
+
|
|
64
|
+
# === MarkdownIntegration ===
|
|
65
|
+
markdown = staticmethod(MarkdownIntegration.markdown)
|
|
66
|
+
markdown_docs = staticmethod(MarkdownIntegration.markdown_docs)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Markdown rendering utilities for Django Admin.
|
|
3
|
+
|
|
4
|
+
Provides MarkdownRenderer and mermaid plugin support.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .mermaid_plugin import (
|
|
8
|
+
get_mermaid_resources,
|
|
9
|
+
get_mermaid_script,
|
|
10
|
+
get_mermaid_styles,
|
|
11
|
+
mermaid_plugin,
|
|
12
|
+
)
|
|
13
|
+
from .renderer import MarkdownRenderer
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"MarkdownRenderer",
|
|
17
|
+
"mermaid_plugin",
|
|
18
|
+
"get_mermaid_styles",
|
|
19
|
+
"get_mermaid_script",
|
|
20
|
+
"get_mermaid_resources",
|
|
21
|
+
]
|
|
@@ -140,36 +140,39 @@ class NavigationManager(BaseCfgModule):
|
|
|
140
140
|
separator=True,
|
|
141
141
|
collapsible=True,
|
|
142
142
|
items=[
|
|
143
|
-
NavigationItem(title="Dashboard", icon=Icons.MONITOR_HEART, link="/cfg/admin/admin/centrifugo"),
|
|
143
|
+
NavigationItem(title="Dashboard", icon=Icons.MONITOR_HEART, link="/cfg/admin/admin/dashboard/centrifugo"),
|
|
144
144
|
NavigationItem(title="Logs", icon=Icons.LIST_ALT, link=str(reverse_lazy("admin:django_cfg_centrifugo_centrifugolog_changelist"))),
|
|
145
145
|
]
|
|
146
146
|
)
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
-
#
|
|
150
|
-
if self.
|
|
151
|
-
|
|
149
|
+
# gRPC Dashboard (if enabled)
|
|
150
|
+
if self.is_grpc_enabled():
|
|
151
|
+
grpc_items = []
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
# Monitoring API endpoint
|
|
154
|
+
grpc_items.append(
|
|
155
|
+
NavigationItem(title="Monitor", icon=Icons.MONITOR_HEART, link="/cfg/grpc/monitor/overview/")
|
|
155
156
|
)
|
|
156
157
|
|
|
157
|
-
#
|
|
158
|
+
# Request Logs with safe URL resolution
|
|
158
159
|
logs_item = self._create_nav_item(
|
|
159
|
-
title="Logs",
|
|
160
|
-
icon=Icons.
|
|
161
|
-
url_name="admin:
|
|
162
|
-
fallback_link="/admin/
|
|
160
|
+
title="Request Logs",
|
|
161
|
+
icon=Icons.LIST_ALT,
|
|
162
|
+
url_name="admin:grpc_grpcrequestlog_changelist",
|
|
163
|
+
fallback_link="/admin/grpc/grpcrequestlog/"
|
|
163
164
|
)
|
|
164
165
|
if logs_item:
|
|
165
|
-
|
|
166
|
+
grpc_items.append(logs_item)
|
|
166
167
|
|
|
167
|
-
navigation_sections.append(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
navigation_sections.append(
|
|
169
|
+
NavigationSection(
|
|
170
|
+
title="gRPC",
|
|
171
|
+
separator=True,
|
|
172
|
+
collapsible=True,
|
|
173
|
+
items=grpc_items
|
|
174
|
+
)
|
|
175
|
+
)
|
|
173
176
|
|
|
174
177
|
# System Operations section
|
|
175
178
|
system_items = []
|
django_cfg/pyproject.toml
CHANGED
|
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "django-cfg"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.5.2"
|
|
8
8
|
description = "Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "nextjs-admin", "react-admin", "websocket", "centrifugo", "real-time", "typescript-generation", "ai-agents", "enterprise-django", "django-settings", "type-safe-config", "modern-django",]
|
|
11
11
|
classifiers = [ "Development Status :: 4 - Beta", "Framework :: Django", "Framework :: Django :: 5.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Systems Administration", "Typing :: Typed",]
|
|
12
12
|
requires-python = ">=3.12,<3.14"
|
|
13
|
-
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "django-
|
|
13
|
+
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "django-rq>=3.1.0,<4.0", "rq-scheduler>=0.14.0,<1.0", "djangorestframework>=3.16.0,<4.0", "djangorestframework-simplejwt>=5.5.0,<6.0", "djangorestframework-simplejwt[token-blacklist]>=5.5.0,<6.0", "drf-nested-routers>=0.94.0,<1.0", "django-filter>=25.0,<26.0", "django-ratelimit>=4.1.0,<5.0.0", "drf-spectacular>=0.28.0,<1.0", "drf-spectacular-sidecar>=2025.8.0,<2026.0", "django-json-widget>=2.0.0,<3.0", "django-import-export>=4.3.0,<5.0", "django-extensions>=4.1.0,<5.0", "django-constance>=4.3.0,<5.0", "django-unfold>=0.64.0,<1.0", "django-redis>=6.0.0,<7.0", "redis>=6.4.0,<7.0", "hiredis>=2.0.0,<4.0", "setuptools>=75.0.0; python_version>='3.13'", "pyTelegramBotAPI>=4.28.0,<5.0", "coolname>=2.2.0,<3.0", "django-admin-rangefilter>=0.13.0,<1.0", "python-json-logger>=3.3.0,<4.0", "requests>=2.32.0,<3.0", "tiktoken>=0.11.0,<1.0", "openai>=1.107.0,<2.0", "twilio>=9.8.0,<10.0", "sendgrid>=6.12.0,<7.0", "beautifulsoup4>=4.13.0,<5.0", "lxml>=6.0.0,<7.0", "pgvector>=0.4.0,<1.0", "tenacity>=9.1.2,<10.0.0", "mypy (>=1.18.2,<2.0.0)", "django-tailwind[reload] (>=4.2.0,<5.0.0)", "jinja2 (>=3.1.6,<4.0.0)", "django-axes[ipware] (>=8.0.0,<9.0.0)", "pydantic-settings (>=2.11.0,<3.0.0)", "httpx>=0.28.1,<1.0", "mistune>=3.1.4,<4.0",]
|
|
14
14
|
[[project.authors]]
|
|
15
15
|
name = "Django-CFG Team"
|
|
16
16
|
email = "info@djangocfg.com"
|
|
@@ -26,11 +26,12 @@ text = "MIT"
|
|
|
26
26
|
local = []
|
|
27
27
|
django52 = [ "django>=5.2,<6.0",]
|
|
28
28
|
ai = [ "pydantic-ai>=1.0.10,<2.0",]
|
|
29
|
+
grpc = [ "grpcio>=1.50.0,<2.0", "grpcio-tools>=1.50.0,<2.0", "protobuf>=5.0,<7.0", "djangogrpcframework>=0.2.1",]
|
|
29
30
|
dev = [ "django>=5.2,<6.0", "pytest>=8.4,<9.0", "pytest-django>=4.11,<5.0", "pytest-cov>=7.0,<8.0", "pytest-mock>=3.15,<4.0", "factory-boy>=3.3,<4.0", "fakeredis>=2.28,<3.0", "black>=25.9,<26.0", "isort>=6.0,<7.0", "flake8>=6.0.0,<8.0", "mypy>=1.18,<2.0", "pre-commit>=4.3,<5.0", "build>=1.3,<2.0", "twine>=6.2,<7.0", "tomlkit>=0.13.3,<1.0", "questionary>=2.1.0,<3.0", "rich>=13.0.0,<15.0", "mkdocs>=1.6,<2.0", "mkdocs-material>=9.6,<10.0", "mkdocstrings[python]>=0.30,<1.0", "redis>=6.4.0,<7.0",]
|
|
30
31
|
test = [ "django>=5.2,<6.0", "pytest>=8.4,<9.0", "pytest-django>=4.11,<5.0", "pytest-cov>=7.0,<8.0", "pytest-mock>=3.15,<4.0", "pytest-xdist>=3.8,<4.0", "factory-boy>=3.3,<4.0", "fakeredis>=2.28,<3.0",]
|
|
31
32
|
docs = [ "mkdocs>=1.6,<2.0", "mkdocs-material>=9.6,<10.0", "mkdocstrings[python]>=0.30,<1.0", "pymdown-extensions>=10.16,<11.0",]
|
|
32
33
|
tasks = [ "redis>=6.4.0,<7.0",]
|
|
33
|
-
full = [ "django>=5.2,<6.0", "pytest>=8.4,<9.0", "pytest-django>=4.11,<5.0", "pytest-cov>=7.0,<8.0", "pytest-mock>=3.15,<4.0", "pytest-xdist>=3.8,<4.0", "factory-boy>=3.3,<4.0", "black>=25.9,<26.0", "isort>=6.0,<7.0", "flake8>=6.0.0,<8.0", "mypy>=1.18,<2.0", "pre-commit>=4.3,<5.0", "build>=1.3,<2.0", "twine>=6.2,<7.0", "tomlkit>=0.13.3,<1.0", "questionary>=2.1.0,<3.0", "rich>=13.0.0,<15.0", "mkdocs>=1.6,<2.0", "mkdocs-material>=9.6,<10.0", "mkdocstrings[python]>=0.30,<1.0", "pymdown-extensions>=10.16,<11.0", "redis>=6.4.0,<7.0",]
|
|
34
|
+
full = [ "django>=5.2,<6.0", "pytest>=8.4,<9.0", "pytest-django>=4.11,<5.0", "pytest-cov>=7.0,<8.0", "pytest-mock>=3.15,<4.0", "pytest-xdist>=3.8,<4.0", "factory-boy>=3.3,<4.0", "black>=25.9,<26.0", "isort>=6.0,<7.0", "flake8>=6.0.0,<8.0", "mypy>=1.18,<2.0", "pre-commit>=4.3,<5.0", "build>=1.3,<2.0", "twine>=6.2,<7.0", "tomlkit>=0.13.3,<1.0", "questionary>=2.1.0,<3.0", "rich>=13.0.0,<15.0", "mkdocs>=1.6,<2.0", "mkdocs-material>=9.6,<10.0", "mkdocstrings[python]>=0.30,<1.0", "pymdown-extensions>=10.16,<11.0", "redis>=6.4.0,<7.0", "grpcio>=1.50.0,<2.0", "grpcio-tools>=1.50.0,<2.0", "protobuf>=5.0,<7.0", "djangogrpcframework>=0.2.1",]
|
|
34
35
|
|
|
35
36
|
[project.urls]
|
|
36
37
|
Homepage = "https://djangocfg.com"
|
|
@@ -114,9 +115,6 @@ exclude_lines = [ "pragma: no cover", "def __repr__", "if self.debug:", "if sett
|
|
|
114
115
|
[tool.coverage.html]
|
|
115
116
|
directory = "htmlcov"
|
|
116
117
|
|
|
117
|
-
[tool.poetry.group.local]
|
|
118
|
-
optional = true
|
|
119
|
-
|
|
120
118
|
[tool.poetry.group.dev.dependencies]
|
|
121
119
|
tomlkit = "^0.13.3"
|
|
122
120
|
build = "^1.3.0"
|
django_cfg/registry/core.py
CHANGED
|
@@ -38,10 +38,6 @@ CORE_REGISTRY = {
|
|
|
38
38
|
# Security - Django Crypto Fields
|
|
39
39
|
"CryptoFieldsConfig": ("django_cfg.models.django.crypto_fields", "CryptoFieldsConfig"),
|
|
40
40
|
|
|
41
|
-
# Scheduling - Django-Q2
|
|
42
|
-
"DjangoQ2Config": ("django_cfg.models.django.django_q2", "DjangoQ2Config"),
|
|
43
|
-
"DjangoQ2ScheduleConfig": ("django_cfg.models.django.django_q2", "DjangoQ2ScheduleConfig"),
|
|
44
|
-
|
|
45
41
|
# Limits models
|
|
46
42
|
"LimitsConfig": ("django_cfg.models.api.limits", "LimitsConfig"),
|
|
47
43
|
|
|
@@ -51,9 +47,10 @@ CORE_REGISTRY = {
|
|
|
51
47
|
# JWT models
|
|
52
48
|
"JWTConfig": ("django_cfg.models.api.jwt", "JWTConfig"),
|
|
53
49
|
|
|
54
|
-
#
|
|
55
|
-
"
|
|
56
|
-
"
|
|
50
|
+
# Django-RQ models
|
|
51
|
+
"DjangoRQConfig": ("django_cfg.models.django.django_rq", "DjangoRQConfig"),
|
|
52
|
+
"RQQueueConfig": ("django_cfg.models.django.django_rq", "RQQueueConfig"),
|
|
53
|
+
"RQScheduleConfig": ("django_cfg.models.django.django_rq", "RQScheduleConfig"),
|
|
57
54
|
|
|
58
55
|
# Payment system models (BaseCfgAutoModule)
|
|
59
56
|
"PaymentsConfig": ("django_cfg.models.payments.config", "PaymentsConfig"),
|
django_cfg/registry/modules.py
CHANGED
|
@@ -13,6 +13,12 @@ MODULES_REGISTRY = {
|
|
|
13
13
|
# Centrifugo module
|
|
14
14
|
"DjangoCfgCentrifugoConfig": ("django_cfg.apps.centrifugo.services.client.config", "DjangoCfgCentrifugoConfig"),
|
|
15
15
|
|
|
16
|
+
# gRPC module
|
|
17
|
+
"GRPCConfig": ("django_cfg.models.api.grpc", "GRPCConfig"),
|
|
18
|
+
"GRPCServerConfig": ("django_cfg.models.api.grpc", "GRPCServerConfig"),
|
|
19
|
+
"GRPCAuthConfig": ("django_cfg.models.api.grpc", "GRPCAuthConfig"),
|
|
20
|
+
"GRPCProtoConfig": ("django_cfg.models.api.grpc", "GRPCProtoConfig"),
|
|
21
|
+
|
|
16
22
|
# Next.js Admin Integration
|
|
17
23
|
"NextJsAdminConfig": ("django_cfg.modules.nextjs_admin", "NextJsAdminConfig"),
|
|
18
24
|
|
|
Binary file
|