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
@@ -1,169 +1,20 @@
|
|
1
1
|
"""
|
2
|
-
Django
|
2
|
+
Django-CFG wrapper for check_endpoints command.
|
3
|
+
|
4
|
+
This is a simple alias for django_admin.management.commands.check_endpoints.
|
5
|
+
All logic is in django_admin module.
|
3
6
|
|
4
7
|
Usage:
|
5
8
|
python manage.py check_endpoints
|
6
|
-
python manage.py check_endpoints --include-unnamed
|
7
|
-
python manage.py check_endpoints --timeout 10
|
8
|
-
python manage.py check_endpoints --json
|
9
9
|
"""
|
10
10
|
|
11
|
-
from
|
12
|
-
from django.urls import reverse
|
13
|
-
from django_cfg.apps.api.endpoints.checker import check_all_endpoints
|
14
|
-
import json
|
15
|
-
|
16
|
-
|
17
|
-
class Command(BaseCommand):
|
18
|
-
help = 'Check status of all Django CFG API endpoints'
|
19
|
-
|
20
|
-
def add_arguments(self, parser):
|
21
|
-
parser.add_argument(
|
22
|
-
'--include-unnamed',
|
23
|
-
action='store_true',
|
24
|
-
help='Include unnamed URL patterns in the check',
|
25
|
-
)
|
26
|
-
parser.add_argument(
|
27
|
-
'--timeout',
|
28
|
-
type=int,
|
29
|
-
default=5,
|
30
|
-
help='Request timeout in seconds (default: 5)',
|
31
|
-
)
|
32
|
-
parser.add_argument(
|
33
|
-
'--json',
|
34
|
-
action='store_true',
|
35
|
-
help='Output results as JSON',
|
36
|
-
)
|
37
|
-
parser.add_argument(
|
38
|
-
'--url',
|
39
|
-
type=str,
|
40
|
-
help='Check specific endpoint by URL name (e.g., "endpoints_status")',
|
41
|
-
)
|
42
|
-
parser.add_argument(
|
43
|
-
'--no-auth',
|
44
|
-
action='store_true',
|
45
|
-
help='Disable automatic JWT authentication retry (default: enabled)',
|
46
|
-
)
|
47
|
-
|
48
|
-
def handle(self, *args, **options):
|
49
|
-
include_unnamed = options['include_unnamed']
|
50
|
-
timeout = options['timeout']
|
51
|
-
output_json = options['json']
|
52
|
-
url_name = options.get('url')
|
53
|
-
auto_auth = not options['no_auth'] # Auto-auth enabled by default
|
54
|
-
|
55
|
-
# If specific URL requested, just resolve and display it
|
56
|
-
if url_name:
|
57
|
-
try:
|
58
|
-
url = reverse(url_name)
|
59
|
-
self.stdout.write(self.style.SUCCESS(f'โ
URL name "{url_name}" resolves to: {url}'))
|
60
|
-
return
|
61
|
-
except Exception as e:
|
62
|
-
self.stdout.write(self.style.ERROR(f'โ Error resolving URL "{url_name}": {e}'))
|
63
|
-
return
|
64
|
-
|
65
|
-
# Check all endpoints
|
66
|
-
auth_msg = "with auto-auth" if auto_auth else "without auth"
|
67
|
-
self.stdout.write(self.style.WARNING(f'๐ Checking endpoints (timeout: {timeout}s, {auth_msg})...'))
|
68
|
-
|
69
|
-
status_data = check_all_endpoints(
|
70
|
-
include_unnamed=include_unnamed,
|
71
|
-
timeout=timeout,
|
72
|
-
auto_auth=auto_auth
|
73
|
-
)
|
74
|
-
|
75
|
-
# Output as JSON if requested
|
76
|
-
if output_json:
|
77
|
-
self.stdout.write(json.dumps(status_data, indent=2))
|
78
|
-
return
|
79
|
-
|
80
|
-
# Pretty print results
|
81
|
-
self._print_results(status_data)
|
82
|
-
|
83
|
-
def _print_results(self, data):
|
84
|
-
"""Print formatted results to console."""
|
85
|
-
|
86
|
-
# Overall status
|
87
|
-
status = data['status']
|
88
|
-
if status == 'healthy':
|
89
|
-
status_style = self.style.SUCCESS
|
90
|
-
emoji = 'โ
'
|
91
|
-
elif status == 'degraded':
|
92
|
-
status_style = self.style.WARNING
|
93
|
-
emoji = 'โ ๏ธ'
|
94
|
-
else:
|
95
|
-
status_style = self.style.ERROR
|
96
|
-
emoji = 'โ'
|
97
|
-
|
98
|
-
self.stdout.write('')
|
99
|
-
self.stdout.write(status_style(f'{emoji} Overall Status: {status.upper()}'))
|
100
|
-
self.stdout.write('')
|
101
|
-
|
102
|
-
# Summary
|
103
|
-
self.stdout.write(self.style.HTTP_INFO('๐ Summary:'))
|
104
|
-
self.stdout.write(f' Total endpoints: {data["total_endpoints"]}')
|
105
|
-
self.stdout.write(self.style.SUCCESS(f' โ
Healthy: {data["healthy"]}'))
|
106
|
-
self.stdout.write(self.style.WARNING(f' โ ๏ธ Warnings: {data["warnings"]}'))
|
107
|
-
self.stdout.write(self.style.ERROR(f' โ Unhealthy: {data["unhealthy"]}'))
|
108
|
-
self.stdout.write(self.style.ERROR(f' โ Errors: {data["errors"]}'))
|
109
|
-
self.stdout.write(f' โญ๏ธ Skipped: {data["skipped"]}')
|
110
|
-
self.stdout.write('')
|
111
|
-
|
112
|
-
# Endpoints details
|
113
|
-
self.stdout.write(self.style.HTTP_INFO('๐ Endpoints:'))
|
114
|
-
|
115
|
-
for endpoint in data['endpoints']:
|
116
|
-
name = endpoint.get('url_name') or 'unnamed'
|
117
|
-
url = endpoint['url']
|
118
|
-
status = endpoint['status']
|
119
|
-
|
120
|
-
if status == 'healthy':
|
121
|
-
icon = 'โ
'
|
122
|
-
style = self.style.SUCCESS
|
123
|
-
elif status == 'degraded':
|
124
|
-
icon = 'โ ๏ธ'
|
125
|
-
style = self.style.WARNING
|
126
|
-
else:
|
127
|
-
icon = 'โ'
|
128
|
-
style = self.style.ERROR
|
129
|
-
|
130
|
-
self.stdout.write(f' {icon} {name}')
|
131
|
-
|
132
|
-
# Show both pattern and resolved URL for parametrized endpoints
|
133
|
-
if endpoint.get('has_parameters') and endpoint.get('url_pattern'):
|
134
|
-
self.stdout.write(f' Pattern: {endpoint["url_pattern"]}')
|
135
|
-
self.stdout.write(f' Resolved: {url}')
|
136
|
-
else:
|
137
|
-
self.stdout.write(f' URL: {url}')
|
138
|
-
|
139
|
-
# Show status with status code
|
140
|
-
status_code = endpoint.get('status_code')
|
141
|
-
if status_code:
|
142
|
-
self.stdout.write(style(f' Status: {status} ({status_code})'))
|
143
|
-
else:
|
144
|
-
self.stdout.write(style(f' Status: {status}'))
|
145
|
-
|
146
|
-
if endpoint.get('response_time_ms'):
|
147
|
-
self.stdout.write(f' Response time: {endpoint["response_time_ms"]:.2f}ms')
|
148
|
-
|
149
|
-
if endpoint.get('error'):
|
150
|
-
error_type = endpoint.get('error_type', 'general')
|
151
|
-
if error_type == 'database':
|
152
|
-
self.stdout.write(self.style.WARNING(f' โ ๏ธ DB Error (multi-db): {endpoint["error"]}'))
|
153
|
-
else:
|
154
|
-
self.stdout.write(self.style.ERROR(f' Error: {endpoint["error"]}'))
|
155
|
-
|
156
|
-
# Show reason for warnings (e.g., 404 explanations)
|
157
|
-
if endpoint.get('reason') and status == 'warning':
|
158
|
-
self.stdout.write(self.style.WARNING(f' โ ๏ธ {endpoint["reason"]}'))
|
159
|
-
|
160
|
-
if endpoint.get('required_auth'):
|
161
|
-
self.stdout.write(f' ๐ Required JWT authentication')
|
11
|
+
from django_cfg.modules.django_admin.management.commands.check_endpoints import Command as CheckEndpointsCommand
|
162
12
|
|
163
|
-
if endpoint.get('rate_limited'):
|
164
|
-
self.stdout.write(f' โฑ๏ธ Rate limited (429)')
|
165
13
|
|
166
|
-
|
14
|
+
class Command(CheckEndpointsCommand):
|
15
|
+
"""
|
16
|
+
Alias for check_endpoints command.
|
167
17
|
|
168
|
-
|
169
|
-
|
18
|
+
Simply inherits from CheckEndpointsCommand without any changes.
|
19
|
+
"""
|
20
|
+
pass
|
@@ -1,355 +1,20 @@
|
|
1
1
|
"""
|
2
|
-
Django
|
2
|
+
Django-CFG wrapper for check_settings command.
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
"""
|
7
|
-
|
8
|
-
import os
|
9
|
-
import sys
|
10
|
-
from pathlib import Path
|
11
|
-
from django.core.management.base import BaseCommand
|
12
|
-
from django.conf import settings
|
13
|
-
from django.core.exceptions import ImproperlyConfigured
|
14
|
-
from django.core.mail import get_connection
|
15
|
-
from datetime import datetime
|
16
|
-
from django_cfg.modules.django_logging import get_logger
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
logger = get_logger('check_settings')
|
21
|
-
|
22
|
-
class Command(BaseCommand):
|
23
|
-
"""Command to check and debug django-cfg settings."""
|
24
|
-
|
25
|
-
# Web execution metadata
|
26
|
-
web_executable = True
|
27
|
-
requires_input = False
|
28
|
-
is_destructive = False
|
29
|
-
|
30
|
-
help = "Check and debug django-cfg configuration settings"
|
31
|
-
|
32
|
-
def add_arguments(self, parser):
|
33
|
-
parser.add_argument(
|
34
|
-
'--email-test',
|
35
|
-
action='store_true',
|
36
|
-
help='Test email configuration and SMTP connection'
|
37
|
-
)
|
38
|
-
parser.add_argument(
|
39
|
-
'--verbose',
|
40
|
-
action='store_true',
|
41
|
-
help='Show detailed configuration information'
|
42
|
-
)
|
43
|
-
|
44
|
-
def handle(self, *args, **options):
|
45
|
-
"""Main command handler."""
|
46
|
-
logger.info("Starting check_settings command")
|
47
|
-
self.stdout.write(self.style.SUCCESS("\n๐ Django CFG Settings Checker\n"))
|
48
|
-
|
49
|
-
# Show basic info
|
50
|
-
self.show_environment_info()
|
51
|
-
self.show_email_config()
|
52
|
-
self.show_drf_config()
|
53
|
-
|
54
|
-
if options['verbose']:
|
55
|
-
self.show_database_config()
|
56
|
-
self.show_app_config()
|
57
|
-
self.show_cors_config()
|
58
|
-
|
59
|
-
if options['email_test']:
|
60
|
-
self.test_email_connection()
|
61
|
-
|
62
|
-
def show_environment_info(self):
|
63
|
-
"""Show environment and debug information."""
|
64
|
-
self.stdout.write(self.style.SUCCESS("๐ Environment Information:"))
|
65
|
-
|
66
|
-
# Debug mode
|
67
|
-
debug = getattr(settings, 'DEBUG', False)
|
68
|
-
self.stdout.write(f" ๐ DEBUG: {debug}")
|
69
|
-
|
70
|
-
# Environment detection
|
71
|
-
env_vars = {
|
72
|
-
'DJANGO_SETTINGS_MODULE': os.environ.get('DJANGO_SETTINGS_MODULE', 'Not set'),
|
73
|
-
'ENVIRONMENT': os.environ.get('ENVIRONMENT', 'Not set'),
|
74
|
-
}
|
75
|
-
|
76
|
-
for key, value in env_vars.items():
|
77
|
-
self.stdout.write(f" ๐ {key}: {value}")
|
78
|
-
|
79
|
-
def show_email_config(self):
|
80
|
-
"""Show detailed email configuration."""
|
81
|
-
self.stdout.write(self.style.SUCCESS("\n๐ง Email Configuration:"))
|
82
|
-
|
83
|
-
# Basic email settings
|
84
|
-
email_settings = {
|
85
|
-
'EMAIL_BACKEND': getattr(settings, 'EMAIL_BACKEND', 'Not set'),
|
86
|
-
'EMAIL_HOST': getattr(settings, 'EMAIL_HOST', 'Not set'),
|
87
|
-
'EMAIL_PORT': getattr(settings, 'EMAIL_PORT', 'Not set'),
|
88
|
-
'EMAIL_USE_TLS': getattr(settings, 'EMAIL_USE_TLS', 'Not set'),
|
89
|
-
'EMAIL_USE_SSL': getattr(settings, 'EMAIL_USE_SSL', 'Not set'),
|
90
|
-
'EMAIL_HOST_USER': getattr(settings, 'EMAIL_HOST_USER', 'Not set'),
|
91
|
-
'DEFAULT_FROM_EMAIL': getattr(settings, 'DEFAULT_FROM_EMAIL', 'Not set'),
|
92
|
-
}
|
93
|
-
|
94
|
-
# Show password status (not actual password)
|
95
|
-
password_set = bool(getattr(settings, 'EMAIL_HOST_PASSWORD', None))
|
96
|
-
email_settings['EMAIL_HOST_PASSWORD'] = '***SET***' if password_set else 'Not set'
|
97
|
-
|
98
|
-
for key, value in email_settings.items():
|
99
|
-
icon = "โ
" if value != 'Not set' else "โ"
|
100
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
101
|
-
|
102
|
-
# Analyze backend type
|
103
|
-
backend = email_settings['EMAIL_BACKEND']
|
104
|
-
if 'console' in backend:
|
105
|
-
self.stdout.write(self.style.WARNING(" โ ๏ธ Console backend - emails will be printed to console"))
|
106
|
-
elif 'locmem' in backend:
|
107
|
-
self.stdout.write(self.style.WARNING(" โ ๏ธ Local memory backend - emails stored in memory"))
|
108
|
-
elif 'filebased' in backend:
|
109
|
-
self.stdout.write(self.style.WARNING(" โ ๏ธ File backend - emails saved to files"))
|
110
|
-
elif 'smtp' in backend:
|
111
|
-
self.stdout.write(self.style.SUCCESS(" ๐ค SMTP backend - emails will be sent via SMTP"))
|
112
|
-
|
113
|
-
# Check django-cfg email service
|
114
|
-
try:
|
115
|
-
from django_cfg.modules.django_email import DjangoEmailService
|
116
|
-
email_service = DjangoEmailService()
|
117
|
-
backend_info = email_service.get_backend_info()
|
118
|
-
|
119
|
-
self.stdout.write(f"\n ๐ง Django CFG Email Service:")
|
120
|
-
self.stdout.write(f" Backend: {backend_info['backend']}")
|
121
|
-
self.stdout.write(f" Configured: {backend_info['configured']}")
|
122
|
-
|
123
|
-
except Exception as e:
|
124
|
-
self.stdout.write(self.style.ERROR(f" โ Django CFG Email Service error: {e}"))
|
4
|
+
This is a simple alias for django_admin.management.commands.check_settings.
|
5
|
+
All logic is in django_admin module.
|
125
6
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
# Check REST_FRAMEWORK settings
|
131
|
-
rest_framework = getattr(settings, 'REST_FRAMEWORK', {})
|
132
|
-
if rest_framework:
|
133
|
-
self.stdout.write(" โ
REST_FRAMEWORK configured")
|
134
|
-
|
135
|
-
# Show key DRF settings
|
136
|
-
drf_settings = {
|
137
|
-
'DEFAULT_SCHEMA_CLASS': rest_framework.get('DEFAULT_SCHEMA_CLASS', 'Not set'),
|
138
|
-
'DEFAULT_AUTHENTICATION_CLASSES': rest_framework.get('DEFAULT_AUTHENTICATION_CLASSES', []),
|
139
|
-
'DEFAULT_PERMISSION_CLASSES': rest_framework.get('DEFAULT_PERMISSION_CLASSES', []),
|
140
|
-
'DEFAULT_PAGINATION_CLASS': rest_framework.get('DEFAULT_PAGINATION_CLASS', 'Not set'),
|
141
|
-
'PAGE_SIZE': rest_framework.get('PAGE_SIZE', 'Not set'),
|
142
|
-
}
|
143
|
-
|
144
|
-
for key, value in drf_settings.items():
|
145
|
-
icon = "โ
" if value and value != 'Not set' else "โ"
|
146
|
-
if isinstance(value, list):
|
147
|
-
if value:
|
148
|
-
self.stdout.write(f" {icon} {key}:")
|
149
|
-
for item in value:
|
150
|
-
self.stdout.write(f" - {item}")
|
151
|
-
else:
|
152
|
-
self.stdout.write(f" {icon} {key}: []")
|
153
|
-
else:
|
154
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
155
|
-
else:
|
156
|
-
self.stdout.write(" โ REST_FRAMEWORK not configured")
|
157
|
-
|
158
|
-
# Check SPECTACULAR_SETTINGS
|
159
|
-
spectacular = getattr(settings, 'SPECTACULAR_SETTINGS', {})
|
160
|
-
if spectacular:
|
161
|
-
self.stdout.write("\n โ
SPECTACULAR_SETTINGS configured")
|
162
|
-
|
163
|
-
# Show key Spectacular settings
|
164
|
-
spectacular_settings = {
|
165
|
-
'TITLE': spectacular.get('TITLE', 'Not set'),
|
166
|
-
'VERSION': spectacular.get('VERSION', 'Not set'),
|
167
|
-
'SCHEMA_PATH_PREFIX': spectacular.get('SCHEMA_PATH_PREFIX', 'Not set'),
|
168
|
-
'SERVE_INCLUDE_SCHEMA': spectacular.get('SERVE_INCLUDE_SCHEMA', 'Not set'),
|
169
|
-
}
|
170
|
-
|
171
|
-
for key, value in spectacular_settings.items():
|
172
|
-
icon = "โ
" if value != 'Not set' else "โ"
|
173
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
174
|
-
else:
|
175
|
-
self.stdout.write("\n โ SPECTACULAR_SETTINGS not configured")
|
176
|
-
|
177
|
-
# Check SimpleJWT settings
|
178
|
-
simple_jwt = getattr(settings, 'SIMPLE_JWT', {})
|
179
|
-
if simple_jwt:
|
180
|
-
self.stdout.write("\n โ
SIMPLE_JWT configured")
|
181
|
-
|
182
|
-
jwt_settings = {
|
183
|
-
'ACCESS_TOKEN_LIFETIME': simple_jwt.get('ACCESS_TOKEN_LIFETIME', 'Not set'),
|
184
|
-
'REFRESH_TOKEN_LIFETIME': simple_jwt.get('REFRESH_TOKEN_LIFETIME', 'Not set'),
|
185
|
-
'ALGORITHM': simple_jwt.get('ALGORITHM', 'Not set'),
|
186
|
-
}
|
187
|
-
|
188
|
-
for key, value in jwt_settings.items():
|
189
|
-
icon = "โ
" if value != 'Not set' else "โ"
|
190
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
191
|
-
else:
|
192
|
-
self.stdout.write("\n โ SIMPLE_JWT not configured")
|
193
|
-
|
194
|
-
# Get django-cfg config
|
195
|
-
try:
|
196
|
-
from django_cfg.core.state import get_current_config
|
197
|
-
config = get_current_config()
|
198
|
-
|
199
|
-
if config:
|
200
|
-
self.stdout.write("\n ๐ Django-CFG Config:")
|
201
|
-
self.stdout.write(f" drf: {'โ
Configured' if config.drf else 'โ Not set'}")
|
202
|
-
self.stdout.write(f" spectacular: {'โ
Configured' if config.spectacular else 'โ Not set'}")
|
203
|
-
self.stdout.write(f" jwt: {'โ
Configured' if config.jwt else 'โ Not set'}")
|
204
|
-
self.stdout.write(f" revolution: {'โ
Configured' if config.revolution else 'โ Not set'}")
|
205
|
-
except Exception as e:
|
206
|
-
self.stdout.write(self.style.ERROR(f" โ Error getting django-cfg config: {e}"))
|
207
|
-
|
208
|
-
def show_database_config(self):
|
209
|
-
"""Show database configuration."""
|
210
|
-
self.stdout.write(self.style.SUCCESS("\n๐๏ธ Database Configuration:"))
|
211
|
-
|
212
|
-
databases = getattr(settings, 'DATABASES', {})
|
213
|
-
for db_name, db_config in databases.items():
|
214
|
-
engine = db_config.get('ENGINE', 'Unknown')
|
215
|
-
name = db_config.get('NAME', 'Unknown')
|
216
|
-
host = db_config.get('HOST', 'localhost')
|
217
|
-
port = db_config.get('PORT', 'default')
|
218
|
-
|
219
|
-
self.stdout.write(f" ๐ {db_name}:")
|
220
|
-
self.stdout.write(f" Engine: {engine}")
|
221
|
-
self.stdout.write(f" Name: {name}")
|
222
|
-
if host and host != 'localhost':
|
223
|
-
self.stdout.write(f" Host: {host}:{port}")
|
7
|
+
Usage:
|
8
|
+
python manage.py check_settings
|
9
|
+
"""
|
224
10
|
|
225
|
-
|
226
|
-
"""Show installed apps configuration."""
|
227
|
-
self.stdout.write(self.style.SUCCESS("\n๐ฆ Django CFG Apps:"))
|
228
|
-
|
229
|
-
installed_apps = getattr(settings, 'INSTALLED_APPS', [])
|
230
|
-
cfg_apps = [app for app in installed_apps if 'django_cfg' in app]
|
231
|
-
|
232
|
-
for app in cfg_apps:
|
233
|
-
self.stdout.write(f" โ
{app}")
|
234
|
-
|
235
|
-
if not cfg_apps:
|
236
|
-
self.stdout.write(" โ No django_cfg apps found")
|
11
|
+
from django_cfg.modules.django_admin.management.commands.check_settings import Command as CheckSettingsCommand
|
237
12
|
|
238
|
-
def show_cors_config(self):
|
239
|
-
"""Show CORS and security configuration."""
|
240
|
-
self.stdout.write(self.style.SUCCESS("\n๐ CORS & Security Configuration:"))
|
241
|
-
|
242
|
-
# Get current config
|
243
|
-
try:
|
244
|
-
from django_cfg.core.state import get_current_config
|
245
|
-
config = get_current_config()
|
246
|
-
|
247
|
-
if config:
|
248
|
-
self.stdout.write(f" ๐ Security Domains: {config.security_domains}")
|
249
|
-
self.stdout.write(f" ๐ CORS Headers: {config.cors_allow_headers}")
|
250
|
-
self.stdout.write(f" ๐ SSL Redirect: {config.ssl_redirect}")
|
251
|
-
else:
|
252
|
-
self.stdout.write(" โ ๏ธ No django-cfg config instance found")
|
253
|
-
|
254
|
-
except Exception as e:
|
255
|
-
self.stdout.write(self.style.ERROR(f" โ Error getting config: {e}"))
|
256
|
-
|
257
|
-
# Show Django settings
|
258
|
-
cors_settings = {
|
259
|
-
'CORS_ALLOW_ALL_ORIGINS': getattr(settings, 'CORS_ALLOW_ALL_ORIGINS', None),
|
260
|
-
'CORS_ALLOWED_ORIGINS': getattr(settings, 'CORS_ALLOWED_ORIGINS', None),
|
261
|
-
'CORS_ALLOW_CREDENTIALS': getattr(settings, 'CORS_ALLOW_CREDENTIALS', None),
|
262
|
-
'CORS_ALLOW_HEADERS': getattr(settings, 'CORS_ALLOW_HEADERS', None),
|
263
|
-
'CSRF_TRUSTED_ORIGINS': getattr(settings, 'CSRF_TRUSTED_ORIGINS', None),
|
264
|
-
}
|
265
|
-
|
266
|
-
self.stdout.write("\n ๐ง Generated Django Settings:")
|
267
|
-
for key, value in cors_settings.items():
|
268
|
-
if value is not None:
|
269
|
-
icon = "โ
"
|
270
|
-
if key == 'CORS_ALLOW_HEADERS' and isinstance(value, list):
|
271
|
-
# Show first few headers for readability
|
272
|
-
display_value = value[:3] + ['...'] if len(value) > 3 else value
|
273
|
-
self.stdout.write(f" {icon} {key}: {display_value} ({len(value)} total)")
|
274
|
-
elif key in ['CORS_ALLOWED_ORIGINS', 'CSRF_TRUSTED_ORIGINS'] and isinstance(value, list):
|
275
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
276
|
-
else:
|
277
|
-
self.stdout.write(f" {icon} {key}: {value}")
|
278
|
-
else:
|
279
|
-
self.stdout.write(f" โญ {key}: Not set")
|
280
|
-
|
281
|
-
# Analysis
|
282
|
-
self.stdout.write("\n ๐ CORS Analysis:")
|
283
|
-
if cors_settings['CORS_ALLOW_ALL_ORIGINS']:
|
284
|
-
self.stdout.write(" ๐ก Development mode: All origins allowed")
|
285
|
-
elif cors_settings['CORS_ALLOWED_ORIGINS']:
|
286
|
-
origins_count = len(cors_settings['CORS_ALLOWED_ORIGINS'])
|
287
|
-
self.stdout.write(f" ๐ข Production mode: {origins_count} specific origins allowed")
|
288
|
-
else:
|
289
|
-
self.stdout.write(" ๐ด No CORS origins configured")
|
290
13
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
try:
|
296
|
-
# Test Django's email connection
|
297
|
-
connection = get_connection()
|
298
|
-
connection.open()
|
299
|
-
self.stdout.write(" โ
Django email connection successful")
|
300
|
-
connection.close()
|
301
|
-
|
302
|
-
except Exception as e:
|
303
|
-
self.stdout.write(self.style.ERROR(f" โ Django email connection failed: {e}"))
|
304
|
-
|
305
|
-
try:
|
306
|
-
# Test django-cfg email service
|
307
|
-
from django_cfg.modules.django_email import DjangoEmailService
|
308
|
-
email_service = DjangoEmailService()
|
309
|
-
|
310
|
-
# Try to send a test email (dry run)
|
311
|
-
self.stdout.write(" ๐ Testing django-cfg email service...")
|
312
|
-
|
313
|
-
# Just check if service can be initialized
|
314
|
-
backend_info = email_service.get_backend_info()
|
315
|
-
if backend_info['configured']:
|
316
|
-
self.stdout.write(" โ
Django CFG email service is properly configured")
|
317
|
-
else:
|
318
|
-
self.stdout.write(self.style.WARNING(" โ ๏ธ Django CFG email service configuration incomplete"))
|
319
|
-
|
320
|
-
except Exception as e:
|
321
|
-
self.stdout.write(self.style.ERROR(f" โ Django CFG email service test failed: {e}"))
|
322
|
-
|
323
|
-
# Show recommendations
|
324
|
-
self.show_email_recommendations()
|
14
|
+
class Command(CheckSettingsCommand):
|
15
|
+
"""
|
16
|
+
Alias for check_settings command.
|
325
17
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
backend = getattr(settings, 'EMAIL_BACKEND', '')
|
331
|
-
debug = getattr(settings, 'DEBUG', False)
|
332
|
-
|
333
|
-
if 'console' in backend and not debug:
|
334
|
-
self.stdout.write(" โ ๏ธ Console backend in production - emails won't be delivered")
|
335
|
-
self.stdout.write(" Consider switching to SMTP backend")
|
336
|
-
|
337
|
-
if 'smtp' in backend:
|
338
|
-
host = getattr(settings, 'EMAIL_HOST', '')
|
339
|
-
user = getattr(settings, 'EMAIL_HOST_USER', '')
|
340
|
-
password = getattr(settings, 'EMAIL_HOST_PASSWORD', '')
|
341
|
-
|
342
|
-
if not host:
|
343
|
-
self.stdout.write(" โ SMTP host not configured")
|
344
|
-
if not user:
|
345
|
-
self.stdout.write(" โ SMTP username not configured")
|
346
|
-
if not password:
|
347
|
-
self.stdout.write(" โ SMTP password not configured")
|
348
|
-
|
349
|
-
if host and user and password:
|
350
|
-
self.stdout.write(" โ
SMTP configuration appears complete")
|
351
|
-
|
352
|
-
self.stdout.write("\n ๐ For more help:")
|
353
|
-
self.stdout.write(" - Check your config.dev.yaml email settings")
|
354
|
-
self.stdout.write(" - Verify SMTP credentials with your email provider")
|
355
|
-
self.stdout.write(" - Test with: python manage.py test_email")
|
18
|
+
Simply inherits from CheckSettingsCommand without any changes.
|
19
|
+
"""
|
20
|
+
pass
|