django-cfg 1.4.9__py3-none-any.whl → 1.4.11__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.
Files changed (193) hide show
  1. django_cfg/apps/agents/management/commands/create_agent.py +1 -1
  2. django_cfg/apps/agents/management/commands/orchestrator_status.py +3 -3
  3. django_cfg/apps/newsletter/serializers.py +40 -3
  4. django_cfg/apps/newsletter/views/campaigns.py +12 -3
  5. django_cfg/apps/newsletter/views/emails.py +14 -3
  6. django_cfg/apps/newsletter/views/subscriptions.py +12 -2
  7. django_cfg/apps/payments/middleware/api_access.py +6 -2
  8. django_cfg/apps/payments/middleware/rate_limiting.py +2 -1
  9. django_cfg/apps/payments/middleware/usage_tracking.py +5 -1
  10. django_cfg/apps/payments/models/managers/api_key_managers.py +0 -1
  11. django_cfg/apps/payments/models/managers/subscription_managers.py +0 -1
  12. django_cfg/apps/payments/services/core/balance_service.py +5 -5
  13. django_cfg/apps/payments/services/core/subscription_service.py +1 -2
  14. django_cfg/apps/payments/views/api/balances.py +8 -7
  15. django_cfg/apps/payments/views/api/base.py +10 -6
  16. django_cfg/apps/payments/views/api/currencies.py +53 -10
  17. django_cfg/apps/payments/views/api/payments.py +3 -1
  18. django_cfg/apps/payments/views/api/subscriptions.py +2 -5
  19. django_cfg/apps/payments/views/api/webhooks.py +72 -7
  20. django_cfg/apps/payments/views/overview/serializers.py +34 -1
  21. django_cfg/apps/payments/views/overview/views.py +2 -1
  22. django_cfg/apps/payments/views/serializers/payments.py +6 -6
  23. django_cfg/apps/urls.py +106 -45
  24. django_cfg/core/base/config_model.py +2 -2
  25. django_cfg/core/constants.py +1 -1
  26. django_cfg/core/generation/integration_generators/__init__.py +1 -1
  27. django_cfg/core/generation/integration_generators/api.py +82 -41
  28. django_cfg/core/integration/display/startup.py +30 -22
  29. django_cfg/core/integration/url_integration.py +15 -16
  30. django_cfg/dashboard/sections/documentation.py +391 -0
  31. django_cfg/management/commands/check_endpoints.py +11 -160
  32. django_cfg/management/commands/check_settings.py +13 -265
  33. django_cfg/management/commands/clear_constance.py +13 -201
  34. django_cfg/management/commands/create_token.py +13 -321
  35. django_cfg/management/commands/generate_clients.py +23 -0
  36. django_cfg/management/commands/list_urls.py +13 -306
  37. django_cfg/management/commands/migrate_all.py +13 -126
  38. django_cfg/management/commands/migrator.py +13 -396
  39. django_cfg/management/commands/rundramatiq.py +15 -247
  40. django_cfg/management/commands/rundramatiq_simulator.py +12 -429
  41. django_cfg/management/commands/runserver_ngrok.py +15 -160
  42. django_cfg/management/commands/script.py +12 -488
  43. django_cfg/management/commands/show_config.py +12 -215
  44. django_cfg/management/commands/show_urls.py +12 -342
  45. django_cfg/management/commands/superuser.py +15 -295
  46. django_cfg/management/commands/task_clear.py +14 -217
  47. django_cfg/management/commands/task_status.py +13 -248
  48. django_cfg/management/commands/test_email.py +15 -86
  49. django_cfg/management/commands/test_telegram.py +14 -61
  50. django_cfg/management/commands/test_twilio.py +15 -105
  51. django_cfg/management/commands/tree.py +13 -383
  52. django_cfg/management/commands/validate_openapi.py +10 -0
  53. django_cfg/middleware/README.md +1 -1
  54. django_cfg/middleware/user_activity.py +3 -3
  55. django_cfg/models/__init__.py +2 -2
  56. django_cfg/models/api/drf/spectacular.py +6 -6
  57. django_cfg/models/django/__init__.py +2 -2
  58. django_cfg/models/django/openapi.py +238 -0
  59. django_cfg/models/django/{revolution.py → revolution_legacy.py} +8 -0
  60. django_cfg/modules/django_admin/management/__init__.py +0 -0
  61. django_cfg/modules/django_admin/management/commands/__init__.py +0 -0
  62. django_cfg/modules/django_admin/management/commands/check_endpoints.py +169 -0
  63. django_cfg/modules/django_admin/management/commands/check_settings.py +355 -0
  64. django_cfg/modules/django_admin/management/commands/clear_constance.py +208 -0
  65. django_cfg/modules/django_admin/management/commands/create_token.py +328 -0
  66. django_cfg/modules/django_admin/management/commands/list_urls.py +313 -0
  67. django_cfg/modules/django_admin/management/commands/migrate_all.py +133 -0
  68. django_cfg/modules/django_admin/management/commands/migrator.py +403 -0
  69. django_cfg/modules/django_admin/management/commands/script.py +496 -0
  70. django_cfg/modules/django_admin/management/commands/show_config.py +225 -0
  71. django_cfg/modules/django_admin/management/commands/show_urls.py +361 -0
  72. django_cfg/modules/django_admin/management/commands/superuser.py +302 -0
  73. django_cfg/modules/django_admin/management/commands/tree.py +390 -0
  74. django_cfg/modules/django_client/__init__.py +20 -0
  75. django_cfg/modules/django_client/apps.py +35 -0
  76. django_cfg/modules/django_client/core/__init__.py +56 -0
  77. django_cfg/modules/django_client/core/archive/__init__.py +11 -0
  78. django_cfg/modules/django_client/core/archive/manager.py +134 -0
  79. django_cfg/modules/django_client/core/cli/__init__.py +12 -0
  80. django_cfg/modules/django_client/core/cli/main.py +235 -0
  81. django_cfg/modules/django_client/core/config/__init__.py +18 -0
  82. django_cfg/modules/django_client/core/config/config.py +188 -0
  83. django_cfg/modules/django_client/core/config/group.py +101 -0
  84. django_cfg/modules/django_client/core/config/service.py +209 -0
  85. django_cfg/modules/django_client/core/generator/__init__.py +115 -0
  86. django_cfg/modules/django_client/core/generator/base.py +767 -0
  87. django_cfg/modules/django_client/core/generator/python.py +751 -0
  88. django_cfg/modules/django_client/core/generator/templates/python/__init__.py.jinja +9 -0
  89. django_cfg/modules/django_client/core/generator/templates/python/api_wrapper.py.jinja +130 -0
  90. django_cfg/modules/django_client/core/generator/templates/python/app_init.py.jinja +6 -0
  91. django_cfg/modules/django_client/core/generator/templates/python/client/app_client.py.jinja +18 -0
  92. django_cfg/modules/django_client/core/generator/templates/python/client/flat_client.py.jinja +38 -0
  93. django_cfg/modules/django_client/core/generator/templates/python/client/main_client.py.jinja +50 -0
  94. django_cfg/modules/django_client/core/generator/templates/python/client/main_client_file.py.jinja +13 -0
  95. django_cfg/modules/django_client/core/generator/templates/python/client/operation_method.py.jinja +7 -0
  96. django_cfg/modules/django_client/core/generator/templates/python/client/sub_client.py.jinja +11 -0
  97. django_cfg/modules/django_client/core/generator/templates/python/client_file.py.jinja +13 -0
  98. django_cfg/modules/django_client/core/generator/templates/python/main_init.py.jinja +50 -0
  99. django_cfg/modules/django_client/core/generator/templates/python/models/app_models.py.jinja +17 -0
  100. django_cfg/modules/django_client/core/generator/templates/python/models/enum_class.py.jinja +15 -0
  101. django_cfg/modules/django_client/core/generator/templates/python/models/enums.py.jinja +8 -0
  102. django_cfg/modules/django_client/core/generator/templates/python/models/models.py.jinja +17 -0
  103. django_cfg/modules/django_client/core/generator/templates/python/models/schema_class.py.jinja +19 -0
  104. django_cfg/modules/django_client/core/generator/templates/python/utils/logger.py.jinja +255 -0
  105. django_cfg/modules/django_client/core/generator/templates/python/utils/schema.py.jinja +12 -0
  106. django_cfg/modules/django_client/core/generator/templates/typescript/app_index.ts.jinja +2 -0
  107. django_cfg/modules/django_client/core/generator/templates/typescript/client/app_client.ts.jinja +18 -0
  108. django_cfg/modules/django_client/core/generator/templates/typescript/client/client.ts.jinja +327 -0
  109. django_cfg/modules/django_client/core/generator/templates/typescript/client/flat_client.ts.jinja +109 -0
  110. django_cfg/modules/django_client/core/generator/templates/typescript/client/main_client_file.ts.jinja +9 -0
  111. django_cfg/modules/django_client/core/generator/templates/typescript/client/operation.ts.jinja +61 -0
  112. django_cfg/modules/django_client/core/generator/templates/typescript/client/sub_client.ts.jinja +15 -0
  113. django_cfg/modules/django_client/core/generator/templates/typescript/client_file.ts.jinja +9 -0
  114. django_cfg/modules/django_client/core/generator/templates/typescript/index.ts.jinja +5 -0
  115. django_cfg/modules/django_client/core/generator/templates/typescript/main_index.ts.jinja +206 -0
  116. django_cfg/modules/django_client/core/generator/templates/typescript/models/app_models.ts.jinja +8 -0
  117. django_cfg/modules/django_client/core/generator/templates/typescript/models/enums.ts.jinja +4 -0
  118. django_cfg/modules/django_client/core/generator/templates/typescript/models/models.ts.jinja +8 -0
  119. django_cfg/modules/django_client/core/generator/templates/typescript/utils/errors.ts.jinja +114 -0
  120. django_cfg/modules/django_client/core/generator/templates/typescript/utils/http.ts.jinja +98 -0
  121. django_cfg/modules/django_client/core/generator/templates/typescript/utils/logger.ts.jinja +251 -0
  122. django_cfg/modules/django_client/core/generator/templates/typescript/utils/schema.ts.jinja +7 -0
  123. django_cfg/modules/django_client/core/generator/templates/typescript/utils/storage.ts.jinja +114 -0
  124. django_cfg/modules/django_client/core/generator/typescript.py +872 -0
  125. django_cfg/modules/django_client/core/groups/__init__.py +13 -0
  126. django_cfg/modules/django_client/core/groups/detector.py +178 -0
  127. django_cfg/modules/django_client/core/groups/manager.py +314 -0
  128. django_cfg/modules/django_client/core/ir/__init__.py +57 -0
  129. django_cfg/modules/django_client/core/ir/context.py +387 -0
  130. django_cfg/modules/django_client/core/ir/operation.py +518 -0
  131. django_cfg/modules/django_client/core/ir/schema.py +353 -0
  132. django_cfg/modules/django_client/core/parser/__init__.py +74 -0
  133. django_cfg/modules/django_client/core/parser/base.py +648 -0
  134. django_cfg/modules/django_client/core/parser/models/__init__.py +74 -0
  135. django_cfg/modules/django_client/core/parser/models/base.py +212 -0
  136. django_cfg/modules/django_client/core/parser/models/components.py +160 -0
  137. django_cfg/modules/django_client/core/parser/models/openapi.py +203 -0
  138. django_cfg/modules/django_client/core/parser/models/operation.py +207 -0
  139. django_cfg/modules/django_client/core/parser/models/schema.py +266 -0
  140. django_cfg/modules/django_client/core/parser/openapi30.py +56 -0
  141. django_cfg/modules/django_client/core/parser/openapi31.py +64 -0
  142. django_cfg/modules/django_client/core/validation/__init__.py +22 -0
  143. django_cfg/modules/django_client/core/validation/checker.py +134 -0
  144. django_cfg/modules/django_client/core/validation/fixer.py +216 -0
  145. django_cfg/modules/django_client/core/validation/reporter.py +480 -0
  146. django_cfg/modules/django_client/core/validation/rules/__init__.py +11 -0
  147. django_cfg/modules/django_client/core/validation/rules/base.py +96 -0
  148. django_cfg/modules/django_client/core/validation/rules/type_hints.py +288 -0
  149. django_cfg/modules/django_client/core/validation/safety.py +266 -0
  150. django_cfg/modules/django_client/management/__init__.py +3 -0
  151. django_cfg/modules/django_client/management/commands/__init__.py +3 -0
  152. django_cfg/modules/django_client/management/commands/generate_client.py +422 -0
  153. django_cfg/modules/django_client/management/commands/validate_openapi.py +343 -0
  154. django_cfg/modules/django_client/spectacular/__init__.py +9 -0
  155. django_cfg/modules/django_client/spectacular/enum_naming.py +192 -0
  156. django_cfg/modules/django_client/urls.py +72 -0
  157. django_cfg/modules/django_email/management/__init__.py +0 -0
  158. django_cfg/modules/django_email/management/commands/__init__.py +0 -0
  159. django_cfg/modules/django_email/management/commands/test_email.py +93 -0
  160. django_cfg/modules/django_logging/django_logger.py +6 -6
  161. django_cfg/modules/django_ngrok/management/__init__.py +0 -0
  162. django_cfg/modules/django_ngrok/management/commands/__init__.py +0 -0
  163. django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +167 -0
  164. django_cfg/modules/django_tasks/management/__init__.py +0 -0
  165. django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
  166. django_cfg/modules/django_tasks/management/commands/rundramatiq.py +254 -0
  167. django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +437 -0
  168. django_cfg/modules/django_tasks/management/commands/task_clear.py +226 -0
  169. django_cfg/modules/django_tasks/management/commands/task_status.py +257 -0
  170. django_cfg/modules/django_telegram/management/__init__.py +0 -0
  171. django_cfg/modules/django_telegram/management/commands/__init__.py +0 -0
  172. django_cfg/modules/django_telegram/management/commands/test_telegram.py +68 -0
  173. django_cfg/modules/django_twilio/management/__init__.py +0 -0
  174. django_cfg/modules/django_twilio/management/commands/__init__.py +0 -0
  175. django_cfg/modules/django_twilio/management/commands/test_twilio.py +112 -0
  176. django_cfg/modules/django_unfold/callbacks/main.py +16 -5
  177. django_cfg/modules/django_unfold/callbacks/revolution.py +41 -36
  178. django_cfg/modules/django_unfold/dashboard.py +1 -1
  179. django_cfg/pyproject.toml +2 -6
  180. django_cfg/registry/third_party.py +5 -7
  181. django_cfg/routing/callbacks.py +1 -1
  182. django_cfg/static/admin/css/prose-unfold.css +666 -0
  183. django_cfg/templates/admin/index.html +8 -0
  184. django_cfg/templates/admin/index_new.html +13 -0
  185. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +15 -3
  186. django_cfg/templates/admin/sections/documentation_section.html +172 -0
  187. django_cfg/templates/admin/snippets/tabs/documentation_tab.html +231 -0
  188. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/METADATA +2 -2
  189. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/RECORD +192 -71
  190. django_cfg/management/commands/generate.py +0 -107
  191. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/WHEEL +0 -0
  192. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/entry_points.txt +0 -0
  193. {django_cfg-1.4.9.dist-info → django_cfg-1.4.11.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,238 @@
1
+ """
2
+ Django Client (OpenAPI) Configuration with DRF Integration
3
+
4
+ Extended configuration model that integrates openapi_client for automatic
5
+ TypeScript and Python client generation from Django REST Framework endpoints.
6
+
7
+ This replaces django-revolution with a cleaner, faster, type-safe implementation.
8
+ """
9
+
10
+ from typing import Dict, Any, Optional
11
+ from pydantic import BaseModel, Field
12
+ from django_cfg.modules.django_client.core.config import OpenAPIConfig, OpenAPIGroupConfig
13
+
14
+
15
+ class ExtendedOpenAPIConfig(OpenAPIConfig):
16
+ """
17
+ Extended OpenAPI configuration with DRF parameters for django-cfg integration.
18
+
19
+ This extends the base OpenAPIConfig to include DRF-specific
20
+ parameters and django-cfg integration helpers.
21
+
22
+ Example:
23
+ ```python
24
+ from django_cfg import ExtendedOpenAPIConfig, OpenAPIGroupConfig
25
+
26
+ config = ExtendedOpenAPIConfig(
27
+ enabled=True,
28
+ groups=[
29
+ OpenAPIGroupConfig(
30
+ name='api',
31
+ apps=['users', 'posts'],
32
+ title='Main API',
33
+ version='v1',
34
+ ),
35
+ ],
36
+ drf_title='My API',
37
+ drf_description='REST API for my project',
38
+ )
39
+ ```
40
+ """
41
+
42
+ # DRF Configuration parameters for automatic DRF setup
43
+ drf_title: str = Field(
44
+ default="API",
45
+ description="API title for DRF Spectacular"
46
+ )
47
+ drf_description: str = Field(
48
+ default="RESTful API",
49
+ description="API description for DRF Spectacular"
50
+ )
51
+ drf_version: str = Field(
52
+ default="1.0.0",
53
+ description="API version for DRF Spectacular"
54
+ )
55
+ drf_schema_path_prefix: Optional[str] = Field(
56
+ default=None, # Will default to "/api/" if None
57
+ description="Schema path prefix for DRF Spectacular"
58
+ )
59
+ drf_enable_browsable_api: bool = Field(
60
+ default=False,
61
+ description="Enable DRF browsable API"
62
+ )
63
+ drf_enable_throttling: bool = Field(
64
+ default=False,
65
+ description="Enable DRF throttling"
66
+ )
67
+ drf_serve_include_schema: bool = Field(
68
+ default=False,
69
+ description="Include schema in Spectacular UI"
70
+ )
71
+
72
+ # Django-cfg specific integration
73
+ api_prefix: str = Field(
74
+ default="api",
75
+ description="API prefix for URL routing (e.g., 'api' -> /api/...)"
76
+ )
77
+
78
+ def get_drf_schema_path_prefix(self) -> str:
79
+ """Get the schema path prefix, defaulting to api_prefix if not set."""
80
+ if self.drf_schema_path_prefix:
81
+ return self.drf_schema_path_prefix
82
+ return f"/{self.api_prefix}/"
83
+
84
+ def get_drf_config_kwargs(self) -> Dict[str, Any]:
85
+ """
86
+ Get kwargs for DRF configuration from this config.
87
+
88
+ Returns:
89
+ Dict of parameters for DRF + Spectacular setup
90
+ """
91
+ return {
92
+ "title": self.drf_title,
93
+ "description": self.drf_description,
94
+ "version": self.drf_version,
95
+ "schema_path_prefix": self.get_drf_schema_path_prefix(),
96
+ "enable_browsable_api": self.drf_enable_browsable_api,
97
+ "enable_throttling": self.drf_enable_throttling,
98
+ "serve_include_schema": self.drf_serve_include_schema,
99
+ # REQUIRED by django-client for correct Request/Response split
100
+ "component_split_request": True,
101
+ "component_split_patch": True,
102
+ }
103
+
104
+ def get_groups_with_defaults(self) -> Dict[str, OpenAPIGroupConfig]:
105
+ """
106
+ Get groups with django-cfg default groups automatically added.
107
+
108
+ Returns:
109
+ Dict of groups including default django-cfg groups
110
+ """
111
+ # Convert list to dict for compatibility
112
+ groups_dict = {group.name: group for group in self.groups}
113
+
114
+ # Add default django-cfg groups if enabled
115
+ try:
116
+ from django_cfg.modules.base import BaseCfgModule
117
+ base_module = BaseCfgModule()
118
+
119
+ support_enabled = base_module.is_support_enabled()
120
+ accounts_enabled = base_module.is_accounts_enabled()
121
+ newsletter_enabled = base_module.is_newsletter_enabled()
122
+ leads_enabled = base_module.is_leads_enabled()
123
+ knowbase_enabled = base_module.is_knowbase_enabled()
124
+ agents_enabled = base_module.is_agents_enabled()
125
+ tasks_enabled = base_module.should_enable_tasks()
126
+ payments_enabled = base_module.is_payments_enabled()
127
+
128
+ # Collect all enabled django-cfg apps for unified group
129
+ enabled_cfg_apps = []
130
+ if support_enabled:
131
+ enabled_cfg_apps.append("django_cfg.apps.support")
132
+ if accounts_enabled:
133
+ enabled_cfg_apps.append("django_cfg.apps.accounts")
134
+ if newsletter_enabled:
135
+ enabled_cfg_apps.append("django_cfg.apps.newsletter")
136
+ if leads_enabled:
137
+ enabled_cfg_apps.append("django_cfg.apps.leads")
138
+ if knowbase_enabled:
139
+ enabled_cfg_apps.append("django_cfg.apps.knowbase")
140
+ if agents_enabled:
141
+ enabled_cfg_apps.append("django_cfg.apps.agents")
142
+ if tasks_enabled:
143
+ enabled_cfg_apps.append("django_cfg.apps.tasks")
144
+ if payments_enabled:
145
+ enabled_cfg_apps.append("django_cfg.apps.payments")
146
+
147
+ # Add unified 'cfg' group with all enabled apps
148
+ if enabled_cfg_apps and 'cfg' not in groups_dict:
149
+ groups_dict['cfg'] = OpenAPIGroupConfig(
150
+ name="cfg",
151
+ apps=enabled_cfg_apps,
152
+ title="Django-CFG API",
153
+ description="All django-cfg built-in applications",
154
+ )
155
+
156
+ # Skip individual cfg_* groups - use unified 'cfg' instead
157
+ return groups_dict
158
+
159
+ # Add Support group if enabled
160
+ if support_enabled and 'cfg_support' not in groups_dict:
161
+ groups_dict['cfg_support'] = OpenAPIGroupConfig(
162
+ name="cfg_support",
163
+ apps=["django_cfg.apps.support"],
164
+ title="Support API",
165
+ description="Support tickets and messages API",
166
+ )
167
+
168
+ # Add Accounts group if enabled
169
+ if accounts_enabled and 'cfg_accounts' not in groups_dict:
170
+ groups_dict['cfg_accounts'] = OpenAPIGroupConfig(
171
+ name="cfg_accounts",
172
+ apps=["django_cfg.apps.accounts"],
173
+ title="Accounts API",
174
+ description="User management, OTP, profiles, and activity tracking API",
175
+ )
176
+
177
+ # Add Newsletter group if enabled
178
+ if newsletter_enabled and 'cfg_newsletter' not in groups_dict:
179
+ groups_dict['cfg_newsletter'] = OpenAPIGroupConfig(
180
+ name="cfg_newsletter",
181
+ apps=["django_cfg.apps.newsletter"],
182
+ title="Newsletter API",
183
+ description="Email campaigns, subscriptions, and newsletter management API",
184
+ )
185
+
186
+ # Add Leads group if enabled
187
+ if leads_enabled and 'cfg_leads' not in groups_dict:
188
+ groups_dict['cfg_leads'] = OpenAPIGroupConfig(
189
+ name="cfg_leads",
190
+ apps=["django_cfg.apps.leads"],
191
+ title="Leads API",
192
+ description="Lead collection, contact forms, and CRM integration API",
193
+ )
194
+
195
+ # Add Knowbase group if enabled
196
+ if knowbase_enabled and 'cfg_knowbase' not in groups_dict:
197
+ groups_dict['cfg_knowbase'] = OpenAPIGroupConfig(
198
+ name="cfg_knowbase",
199
+ apps=["django_cfg.apps.knowbase"],
200
+ title="Knowbase API",
201
+ description="Knowledge base, AI chat, embeddings, and search API",
202
+ )
203
+
204
+ # Add Agents group if enabled
205
+ if agents_enabled and 'cfg_agents' not in groups_dict:
206
+ groups_dict['cfg_agents'] = OpenAPIGroupConfig(
207
+ name="cfg_agents",
208
+ apps=["django_cfg.apps.agents"],
209
+ title="Agents API",
210
+ description="Agent definitions, executions, workflows, and tools API",
211
+ )
212
+
213
+ # Add Tasks group if enabled
214
+ if tasks_enabled and 'cfg_tasks' not in groups_dict:
215
+ groups_dict['cfg_tasks'] = OpenAPIGroupConfig(
216
+ name="cfg_tasks",
217
+ apps=["django_cfg.apps.tasks"],
218
+ title="Tasks API",
219
+ description="Tasks, workflows, and automation API",
220
+ )
221
+
222
+ # Add Payments group if enabled
223
+ if payments_enabled and 'cfg_payments' not in groups_dict:
224
+ groups_dict['cfg_payments'] = OpenAPIGroupConfig(
225
+ name="cfg_payments",
226
+ apps=["django_cfg.apps.payments"],
227
+ title="Payments API",
228
+ description="Payments, subscriptions, and billing API",
229
+ )
230
+
231
+ except Exception:
232
+ pass
233
+
234
+ return groups_dict
235
+
236
+
237
+ # Alias for easier import
238
+ OpenAPIClientConfig = ExtendedOpenAPIConfig
@@ -117,6 +117,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
117
117
  description="Support tickets and messages API",
118
118
  public=False,
119
119
  auth_required=True,
120
+ group="cfg",
120
121
  # version="v1",
121
122
  )
