django-cfg 1.4.10__py3-none-any.whl → 1.4.13__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.
- django_cfg/apps/agents/management/commands/create_agent.py +1 -1
- django_cfg/apps/agents/management/commands/orchestrator_status.py +3 -3
- django_cfg/apps/newsletter/serializers.py +40 -3
- django_cfg/apps/newsletter/views/campaigns.py +12 -3
- django_cfg/apps/newsletter/views/emails.py +14 -3
- django_cfg/apps/newsletter/views/subscriptions.py +12 -2
- django_cfg/apps/payments/views/api/currencies.py +49 -6
- django_cfg/apps/payments/views/api/webhooks.py +72 -7
- django_cfg/apps/payments/views/overview/serializers.py +34 -1
- django_cfg/apps/payments/views/overview/views.py +2 -1
- django_cfg/apps/payments/views/serializers/payments.py +6 -6
- django_cfg/apps/urls.py +106 -45
- django_cfg/core/base/config_model.py +2 -2
- django_cfg/core/constants.py +1 -1
- django_cfg/core/generation/integration_generators/__init__.py +1 -1
- django_cfg/core/generation/integration_generators/api.py +73 -49
- django_cfg/core/integration/display/startup.py +30 -22
- django_cfg/core/integration/url_integration.py +15 -16
- django_cfg/management/commands/check_endpoints.py +11 -160
- django_cfg/management/commands/check_settings.py +13 -348
- django_cfg/management/commands/clear_constance.py +13 -201
- django_cfg/management/commands/create_token.py +13 -321
- django_cfg/management/commands/generate_clients.py +23 -0
- django_cfg/management/commands/list_urls.py +13 -306
- django_cfg/management/commands/migrate_all.py +13 -126
- django_cfg/management/commands/migrator.py +13 -396
- django_cfg/management/commands/rundramatiq.py +15 -247
- django_cfg/management/commands/rundramatiq_simulator.py +12 -429
- django_cfg/management/commands/runserver_ngrok.py +15 -160
- django_cfg/management/commands/script.py +12 -488
- django_cfg/management/commands/show_config.py +12 -215
- django_cfg/management/commands/show_urls.py +12 -342
- django_cfg/management/commands/superuser.py +15 -295
- django_cfg/management/commands/task_clear.py +14 -217
- django_cfg/management/commands/task_status.py +13 -248
- django_cfg/management/commands/test_email.py +15 -86
- django_cfg/management/commands/test_telegram.py +14 -61
- django_cfg/management/commands/test_twilio.py +15 -105
- django_cfg/management/commands/tree.py +13 -383
- django_cfg/management/commands/validate_openapi.py +10 -0
- django_cfg/middleware/README.md +1 -1
- django_cfg/middleware/user_activity.py +3 -3
- django_cfg/models/__init__.py +2 -2
- django_cfg/models/api/drf/spectacular.py +6 -6
- django_cfg/models/django/__init__.py +2 -2
- django_cfg/models/django/openapi.py +162 -0
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +169 -0
- django_cfg/modules/django_admin/management/commands/check_settings.py +355 -0
- django_cfg/modules/django_admin/management/commands/clear_constance.py +208 -0
- django_cfg/modules/django_admin/management/commands/create_token.py +328 -0
- django_cfg/modules/django_admin/management/commands/list_urls.py +313 -0
- django_cfg/modules/django_admin/management/commands/migrate_all.py +133 -0
- django_cfg/modules/django_admin/management/commands/migrator.py +403 -0
- django_cfg/modules/django_admin/management/commands/script.py +496 -0
- django_cfg/modules/django_admin/management/commands/show_config.py +225 -0
- django_cfg/modules/django_admin/management/commands/show_urls.py +361 -0
- django_cfg/modules/django_admin/management/commands/superuser.py +302 -0
- django_cfg/modules/django_admin/management/commands/tree.py +390 -0
- django_cfg/modules/django_client/__init__.py +20 -0
- django_cfg/modules/django_client/apps.py +35 -0
- django_cfg/modules/django_client/core/__init__.py +56 -0
- django_cfg/modules/django_client/core/archive/__init__.py +11 -0
- django_cfg/modules/django_client/core/archive/manager.py +134 -0
- django_cfg/modules/django_client/core/cli/__init__.py +12 -0
- django_cfg/modules/django_client/core/cli/main.py +235 -0
- django_cfg/modules/django_client/core/config/__init__.py +18 -0
- django_cfg/modules/django_client/core/config/config.py +208 -0
- django_cfg/modules/django_client/core/config/group.py +101 -0
- django_cfg/modules/django_client/core/config/service.py +209 -0
- django_cfg/modules/django_client/core/generator/__init__.py +115 -0
- django_cfg/modules/django_client/core/generator/base.py +838 -0
- django_cfg/modules/django_client/core/generator/python/__init__.py +16 -0
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +174 -0
- django_cfg/modules/django_client/core/generator/python/files_generator.py +180 -0
- django_cfg/modules/django_client/core/generator/python/generator.py +182 -0
- django_cfg/modules/django_client/core/generator/python/models_generator.py +318 -0
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +278 -0
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +102 -0
- django_cfg/modules/django_client/core/generator/python/templates/__init__.py.jinja +9 -0
- django_cfg/modules/django_client/core/generator/python/templates/api_wrapper.py.jinja +153 -0
- django_cfg/modules/django_client/core/generator/python/templates/app_init.py.jinja +6 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/app_client.py.jinja +18 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/flat_client.py.jinja +38 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/main_client.py.jinja +68 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/main_client_file.py.jinja +14 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/operation_method.py.jinja +9 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/sub_client.py.jinja +18 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/sync_main_client.py.jinja +50 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/sync_operation_method.py.jinja +9 -0
- django_cfg/modules/django_client/core/generator/python/templates/client/sync_sub_client.py.jinja +18 -0
- django_cfg/modules/django_client/core/generator/python/templates/client_file.py.jinja +13 -0
- django_cfg/modules/django_client/core/generator/python/templates/main_init.py.jinja +52 -0
- django_cfg/modules/django_client/core/generator/python/templates/models/app_models.py.jinja +17 -0
- django_cfg/modules/django_client/core/generator/python/templates/models/enum_class.py.jinja +17 -0
- django_cfg/modules/django_client/core/generator/python/templates/models/enums.py.jinja +8 -0
- django_cfg/modules/django_client/core/generator/python/templates/models/models.py.jinja +17 -0
- django_cfg/modules/django_client/core/generator/python/templates/models/schema_class.py.jinja +21 -0
- django_cfg/modules/django_client/core/generator/python/templates/pyproject.toml.jinja +55 -0
- django_cfg/modules/django_client/core/generator/python/templates/utils/logger.py.jinja +255 -0
- django_cfg/modules/django_client/core/generator/python/templates/utils/retry.py.jinja +271 -0
- django_cfg/modules/django_client/core/generator/python/templates/utils/schema.py.jinja +12 -0
- django_cfg/modules/django_client/core/generator/typescript/__init__.py +14 -0
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +165 -0
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +428 -0
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +207 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +432 -0
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +536 -0
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +245 -0
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +298 -0
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +329 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/api_instance.ts.jinja +131 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/app_index.ts.jinja +2 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/app_client.ts.jinja +18 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +403 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/flat_client.ts.jinja +109 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/main_client_file.ts.jinja +10 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/operation.ts.jinja +61 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client/sub_client.ts.jinja +15 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/client_file.ts.jinja +9 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/fetchers.ts.jinja +45 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/index.ts.jinja +30 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/index.ts.jinja +5 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +268 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/models/app_models.ts.jinja +8 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/models/enums.ts.jinja +4 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/models/models.ts.jinja +8 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/package.json.jinja +52 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/schemas/index.ts.jinja +21 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/schemas/schema.ts.jinja +24 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/tsconfig.json.jinja +20 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/errors.ts.jinja +116 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/http.ts.jinja +98 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/logger.ts.jinja +259 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/retry.ts.jinja +175 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/schema.ts.jinja +7 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/utils/storage.ts.jinja +158 -0
- django_cfg/modules/django_client/core/groups/__init__.py +13 -0
- django_cfg/modules/django_client/core/groups/detector.py +178 -0
- django_cfg/modules/django_client/core/groups/manager.py +314 -0
- django_cfg/modules/django_client/core/ir/__init__.py +57 -0
- django_cfg/modules/django_client/core/ir/context.py +387 -0
- django_cfg/modules/django_client/core/ir/operation.py +518 -0
- django_cfg/modules/django_client/core/ir/schema.py +353 -0
- django_cfg/modules/django_client/core/parser/__init__.py +74 -0
- django_cfg/modules/django_client/core/parser/base.py +648 -0
- django_cfg/modules/django_client/core/parser/models/__init__.py +74 -0
- django_cfg/modules/django_client/core/parser/models/base.py +212 -0
- django_cfg/modules/django_client/core/parser/models/components.py +160 -0
- django_cfg/modules/django_client/core/parser/models/openapi.py +203 -0
- django_cfg/modules/django_client/core/parser/models/operation.py +207 -0
- django_cfg/modules/django_client/core/parser/models/schema.py +266 -0
- django_cfg/modules/django_client/core/parser/openapi30.py +56 -0
- django_cfg/modules/django_client/core/parser/openapi31.py +64 -0
- django_cfg/modules/django_client/core/validation/__init__.py +22 -0
- django_cfg/modules/django_client/core/validation/checker.py +134 -0
- django_cfg/modules/django_client/core/validation/fixer.py +216 -0
- django_cfg/modules/django_client/core/validation/reporter.py +480 -0
- django_cfg/modules/django_client/core/validation/rules/__init__.py +11 -0
- django_cfg/modules/django_client/core/validation/rules/base.py +96 -0
- django_cfg/modules/django_client/core/validation/rules/type_hints.py +288 -0
- django_cfg/modules/django_client/core/validation/safety.py +266 -0
- django_cfg/modules/django_client/management/__init__.py +3 -0
- django_cfg/modules/django_client/management/commands/__init__.py +3 -0
- django_cfg/modules/django_client/management/commands/generate_client.py +427 -0
- django_cfg/modules/django_client/management/commands/validate_openapi.py +343 -0
- django_cfg/modules/django_client/pytest.ini +30 -0
- django_cfg/modules/django_client/spectacular/__init__.py +10 -0
- django_cfg/modules/django_client/spectacular/async_detection.py +187 -0
- django_cfg/modules/django_client/spectacular/enum_naming.py +192 -0
- django_cfg/modules/django_client/urls.py +72 -0
- django_cfg/{dashboard → modules/django_dashboard}/DEBUG_README.md +2 -2
- django_cfg/{dashboard → modules/django_dashboard}/REFACTORING_SUMMARY.md +1 -1
- django_cfg/modules/django_dashboard/management/__init__.py +0 -0
- django_cfg/modules/django_dashboard/management/commands/__init__.py +0 -0
- django_cfg/{dashboard → modules/django_dashboard}/management/commands/debug_dashboard.py +5 -5
- django_cfg/modules/django_dashboard/sections/documentation.py +391 -0
- django_cfg/modules/django_email/management/__init__.py +0 -0
- django_cfg/modules/django_email/management/commands/__init__.py +0 -0
- django_cfg/modules/django_email/management/commands/test_email.py +93 -0
- django_cfg/modules/django_logging/LOGGING_GUIDE.md +1 -1
- django_cfg/modules/django_logging/django_logger.py +6 -6
- django_cfg/modules/django_ngrok/management/__init__.py +0 -0
- django_cfg/modules/django_ngrok/management/commands/__init__.py +0 -0
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +167 -0
- django_cfg/modules/django_tasks/management/__init__.py +0 -0
- django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +254 -0
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +437 -0
- django_cfg/modules/django_tasks/management/commands/task_clear.py +226 -0
- django_cfg/modules/django_tasks/management/commands/task_status.py +257 -0
- django_cfg/modules/django_telegram/management/__init__.py +0 -0
- django_cfg/modules/django_telegram/management/commands/__init__.py +0 -0
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +68 -0
- django_cfg/modules/django_twilio/management/__init__.py +0 -0
- django_cfg/modules/django_twilio/management/commands/__init__.py +0 -0
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +112 -0
- django_cfg/modules/django_unfold/callbacks/main.py +21 -10
- django_cfg/modules/django_unfold/callbacks/revolution.py +41 -36
- django_cfg/pyproject.toml +2 -6
- django_cfg/registry/third_party.py +5 -7
- django_cfg/routing/callbacks.py +1 -1
- django_cfg/static/admin/css/prose-unfold.css +666 -0
- django_cfg/templates/admin/index.html +8 -0
- django_cfg/templates/admin/index_new.html +13 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +15 -3
- django_cfg/templates/admin/sections/documentation_section.html +172 -0
- django_cfg/templates/admin/snippets/tabs/documentation_tab.html +231 -0
- {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/METADATA +2 -2
- {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/RECORD +224 -74
- django_cfg/management/commands/generate.py +0 -107
- /django_cfg/models/django/{revolution.py → revolution_legacy.py} +0 -0
- /django_cfg/{dashboard → modules/django_admin}/management/__init__.py +0 -0
- /django_cfg/{dashboard → modules/django_admin}/management/commands/__init__.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/__init__.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/components.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/debug.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/__init__.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/base.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/commands.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/overview.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/stats.py +0 -0
- /django_cfg/{dashboard → modules/django_dashboard}/sections/system.py +0 -0
- {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.10.dist-info → django_cfg-1.4.13.dist-info}/licenses/LICENSE +0 -0
django_cfg/apps/urls.py
CHANGED
@@ -5,67 +5,128 @@ Built-in API endpoints for django_cfg functionality.
|
|
5
5
|
"""
|
6
6
|
|
7
7
|
from django.urls import path, include
|
8
|
-
from typing import List
|
8
|
+
from typing import List, Dict
|
9
9
|
from django.urls import URLPattern
|
10
10
|
|
11
11
|
|
12
|
+
def _register_group_urls(patterns: List[URLPattern], groups: Dict) -> None:
|
13
|
+
"""
|
14
|
+
Auto-register URLs from OpenAPI groups using convention.
|
15
|
+
|
16
|
+
Convention: cfg_{app} → /cfg/{app}/
|
17
|
+
|
18
|
+
Args:
|
19
|
+
patterns: URL patterns list to append to
|
20
|
+
groups: OpenAPI groups dict
|
21
|
+
"""
|
22
|
+
for group_name in groups.keys():
|
23
|
+
# Only django-cfg apps (convention: cfg_*)
|
24
|
+
if not group_name.startswith('cfg_'):
|
25
|
+
continue
|
26
|
+
|
27
|
+
# Extract app name: cfg_payments → payments
|
28
|
+
app_name = group_name[4:]
|
29
|
+
|
30
|
+
# Register main URLs: /cfg/{app}/
|
31
|
+
try:
|
32
|
+
patterns.append(
|
33
|
+
path(f'cfg/{app_name}/', include(f'django_cfg.apps.{app_name}.urls'))
|
34
|
+
)
|
35
|
+
except ImportError:
|
36
|
+
pass # URL module doesn't exist
|
37
|
+
|
38
|
+
# Register admin URLs: /cfg/{app}/admin/ (if exists)
|
39
|
+
try:
|
40
|
+
patterns.append(
|
41
|
+
path(f'cfg/{app_name}/admin/', include(f'django_cfg.apps.{app_name}.urls_admin'))
|
42
|
+
)
|
43
|
+
except ImportError:
|
44
|
+
pass # Admin URL module doesn't exist
|
45
|
+
|
46
|
+
|
47
|
+
def _register_apps_fallback(patterns: List[URLPattern]) -> None:
|
48
|
+
"""
|
49
|
+
Fallback: Register apps when OpenAPI is disabled.
|
50
|
+
|
51
|
+
Uses BaseCfgModule checks to determine which apps are enabled.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
patterns: URL patterns list to append to
|
55
|
+
"""
|
56
|
+
from django_cfg.modules.base import BaseCfgModule
|
57
|
+
base_module = BaseCfgModule()
|
58
|
+
|
59
|
+
# Business logic apps
|
60
|
+
if base_module.is_support_enabled():
|
61
|
+
patterns.append(path('cfg/support/', include('django_cfg.apps.support.urls')))
|
62
|
+
|
63
|
+
if base_module.is_accounts_enabled():
|
64
|
+
patterns.append(path('cfg/accounts/', include('django_cfg.apps.accounts.urls')))
|
65
|
+
|
66
|
+
if base_module.is_newsletter_enabled():
|
67
|
+
patterns.append(path('cfg/newsletter/', include('django_cfg.apps.newsletter.urls')))
|
68
|
+
|
69
|
+
if base_module.is_leads_enabled():
|
70
|
+
patterns.append(path('cfg/leads/', include('django_cfg.apps.leads.urls')))
|
71
|
+
|
72
|
+
if base_module.is_knowbase_enabled():
|
73
|
+
patterns.append(path('cfg/knowbase/', include('django_cfg.apps.knowbase.urls')))
|
74
|
+
|
75
|
+
if base_module.is_agents_enabled():
|
76
|
+
patterns.append(path('cfg/agents/', include('django_cfg.apps.agents.urls')))
|
77
|
+
|
78
|
+
if base_module.should_enable_tasks():
|
79
|
+
patterns.append(path('cfg/tasks/', include('django_cfg.apps.tasks.urls')))
|
80
|
+
patterns.append(path('cfg/tasks/admin/', include('django_cfg.apps.tasks.urls_admin')))
|
81
|
+
|
82
|
+
if base_module.is_payments_enabled():
|
83
|
+
patterns.append(path('cfg/payments/', include('django_cfg.apps.payments.urls')))
|
84
|
+
patterns.append(path('cfg/payments/admin/', include('django_cfg.apps.payments.urls_admin')))
|
85
|
+
|
86
|
+
# Standalone apps
|
87
|
+
if base_module.is_maintenance_enabled():
|
88
|
+
patterns.append(
|
89
|
+
path('admin/django_cfg_maintenance/', include('django_cfg.apps.maintenance.urls_admin'))
|
90
|
+
)
|
91
|
+
|
92
|
+
if base_module.is_rpc_enabled():
|
93
|
+
patterns.append(path('rpc/', include('django_cfg.modules.django_ipc_client.dashboard.urls')))
|
94
|
+
patterns.append(path('admin/rpc/', include('django_cfg.modules.django_ipc_client.dashboard.urls_admin')))
|
95
|
+
|
96
|
+
|
12
97
|
def get_django_cfg_urlpatterns() -> List[URLPattern]:
|
13
98
|
"""
|
14
|
-
Get Django CFG URL patterns based on
|
15
|
-
|
99
|
+
Get Django CFG URL patterns based on OpenAPI groups.
|
100
|
+
|
16
101
|
Returns:
|
17
|
-
List of URL patterns for
|
102
|
+
List of URL patterns for django_cfg
|
18
103
|
"""
|
19
|
-
from django_cfg.modules.base import BaseCfgModule
|
20
|
-
|
21
104
|
patterns = [
|
22
105
|
# Core APIs (always enabled)
|
23
106
|
path('health/', include('django_cfg.apps.api.health.urls')),
|
24
107
|
path('endpoints/', include('django_cfg.apps.api.endpoints.urls')),
|
25
108
|
path('commands/', include('django_cfg.apps.api.commands.urls')),
|
26
|
-
|
109
|
+
|
110
|
+
# OpenAPI schemas (if enabled)
|
111
|
+
# Provides /openapi/{group}/schema/
|
112
|
+
path('openapi/', include('django_cfg.modules.django_client.urls')),
|
27
113
|
]
|
28
|
-
|
114
|
+
|
29
115
|
try:
|
30
|
-
#
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# patterns.append(path('accounts/', include('django_cfg.apps.accounts.urls')))
|
40
|
-
|
41
|
-
# Newsletter and Leads are handled by Django Revolution zones
|
42
|
-
# to avoid URL namespace conflicts and enable client generation
|
43
|
-
# if base_module.is_newsletter_enabled():
|
44
|
-
# patterns.append(path('newsletter/', include('django_cfg.apps.newsletter.urls')))
|
45
|
-
#
|
46
|
-
# if base_module.is_leads_enabled():
|
47
|
-
# patterns.append(path('leads/', include('django_cfg.apps.leads.urls')))
|
48
|
-
|
49
|
-
# Tasks app - enabled when knowbase or agents are enabled
|
50
|
-
if base_module.should_enable_tasks():
|
51
|
-
patterns.append(path('admin/django_cfg_tasks/admin/', include('django_cfg.apps.tasks.urls_admin')))
|
52
|
-
|
53
|
-
# Maintenance app - multi-site maintenance mode with Cloudflare
|
54
|
-
# if base_module.is_maintenance_enabled():
|
55
|
-
# patterns.append(path('admin/django_cfg_maintenance/', include('django_cfg.apps.maintenance.urls_admin')))
|
56
|
-
|
57
|
-
if base_module.is_payments_enabled():
|
58
|
-
patterns.append(path('admin/django_cfg_payments/admin/', include('django_cfg.apps.payments.urls_admin')))
|
59
|
-
|
60
|
-
# RPC Dashboard - WebSocket & RPC activity monitoring
|
61
|
-
if base_module.is_rpc_enabled():
|
62
|
-
patterns.append(path('admin/rpc/', include('django_cfg.modules.django_ipc_client.dashboard.urls_admin')))
|
116
|
+
# Auto-register from OpenAPI groups (preferred)
|
117
|
+
from django_cfg.modules.django_client.core import get_openapi_service
|
118
|
+
service = get_openapi_service()
|
119
|
+
|
120
|
+
if service and service.is_enabled():
|
121
|
+
_register_group_urls(patterns, service.get_groups())
|
122
|
+
else:
|
123
|
+
# Fallback: Use BaseCfgModule when OpenAPI disabled
|
124
|
+
_register_apps_fallback(patterns)
|
63
125
|
|
64
126
|
except Exception:
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
127
|
+
# Last resort fallback
|
128
|
+
_register_apps_fallback(patterns)
|
129
|
+
|
69
130
|
return patterns
|
70
131
|
|
71
132
|
|
@@ -313,12 +313,12 @@ class DjangoConfig(BaseModel):
|
|
313
313
|
# === API Configuration ===
|
314
314
|
drf: Optional[DRFConfig] = Field(
|
315
315
|
default=None,
|
316
|
-
description="Extended Django REST Framework configuration (supplements
|
316
|
+
description="Extended Django REST Framework configuration (supplements OpenAPI Client)",
|
317
317
|
)
|
318
318
|
|
319
319
|
spectacular: Optional[SpectacularConfig] = Field(
|
320
320
|
default=None,
|
321
|
-
description="Extended DRF Spectacular configuration (supplements
|
321
|
+
description="Extended DRF Spectacular configuration (supplements OpenAPI Client)",
|
322
322
|
)
|
323
323
|
|
324
324
|
# === Limits Configuration ===
|
django_cfg/core/constants.py
CHANGED
@@ -4,7 +4,7 @@ Integration generators module.
|
|
4
4
|
Contains generators for third-party integrations and frameworks:
|
5
5
|
- Session configuration
|
6
6
|
- External services (Telegram, Unfold, Constance)
|
7
|
-
- API frameworks (JWT, DRF, Spectacular,
|
7
|
+
- API frameworks (JWT, DRF, Spectacular, OpenAPI Client)
|
8
8
|
- Background tasks (Dramatiq)
|
9
9
|
"""
|
10
10
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
"""
|
2
2
|
API frameworks generator.
|
3
3
|
|
4
|
-
Handles JWT, DRF, Spectacular, and Django
|
4
|
+
Handles JWT, DRF, Spectacular, and Django Client (OpenAPI) configuration.
|
5
5
|
Size: ~250 lines (focused on API frameworks)
|
6
6
|
"""
|
7
7
|
|
@@ -20,7 +20,7 @@ class APIFrameworksGenerator:
|
|
20
20
|
|
21
21
|
Responsibilities:
|
22
22
|
- JWT authentication configuration
|
23
|
-
- Django
|
23
|
+
- Django Client (OpenAPI) framework
|
24
24
|
- Django REST Framework (DRF)
|
25
25
|
- DRF Spectacular (OpenAPI/Swagger)
|
26
26
|
- Auto-configuration and extensions
|
@@ -56,7 +56,7 @@ class APIFrameworksGenerator:
|
|
56
56
|
|
57
57
|
# Generate settings for each API framework
|
58
58
|
settings.update(self._generate_jwt_settings())
|
59
|
-
settings.update(self.
|
59
|
+
settings.update(self._generate_openapi_client_settings())
|
60
60
|
settings.update(self._apply_drf_spectacular_extensions())
|
61
61
|
|
62
62
|
return settings
|
@@ -74,81 +74,105 @@ class APIFrameworksGenerator:
|
|
74
74
|
jwt_settings = self.config.jwt.to_django_settings(self.config.secret_key)
|
75
75
|
return jwt_settings
|
76
76
|
|
77
|
-
def
|
77
|
+
def _generate_openapi_client_settings(self) -> Dict[str, Any]:
|
78
78
|
"""
|
79
|
-
Generate Django
|
79
|
+
Generate Django Client (OpenAPI) framework settings.
|
80
80
|
|
81
81
|
Returns:
|
82
|
-
Dictionary with
|
82
|
+
Dictionary with OpenAPI configuration and auto-generated DRF configuration
|
83
83
|
"""
|
84
|
-
if not hasattr(self.config, "
|
84
|
+
if not hasattr(self.config, "openapi_client") or not self.config.openapi_client:
|
85
85
|
return {}
|
86
86
|
|
87
87
|
settings = {}
|
88
88
|
|
89
|
-
#
|
90
|
-
|
91
|
-
"
|
92
|
-
"api_prefix": self.config.revolution.api_prefix,
|
93
|
-
"debug": getattr(self.config.revolution, "debug", self.config.debug),
|
94
|
-
"auto_install_deps": getattr(self.config.revolution, "auto_install_deps", True),
|
95
|
-
"zones": {
|
96
|
-
zone_name: zone_config.model_dump()
|
97
|
-
for zone_name, zone_config in self.config.revolution.get_zones_with_defaults().items()
|
98
|
-
},
|
99
|
-
}
|
89
|
+
# OpenAPI Client configuration
|
90
|
+
openapi_settings = {
|
91
|
+
"OPENAPI_CLIENT": self.config.openapi_client.model_dump(),
|
100
92
|
}
|
101
|
-
settings.update(
|
93
|
+
settings.update(openapi_settings)
|
102
94
|
|
103
|
-
# Auto-generate DRF configuration
|
104
|
-
drf_settings = self.
|
95
|
+
# Auto-generate DRF configuration from OpenAPIClientConfig
|
96
|
+
drf_settings = self._generate_drf_from_openapi()
|
105
97
|
if drf_settings:
|
106
98
|
settings.update(drf_settings)
|
107
99
|
|
108
100
|
return settings
|
109
101
|
|
110
|
-
def
|
102
|
+
def _generate_drf_from_openapi(self) -> Dict[str, Any]:
|
111
103
|
"""
|
112
|
-
Generate DRF + Spectacular settings from
|
104
|
+
Generate DRF + Spectacular settings from OpenAPIClientConfig.
|
113
105
|
|
114
106
|
Returns:
|
115
107
|
Dictionary with DRF and Spectacular configuration
|
116
108
|
"""
|
117
109
|
try:
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
"
|
124
|
-
"
|
125
|
-
"
|
126
|
-
"
|
127
|
-
"enable_throttling": getattr(self.config.revolution, "drf_enable_throttling", False),
|
128
|
-
|
129
|
-
# Django-CFG specific settings
|
130
|
-
"REST_FRAMEWORK_DEFAULT_PAGINATION_CLASS": "django_cfg.middleware.pagination.DefaultPagination",
|
131
|
-
"REST_FRAMEWORK_PAGE_SIZE": 100,
|
132
|
-
"REST_FRAMEWORK_DEFAULT_RENDERER_CLASSES": [
|
110
|
+
# Extract DRF parameters from OpenAPIClientConfig
|
111
|
+
openapi_config = self.config.openapi_client
|
112
|
+
|
113
|
+
# Build REST_FRAMEWORK settings
|
114
|
+
rest_framework = {
|
115
|
+
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
116
|
+
"DEFAULT_PAGINATION_CLASS": "django_cfg.middleware.pagination.DefaultPagination",
|
117
|
+
"PAGE_SIZE": 100,
|
118
|
+
"DEFAULT_RENDERER_CLASSES": [
|
133
119
|
"rest_framework.renderers.JSONRenderer",
|
134
120
|
"django_cfg.modules.django_drf_theme.renderers.TailwindBrowsableAPIRenderer",
|
135
121
|
],
|
136
122
|
}
|
137
123
|
|
138
|
-
#
|
139
|
-
|
124
|
+
# Add authentication classes if not browsable
|
125
|
+
if not openapi_config.drf_enable_browsable_api:
|
126
|
+
rest_framework["DEFAULT_RENDERER_CLASSES"] = [
|
127
|
+
"rest_framework.renderers.JSONRenderer",
|
128
|
+
]
|
129
|
+
|
130
|
+
# Add throttling if enabled
|
131
|
+
if openapi_config.drf_enable_throttling:
|
132
|
+
rest_framework["DEFAULT_THROTTLE_CLASSES"] = [
|
133
|
+
"rest_framework.throttling.AnonRateThrottle",
|
134
|
+
"rest_framework.throttling.UserRateThrottle",
|
135
|
+
]
|
136
|
+
rest_framework["DEFAULT_THROTTLE_RATES"] = {
|
137
|
+
"anon": "100/day",
|
138
|
+
"user": "1000/day",
|
139
|
+
}
|
140
|
+
|
141
|
+
# Build SPECTACULAR_SETTINGS
|
142
|
+
spectacular_settings = {
|
143
|
+
"TITLE": openapi_config.drf_title,
|
144
|
+
"DESCRIPTION": openapi_config.drf_description,
|
145
|
+
"VERSION": openapi_config.drf_version,
|
146
|
+
"SERVE_INCLUDE_SCHEMA": openapi_config.drf_serve_include_schema,
|
147
|
+
"SCHEMA_PATH_PREFIX": openapi_config.get_drf_schema_path_prefix(),
|
148
|
+
"SWAGGER_UI_SETTINGS": {
|
149
|
+
"deepLinking": True,
|
150
|
+
"persistAuthorization": True,
|
151
|
+
"displayOperationId": True,
|
152
|
+
},
|
153
|
+
"COMPONENT_SPLIT_REQUEST": True,
|
154
|
+
"COMPONENT_SPLIT_PATCH": True,
|
155
|
+
# Postprocessing hooks
|
156
|
+
"POSTPROCESSING_HOOKS": [
|
157
|
+
"django_cfg.modules.django_client.spectacular.auto_fix_enum_names",
|
158
|
+
"django_cfg.modules.django_client.spectacular.mark_async_operations",
|
159
|
+
],
|
160
|
+
}
|
161
|
+
|
162
|
+
drf_settings = {
|
163
|
+
"REST_FRAMEWORK": rest_framework,
|
164
|
+
"SPECTACULAR_SETTINGS": spectacular_settings,
|
165
|
+
}
|
140
166
|
|
141
|
-
logger.info("🚀 Generated DRF + Spectacular settings
|
167
|
+
logger.info("🚀 Generated DRF + Spectacular settings from OpenAPIClientConfig")
|
142
168
|
logger.info(" - Pagination: django_cfg.middleware.pagination.DefaultPagination")
|
143
169
|
logger.info(" - Renderer: TailwindBrowsableAPIRenderer")
|
170
|
+
logger.info(f" - API: {openapi_config.drf_title} v{openapi_config.drf_version}")
|
144
171
|
|
145
172
|
return drf_settings
|
146
173
|
|
147
|
-
except ImportError as e:
|
148
|
-
logger.warning(f"Could not import django_revolution.create_drf_spectacular_config: {e}")
|
149
|
-
return {}
|
150
174
|
except Exception as e:
|
151
|
-
logger.warning(f"Could not generate DRF config from
|
175
|
+
logger.warning(f"Could not generate DRF config from OpenAPIClientConfig: {e}")
|
152
176
|
return {}
|
153
177
|
|
154
178
|
def _apply_drf_spectacular_extensions(self) -> Dict[str, Any]:
|
@@ -185,7 +209,7 @@ class APIFrameworksGenerator:
|
|
185
209
|
Returns:
|
186
210
|
Dictionary with Spectacular settings
|
187
211
|
"""
|
188
|
-
# Check if Spectacular settings exist (from
|
212
|
+
# Check if Spectacular settings exist (from OpenAPI Client or elsewhere)
|
189
213
|
if not hasattr(self, '_has_spectacular_settings'):
|
190
214
|
return {}
|
191
215
|
|
@@ -221,9 +245,9 @@ class APIFrameworksGenerator:
|
|
221
245
|
Returns:
|
222
246
|
Dictionary with DRF settings
|
223
247
|
"""
|
224
|
-
# Don't override if
|
225
|
-
if self.config.
|
226
|
-
logger.info("🔧 DRF settings already configured by
|
248
|
+
# Don't override if OpenAPIClientConfig already created full DRF config
|
249
|
+
if hasattr(self.config, 'openapi_client') and self.config.openapi_client:
|
250
|
+
logger.info("🔧 DRF settings already configured by OpenAPIClientConfig, skipping django-cfg extensions")
|
227
251
|
return {}
|
228
252
|
|
229
253
|
settings = {}
|
@@ -160,8 +160,8 @@ class StartupDisplayManager(BaseDisplayManager):
|
|
160
160
|
# App-specific configuration panels
|
161
161
|
self._display_config_panels()
|
162
162
|
|
163
|
-
#
|
164
|
-
self.
|
163
|
+
# OpenAPI Client info
|
164
|
+
self._display_openapi_client_info()
|
165
165
|
|
166
166
|
# Management commands
|
167
167
|
self._display_commands_info()
|
@@ -661,30 +661,38 @@ class StartupDisplayManager(BaseDisplayManager):
|
|
661
661
|
print(f"❌ ERROR in _display_constance_summary: {e}")
|
662
662
|
traceback.print_exc()
|
663
663
|
|
664
|
-
def
|
665
|
-
"""Display Django
|
664
|
+
def _display_openapi_client_info(self):
|
665
|
+
"""Display Django Client (OpenAPI) information."""
|
666
666
|
try:
|
667
|
-
from
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
667
|
+
from django_cfg.modules.django_client.core.config.service import DjangoOpenAPI
|
668
|
+
|
669
|
+
service = DjangoOpenAPI.instance()
|
670
|
+
if not service.config or not service.config.enabled:
|
671
|
+
return
|
672
|
+
|
673
|
+
openapi_table = self.create_table()
|
674
|
+
openapi_table.add_column("Setting", style="cyan", width=30)
|
675
|
+
openapi_table.add_column("Value", style="white")
|
676
|
+
|
677
|
+
openapi_table.add_row("📦 Status", "[green]Enabled[/green]")
|
678
|
+
openapi_table.add_row("📊 Groups", str(len(service.config.groups)))
|
679
|
+
openapi_table.add_row("🔗 API Prefix", f"/{service.config.api_prefix}/")
|
680
|
+
openapi_table.add_row("📁 Output Dir", str(service.config.output_dir))
|
681
|
+
|
682
|
+
# List groups
|
683
|
+
group_names = [g.name for g in service.config.groups]
|
684
|
+
if group_names:
|
685
|
+
openapi_table.add_row("🏷️ Groups", ", ".join(group_names[:3]) + ("..." if len(group_names) > 3 else ""))
|
686
|
+
|
687
|
+
openapi_panel = self.create_panel(
|
688
|
+
openapi_table,
|
689
|
+
title="🚀 Django Client (OpenAPI)",
|
682
690
|
border_style="blue"
|
683
691
|
)
|
684
|
-
|
685
|
-
self.console.print(
|
692
|
+
|
693
|
+
self.console.print(openapi_panel)
|
686
694
|
except ImportError:
|
687
|
-
# Django
|
695
|
+
# Django Client not available
|
688
696
|
pass
|
689
697
|
except Exception:
|
690
698
|
pass
|
@@ -16,7 +16,7 @@ def add_django_cfg_urls(urlpatterns: List[URLPattern], cfg_prefix: str = "cfg/")
|
|
16
16
|
|
17
17
|
This function adds:
|
18
18
|
- Django CFG management URLs (cfg/)
|
19
|
-
- Django
|
19
|
+
- Django Client URLs (if available)
|
20
20
|
- Startup information display (based on config)
|
21
21
|
|
22
22
|
Args:
|
@@ -37,22 +37,16 @@ def add_django_cfg_urls(urlpatterns: List[URLPattern], cfg_prefix: str = "cfg/")
|
|
37
37
|
|
38
38
|
# Automatically adds:
|
39
39
|
# - path("cfg/", include("django_cfg.apps.urls"))
|
40
|
-
# - Django
|
40
|
+
# - Django Client URLs (if available)
|
41
41
|
# - Startup info display (based on config.startup_info_mode)
|
42
42
|
urlpatterns = add_django_cfg_urls(urlpatterns)
|
43
43
|
"""
|
44
44
|
# Add django_cfg API URLs
|
45
|
+
# Note: Django Client URLs are included in django_cfg.apps.urls
|
46
|
+
# at /cfg/openapi/{group}/schema/ to avoid conflicts
|
45
47
|
new_patterns = urlpatterns + [
|
46
48
|
path(cfg_prefix, include("django_cfg.apps.urls")),
|
47
49
|
]
|
48
|
-
|
49
|
-
# Try to add Django Revolution URLs if available
|
50
|
-
try:
|
51
|
-
from django_revolution import add_revolution_urls
|
52
|
-
new_patterns = add_revolution_urls(new_patterns)
|
53
|
-
except ImportError:
|
54
|
-
# Django Revolution not available - skip
|
55
|
-
pass
|
56
50
|
|
57
51
|
# Add django-browser-reload URLs in development (if installed)
|
58
52
|
if settings.DEBUG:
|
@@ -122,13 +116,18 @@ def get_django_cfg_urls_info() -> dict:
|
|
122
116
|
}
|
123
117
|
}
|
124
118
|
|
125
|
-
# Add Django
|
119
|
+
# Add Django Client info if available
|
126
120
|
try:
|
127
|
-
from
|
128
|
-
|
129
|
-
if
|
130
|
-
info["
|
121
|
+
from django_cfg.modules.django_client.core.config.service import DjangoOpenAPI
|
122
|
+
service = DjangoOpenAPI.instance()
|
123
|
+
if service.config and service.config.enabled:
|
124
|
+
info["django_client"] = {
|
125
|
+
"enabled": True,
|
126
|
+
"groups": len(service.config.groups),
|
127
|
+
"base_url": service.config.base_url,
|
128
|
+
"output_dir": service.config.output_dir,
|
129
|
+
}
|
131
130
|
except ImportError:
|
132
131
|
pass
|
133
|
-
|
132
|
+
|
134
133
|
return info
|