122
123
 
@@ -129,6 +130,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
129
130
  description="User management, OTP, profiles, and activity tracking API",
130
131
  public=False,
131
132
  auth_required=True,
133
+ group="cfg",
132
134
  # version="v1",
133
135
  )
134
136
 
@@ -141,6 +143,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
141
143
  description="Email campaigns, subscriptions, and newsletter management API",
142
144
  public=False,
143
145
  auth_required=True,
146
+ group="cfg",
144
147
  # version="v1",
145
148
  )
146
149
 
@@ -153,6 +156,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
153
156
  description="Lead collection, contact forms, and CRM integration API",
154
157
  public=True, # Leads can be public for contact forms
155
158
  auth_required=False,
159
+ group="cfg",
156
160
  # version="v1",
157
161
  )
158
162
 
@@ -165,6 +169,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
165
169
  description="Knowledge base, AI chat, embeddings, and search API",
166
170
  public=False,
167
171
  auth_required=True,
172
+ group="cfg",
168
173
  # version="v1",
169
174
  )
170
175
 
@@ -177,6 +182,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
177
182
  description="Agent definitions, executions, workflows, and tools API",
178
183
  public=False,
179
184
  auth_required=True,
185
+ group="cfg",
180
186
  # version="v1",
181
187
  )
182
188
 
@@ -189,6 +195,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
189
195
  description="Tasks, workflows, and automation API",
190
196
  public=False,
191
197
  auth_required=True,
198
+ group="cfg",
192
199
  # version="v1",
193
200
  )
194
201
 
@@ -201,6 +208,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
201
208
  description="Payments, subscriptions, and billing API",
202
209
  public=False,
203
210
  auth_required=True,
211
+ group="cfg",
204
212
  # version="v1",
205
213
  )
206
214
 
File without changes
@@ -0,0 +1,169 @@
1
+ """
2
+ Django management command to check all API endpoints status.
3
+
4
+ Usage:
5
+ 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
+ """
10
+
11
+ from django.core.management.base import BaseCommand
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')
162
+
163
+ if endpoint.get('rate_limited'):
164
+ self.stdout.write(f' ⏱️ Rate limited (429)')
165
+
166
+ self.stdout.write('')
167
+
168
+ # Timestamp
169
+ self.stdout.write(self.style.HTTP_INFO(f'🕐 Checked at: {data["timestamp"]}'))