django-cfg 1.3.11__py3-none-any.whl → 1.4.0__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 (439) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/accounts/admin/user_admin.py +39 -16
  4. django_cfg/apps/accounts/serializers/profile.py +1 -1
  5. django_cfg/apps/accounts/services/otp_service.py +18 -11
  6. django_cfg/apps/accounts/signals.py +15 -24
  7. django_cfg/apps/accounts/utils/notifications.py +217 -358
  8. django_cfg/apps/accounts/views/otp.py +2 -2
  9. django_cfg/apps/accounts/views/webhook.py +1 -1
  10. django_cfg/apps/agents/core/django_agent.py +1 -1
  11. django_cfg/apps/api/commands/views.py +66 -83
  12. django_cfg/apps/api/health/drf_views.py +269 -0
  13. django_cfg/apps/api/health/serializers.py +45 -0
  14. django_cfg/apps/api/health/urls.py +6 -1
  15. django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
  16. django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
  17. django_cfg/apps/knowbase/admin/document_admin.py +136 -270
  18. django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
  19. django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
  20. django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
  21. django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
  22. django_cfg/apps/knowbase/config/constance_fields.py +1 -1
  23. django_cfg/apps/knowbase/config/settings.py +2 -2
  24. django_cfg/apps/knowbase/mixins/__init__.py +19 -2
  25. django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
  26. django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
  27. django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
  28. django_cfg/apps/knowbase/mixins/creator.py +10 -10
  29. django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
  30. django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
  31. django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
  32. django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
  33. django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
  34. django_cfg/apps/knowbase/mixins/service.py +2 -2
  35. django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
  36. django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
  37. django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
  38. django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
  39. django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
  40. django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
  41. django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
  42. django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
  43. django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
  44. django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
  45. django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
  46. django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
  47. django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
  48. django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
  49. django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
  50. django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
  51. django_cfg/apps/knowbase/services/embedding/models.py +18 -14
  52. django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
  53. django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
  54. django_cfg/apps/leads/tests.py +1 -1
  55. django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
  56. django_cfg/apps/payments/admin/balance_admin.py +1 -1
  57. django_cfg/apps/payments/admin/currencies_admin.py +1 -1
  58. django_cfg/apps/payments/admin/payments_admin.py +1 -1
  59. django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
  60. django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
  61. django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
  62. django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
  63. django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
  64. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
  65. django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
  66. django_cfg/apps/payments/admin_interface/views/base.py +29 -2
  67. django_cfg/apps/payments/apps.py +1 -1
  68. django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
  69. django_cfg/apps/payments/config/helpers.py +3 -2
  70. django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
  71. django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
  72. django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
  73. django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
  74. django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
  75. django_cfg/apps/payments/management/commands/test_providers.py +1 -1
  76. django_cfg/apps/payments/middleware/api_access.py +1 -1
  77. django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
  78. django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
  79. django_cfg/apps/payments/models/balance.py +2 -2
  80. django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
  81. django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
  82. django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
  83. django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
  84. django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
  85. django_cfg/apps/payments/models/payments.py +2 -2
  86. django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
  87. django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
  88. django_cfg/apps/payments/services/core/base.py +1 -1
  89. django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
  90. django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
  91. django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
  92. django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
  93. django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
  94. django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
  95. django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
  96. django_cfg/apps/payments/services/core/payment_service.py +124 -612
  97. django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
  98. django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
  99. django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
  100. django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
  101. django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
  102. django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
  103. django_cfg/apps/payments/services/providers/base.py +1 -1
  104. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
  105. django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
  106. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
  107. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
  108. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
  109. django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
  110. django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
  111. django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
  112. django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
  113. django_cfg/apps/payments/services/providers/registry.py +1 -1
  114. django_cfg/apps/payments/services/providers/sync_service.py +1 -1
  115. django_cfg/apps/payments/signals/__init__.py +1 -1
  116. django_cfg/apps/payments/signals/api_key_signals.py +1 -1
  117. django_cfg/apps/payments/signals/balance_signals.py +1 -1
  118. django_cfg/apps/payments/signals/payment_signals.py +1 -1
  119. django_cfg/apps/payments/signals/subscription_signals.py +1 -1
  120. django_cfg/apps/payments/views/api/api_keys.py +1 -1
  121. django_cfg/apps/payments/views/api/balances.py +1 -1
  122. django_cfg/apps/payments/views/api/base.py +1 -1
  123. django_cfg/apps/payments/views/api/currencies.py +1 -1
  124. django_cfg/apps/payments/views/api/payments.py +1 -1
  125. django_cfg/apps/payments/views/api/subscriptions.py +1 -1
  126. django_cfg/apps/payments/views/api/webhooks.py +1 -1
  127. django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
  128. django_cfg/apps/payments/views/serializers/balances.py +1 -1
  129. django_cfg/apps/payments/views/serializers/currencies.py +1 -1
  130. django_cfg/apps/payments/views/serializers/payments.py +1 -1
  131. django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
  132. django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
  133. django_cfg/apps/support/admin/support_admin.py +21 -13
  134. django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
  135. django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
  136. django_cfg/apps/support/utils/support_email_service.py +1 -1
  137. django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
  138. django_cfg/apps/tasks/utils/simulator.py +1 -1
  139. django_cfg/apps/tasks/views/dashboard.py +33 -3
  140. django_cfg/apps/urls.py +5 -1
  141. django_cfg/cli/README.md +57 -471
  142. django_cfg/cli/commands/create_project.py +140 -529
  143. django_cfg/cli/main.py +13 -10
  144. django_cfg/core/__init__.py +63 -6
  145. django_cfg/core/base/__init__.py +5 -0
  146. django_cfg/core/base/config_model.py +652 -0
  147. django_cfg/core/builders/__init__.py +11 -0
  148. django_cfg/core/builders/apps_builder.py +258 -0
  149. django_cfg/core/builders/middleware_builder.py +115 -0
  150. django_cfg/core/builders/security_builder.py +96 -0
  151. django_cfg/core/config.py +20 -892
  152. django_cfg/core/constants.py +69 -0
  153. django_cfg/core/environment/__init__.py +9 -0
  154. django_cfg/core/exceptions.py +45 -298
  155. django_cfg/core/generation/__init__.py +51 -0
  156. django_cfg/core/generation/core_generators/__init__.py +0 -0
  157. django_cfg/core/generation/core_generators/settings.py +90 -0
  158. django_cfg/core/generation/core_generators/static.py +82 -0
  159. django_cfg/core/generation/core_generators/templates.py +141 -0
  160. django_cfg/core/generation/data_generators/__init__.py +15 -0
  161. django_cfg/core/generation/data_generators/cache.py +132 -0
  162. django_cfg/core/generation/data_generators/database.py +117 -0
  163. django_cfg/core/generation/generation.py +92 -0
  164. django_cfg/core/generation/integration_generators/__init__.py +21 -0
  165. django_cfg/core/generation/integration_generators/api.py +237 -0
  166. django_cfg/core/generation/integration_generators/sessions.py +65 -0
  167. django_cfg/core/generation/integration_generators/tailwind.py +54 -0
  168. django_cfg/core/generation/integration_generators/tasks.py +92 -0
  169. django_cfg/core/generation/integration_generators/third_party.py +144 -0
  170. django_cfg/core/generation/orchestrator.py +285 -0
  171. django_cfg/core/generation/protocols.py +30 -0
  172. django_cfg/core/generation/security_generators/__init__.py +0 -0
  173. django_cfg/core/generation/utility_generators/__init__.py +24 -0
  174. django_cfg/core/generation/utility_generators/email.py +58 -0
  175. django_cfg/core/generation/utility_generators/i18n.py +66 -0
  176. django_cfg/core/generation/utility_generators/limits.py +58 -0
  177. django_cfg/core/generation/utility_generators/logging.py +66 -0
  178. django_cfg/core/generation/utility_generators/security.py +101 -0
  179. django_cfg/core/generation/utils/__init__.py +0 -0
  180. django_cfg/core/generation/utils/helpers.py +32 -0
  181. django_cfg/core/integration/__init__.py +18 -25
  182. django_cfg/core/integration/display/startup.py +146 -133
  183. django_cfg/core/integration/url_integration.py +13 -2
  184. django_cfg/core/services/__init__.py +5 -0
  185. django_cfg/core/services/config_service.py +121 -0
  186. django_cfg/core/state/__init__.py +9 -0
  187. django_cfg/core/state/registry.py +84 -0
  188. django_cfg/core/types/__init__.py +15 -0
  189. django_cfg/core/types/aliases.py +15 -0
  190. django_cfg/core/types/enums.py +49 -0
  191. django_cfg/dashboard/DEBUG_README.md +105 -0
  192. django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
  193. django_cfg/dashboard/__init__.py +24 -0
  194. django_cfg/dashboard/components.py +308 -0
  195. django_cfg/dashboard/debug.py +176 -0
  196. django_cfg/dashboard/management/__init__.py +0 -0
  197. django_cfg/dashboard/management/commands/__init__.py +0 -0
  198. django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
  199. django_cfg/dashboard/sections/__init__.py +1 -0
  200. django_cfg/dashboard/sections/base.py +128 -0
  201. django_cfg/dashboard/sections/commands.py +32 -0
  202. django_cfg/dashboard/sections/overview.py +394 -0
  203. django_cfg/dashboard/sections/stats.py +48 -0
  204. django_cfg/dashboard/sections/system.py +73 -0
  205. django_cfg/management/commands/check_settings.py +6 -2
  206. django_cfg/management/commands/clear_constance.py +6 -1
  207. django_cfg/management/commands/create_token.py +5 -4
  208. django_cfg/management/commands/generate.py +5 -0
  209. django_cfg/management/commands/list_urls.py +7 -2
  210. django_cfg/management/commands/migrate_all.py +6 -2
  211. django_cfg/management/commands/migrator.py +6 -1
  212. django_cfg/management/commands/rundramatiq.py +6 -1
  213. django_cfg/management/commands/rundramatiq_simulator.py +11 -4
  214. django_cfg/management/commands/runserver_ngrok.py +9 -7
  215. django_cfg/management/commands/script.py +25 -21
  216. django_cfg/management/commands/show_config.py +6 -1
  217. django_cfg/management/commands/show_urls.py +8 -3
  218. django_cfg/management/commands/superuser.py +5 -4
  219. django_cfg/management/commands/task_clear.py +8 -3
  220. django_cfg/management/commands/task_status.py +8 -3
  221. django_cfg/management/commands/test_email.py +6 -1
  222. django_cfg/management/commands/test_telegram.py +6 -1
  223. django_cfg/management/commands/test_twilio.py +6 -1
  224. django_cfg/management/commands/tree.py +7 -4
  225. django_cfg/models/__init__.py +88 -3
  226. django_cfg/models/api/__init__.py +27 -0
  227. django_cfg/models/{api.py → api/config.py} +1 -1
  228. django_cfg/models/api/drf/__init__.py +21 -0
  229. django_cfg/models/api/drf/config.py +101 -0
  230. django_cfg/models/api/drf/redoc.py +31 -0
  231. django_cfg/models/api/drf/spectacular.py +129 -0
  232. django_cfg/models/api/drf/swagger.py +59 -0
  233. django_cfg/models/{api_keys.py → api/keys.py} +16 -6
  234. django_cfg/models/{limits.py → api/limits.py} +0 -1
  235. django_cfg/models/base/__init__.py +14 -0
  236. django_cfg/models/django/__init__.py +16 -0
  237. django_cfg/models/{constance.py → django/constance.py} +1 -1
  238. django_cfg/models/{environment.py → django/environment.py} +1 -1
  239. django_cfg/models/infrastructure/__init__.py +17 -0
  240. django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
  241. django_cfg/models/infrastructure/database/__init__.py +22 -0
  242. django_cfg/models/infrastructure/database/config.py +265 -0
  243. django_cfg/models/infrastructure/database/converters.py +91 -0
  244. django_cfg/models/infrastructure/database/parsers.py +96 -0
  245. django_cfg/models/infrastructure/database/routing.py +85 -0
  246. django_cfg/models/infrastructure/database/validators.py +170 -0
  247. django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
  248. django_cfg/models/{security.py → infrastructure/security.py} +2 -2
  249. django_cfg/models/ngrok/__init__.py +11 -0
  250. django_cfg/models/ngrok/auth.py +37 -0
  251. django_cfg/models/ngrok/config.py +77 -0
  252. django_cfg/models/ngrok/tunnel.py +35 -0
  253. django_cfg/models/payments/__init__.py +20 -0
  254. django_cfg/models/payments/api_keys.py +57 -0
  255. django_cfg/models/{payments.py → payments/config.py} +56 -154
  256. django_cfg/models/payments/providers/__init__.py +15 -0
  257. django_cfg/models/payments/providers/base.py +25 -0
  258. django_cfg/models/payments/providers/nowpayments.py +48 -0
  259. django_cfg/models/services/__init__.py +18 -0
  260. django_cfg/models/services/base.py +65 -0
  261. django_cfg/models/{email.py → services/email.py} +1 -1
  262. django_cfg/models/services/telegram.py +172 -0
  263. django_cfg/models/tasks/__init__.py +51 -0
  264. django_cfg/models/tasks/backends.py +250 -0
  265. django_cfg/models/tasks/config.py +314 -0
  266. django_cfg/models/tasks/utils.py +174 -0
  267. django_cfg/modules/base.py +18 -3
  268. django_cfg/modules/django_admin/decorators/actions.py +1 -1
  269. django_cfg/modules/django_admin/decorators/display.py +1 -1
  270. django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
  271. django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
  272. django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
  273. django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
  274. django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
  275. django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
  276. django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
  277. django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
  278. django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
  279. django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
  280. django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
  281. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
  282. django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
  283. django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
  284. django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
  285. django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
  286. django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
  287. django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
  288. django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
  289. django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
  290. django_cfg/modules/django_drf_theme/README.md +207 -0
  291. django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
  292. django_cfg/modules/django_drf_theme/__init__.py +23 -0
  293. django_cfg/modules/django_drf_theme/apps.py +15 -0
  294. django_cfg/modules/django_drf_theme/renderers.py +58 -0
  295. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
  296. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
  297. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
  298. django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
  299. django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
  300. django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
  301. django_cfg/modules/django_email/__init__.py +14 -0
  302. django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
  303. django_cfg/modules/django_email/utils.py +40 -0
  304. django_cfg/modules/django_health/__init__.py +9 -0
  305. django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
  306. django_cfg/modules/django_llm/llm/client.py +155 -550
  307. django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
  308. django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
  309. django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
  310. django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
  311. django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
  312. django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
  313. django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
  314. django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
  315. django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
  316. django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
  317. django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
  318. django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
  319. django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
  320. django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
  321. django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
  322. django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
  323. django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
  324. django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
  325. django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
  326. django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
  327. django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
  328. django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
  329. django_cfg/modules/django_llm/translator/translator.py +150 -603
  330. django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
  331. django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
  332. django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
  333. django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
  334. django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
  335. django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
  336. django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
  337. django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
  338. django_cfg/modules/django_logging/__init__.py +14 -0
  339. django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
  340. django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
  341. django_cfg/modules/django_ngrok/__init__.py +39 -0
  342. django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
  343. django_cfg/modules/django_rpc_old/POETRY.md +344 -0
  344. django_cfg/modules/django_rpc_old/README.md +397 -0
  345. django_cfg/modules/django_rpc_old/TESTING.md +358 -0
  346. django_cfg/modules/django_rpc_old/__init__.py +39 -0
  347. django_cfg/modules/django_rpc_old/client.py +531 -0
  348. django_cfg/modules/django_rpc_old/config.py +279 -0
  349. django_cfg/modules/django_rpc_old/exceptions.py +172 -0
  350. django_cfg/modules/django_tailwind/README.md +478 -0
  351. django_cfg/modules/django_tailwind/__init__.py +7 -0
  352. django_cfg/modules/django_tailwind/apps.py +10 -0
  353. django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
  354. django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
  355. django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
  356. django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
  357. django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
  358. django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
  359. django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
  360. django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
  361. django_cfg/modules/django_tasks/__init__.py +29 -0
  362. django_cfg/modules/django_tasks/factory.py +127 -0
  363. django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
  364. django_cfg/modules/django_tasks/settings.py +107 -0
  365. django_cfg/modules/django_telegram/__init__.py +29 -0
  366. django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
  367. django_cfg/modules/django_telegram/utils.py +62 -0
  368. django_cfg/modules/django_twilio/__init__.py +54 -107
  369. django_cfg/modules/django_twilio/_imports.py +30 -0
  370. django_cfg/modules/django_twilio/base.py +192 -0
  371. django_cfg/modules/django_twilio/email_otp.py +227 -0
  372. django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
  373. django_cfg/modules/django_twilio/simple_service.py +1 -2
  374. django_cfg/modules/django_twilio/sms.py +94 -0
  375. django_cfg/modules/django_twilio/twilio_service.py +2 -3
  376. django_cfg/modules/django_twilio/unified.py +310 -0
  377. django_cfg/modules/django_twilio/utils.py +190 -0
  378. django_cfg/modules/django_twilio/whatsapp.py +137 -0
  379. django_cfg/modules/django_unfold/callbacks/base.py +198 -7
  380. django_cfg/modules/django_unfold/callbacks/main.py +102 -10
  381. django_cfg/modules/django_unfold/dashboard.py +65 -43
  382. django_cfg/modules/django_unfold/models/config.py +13 -12
  383. django_cfg/modules/django_unfold/models/navigation.py +8 -3
  384. django_cfg/modules/django_unfold/models/tabs.py +2 -2
  385. django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
  386. django_cfg/registry/core.py +24 -26
  387. django_cfg/registry/modules.py +5 -2
  388. django_cfg/registry/services.py +20 -3
  389. django_cfg/registry/third_party.py +8 -8
  390. django_cfg/static/admin/css/dashboard.css +260 -0
  391. django_cfg/static/admin/js/commands.js +171 -0
  392. django_cfg/static/admin/js/dashboard.js +126 -0
  393. django_cfg/templates/admin/components/management_commands.js +375 -0
  394. django_cfg/templates/admin/components/progress_bar.html +18 -23
  395. django_cfg/templates/admin/index.html +48 -20
  396. django_cfg/templates/admin/index_new.html +106 -0
  397. django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
  398. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
  399. django_cfg/templates/admin/sections/commands_section.html +626 -0
  400. django_cfg/templates/admin/sections/overview_section.html +112 -0
  401. django_cfg/templates/admin/sections/stats_section.html +35 -0
  402. django_cfg/templates/admin/sections/system_section.html +99 -0
  403. django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
  404. django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
  405. django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
  406. django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
  407. django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
  408. django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
  409. django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
  410. django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
  411. django_cfg/templatetags/django_cfg.py +7 -1
  412. django_cfg/utils/smart_defaults.py +4 -4
  413. django_cfg-1.4.0.dist-info/METADATA +920 -0
  414. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
  415. django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
  416. django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
  417. django_cfg/core/generation.py +0 -621
  418. django_cfg/management/commands/validate_config.py +0 -189
  419. django_cfg/models/database.py +0 -480
  420. django_cfg/models/drf.py +0 -272
  421. django_cfg/models/ngrok.py +0 -122
  422. django_cfg/models/services.py +0 -440
  423. django_cfg/models/tasks.py +0 -550
  424. django_cfg/modules/django_twilio/service.py +0 -942
  425. django_cfg/template_archive/django_sample.zip +0 -0
  426. django_cfg/templates/rest_framework/api.html +0 -12
  427. django_cfg/utils/toolkit.py +0 -703
  428. django_cfg-1.3.11.dist-info/METADATA +0 -1029
  429. /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
  430. /django_cfg/core/{environment.py → environment/detector.py} +0 -0
  431. /django_cfg/models/{cors.py → api/cors.py} +0 -0
  432. /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
  433. /django_cfg/models/{base.py → base/config.py} +0 -0
  434. /django_cfg/models/{cfg.py → base/module.py} +0 -0
  435. /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
  436. /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
  437. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
  438. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
  439. {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,652 @@
1
+ """
2
+ Core DjangoConfig Pydantic model.
3
+
4
+ This module contains ONLY the data model definition:
5
+ - Field definitions with types and defaults
6
+ - Field validators
7
+ - Simple properties
8
+ - NO business logic (moved to builders and services)
9
+
10
+ Total size: ~350 lines (down from 903 in original config.py)
11
+ """
12
+
13
+ from typing import Dict, List, Optional, Any
14
+ from pathlib import Path
15
+ from pydantic import BaseModel, Field, field_validator, model_validator, PrivateAttr
16
+
17
+ from ..types.enums import EnvironmentMode, StartupInfoMode
18
+ from ..exceptions import ConfigurationError, ValidationError
19
+ from ...models import (
20
+ DatabaseConfig,
21
+ CacheConfig,
22
+ EmailConfig,
23
+ TelegramConfig,
24
+ UnfoldConfig,
25
+ DRFConfig,
26
+ SpectacularConfig,
27
+ LimitsConfig,
28
+ ApiKeys,
29
+ )
30
+ from ...models.tasks import TaskConfig
31
+ from ...models.payments import PaymentsConfig
32
+ from ...models.ngrok import NgrokConfig
33
+ from ...modules.django_cfg_rpc_client.config import DjangoCfgRPCConfig
34
+
35
+
36
+ class DjangoConfig(BaseModel):
37
+ """
38
+ Base configuration class for Django projects.
39
+
40
+ This is a pure data model - all business logic is in separate classes:
41
+ - Apps list generation → InstalledAppsBuilder
42
+ - Middleware generation → MiddlewareBuilder
43
+ - Security settings → SecurityBuilder
44
+ - Settings generation → SettingsGenerator
45
+
46
+ Key Features:
47
+ - 100% type safety through Pydantic v2
48
+ - Environment-aware smart defaults
49
+ - Comprehensive validation
50
+ - Zero raw dictionary usage
51
+
52
+ Example:
53
+ ```python
54
+ class MyProjectConfig(DjangoConfig):
55
+ project_name: str = "My Project"
56
+ databases: Dict[str, DatabaseConfig] = {
57
+ "default": DatabaseConfig(
58
+ engine="django.db.backends.postgresql",
59
+ name="${DATABASE_URL:mydb}",
60
+ )
61
+ }
62
+
63
+ config = MyProjectConfig()
64
+ settings = config.get_all_settings()
65
+ ```
66
+ """
67
+
68
+ model_config = {
69
+ "validate_assignment": True,
70
+ "extra": "forbid", # Forbid arbitrary fields for type safety
71
+ "env_prefix": "DJANGO_",
72
+ "populate_by_name": True,
73
+ "validate_default": True,
74
+ "str_strip_whitespace": True,
75
+ }
76
+
77
+ # === Environment Configuration ===
78
+ env_mode: EnvironmentMode = Field(
79
+ default=EnvironmentMode.PRODUCTION,
80
+ description="Environment mode: development, production, or test",
81
+ )
82
+
83
+ # === Project Information ===
84
+ project_name: str = Field(
85
+ ...,
86
+ description="Human-readable project name",
87
+ min_length=1,
88
+ max_length=100,
89
+ )
90
+
91
+ project_logo: str = Field(
92
+ default="",
93
+ description="Project logo URL",
94
+ )
95
+
96
+ project_version: str = Field(
97
+ default="1.0.0",
98
+ description="Project version",
99
+ pattern=r"^\d+\.\d+\.\d+.*$",
100
+ )
101
+
102
+ project_description: str = Field(
103
+ default="",
104
+ description="Project description",
105
+ max_length=500,
106
+ )
107
+
108
+ # === Django CFG Features ===
109
+ startup_info_mode: StartupInfoMode = Field(
110
+ default=StartupInfoMode.FULL,
111
+ description="Startup information display mode: none (minimal), short (essential), full (complete)",
112
+ )
113
+
114
+ enable_support: bool = Field(
115
+ default=True,
116
+ description="Enable django-cfg Support application (tickets, messages, chat interface)",
117
+ )
118
+
119
+ enable_accounts: bool = Field(
120
+ default=False,
121
+ description="Enable django-cfg Accounts application (advanced user management, OTP, profiles, activity tracking)",
122
+ )
123
+
124
+ enable_newsletter: bool = Field(
125
+ default=False,
126
+ description="Enable django-cfg Newsletter application (email campaigns, subscriptions, bulk emails)",
127
+ )
128
+
129
+ enable_leads: bool = Field(
130
+ default=False,
131
+ description="Enable django-cfg Leads application (lead collection, contact forms, CRM integration)",
132
+ )
133
+
134
+ enable_knowbase: bool = Field(
135
+ default=False,
136
+ description="Enable django-cfg Knowledge Base application (documents, AI chat, embeddings, search)",
137
+ )
138
+
139
+ enable_agents: bool = Field(
140
+ default=False,
141
+ description="Enable django-cfg AI Agents application (agent definitions, executions, workflows, tools)",
142
+ )
143
+
144
+ enable_maintenance: bool = Field(
145
+ default=False,
146
+ description="Enable django-cfg Maintenance application (multi-site maintenance mode with Cloudflare)",
147
+ )
148
+
149
+ # === Payment System Configuration ===
150
+ payments: Optional[PaymentsConfig] = Field(
151
+ default=None,
152
+ description="Universal payment system configuration (providers, subscriptions, API keys, billing)",
153
+ )
154
+
155
+ # === URLs ===
156
+ site_url: str = Field(
157
+ default="http://localhost:3000",
158
+ description="Frontend site URL",
159
+ )
160
+
161
+ api_url: str = Field(
162
+ default="http://localhost:8000",
163
+ description="Backend API URL",
164
+ )
165
+
166
+ ticket_url: str = Field(
167
+ default="{site_url}/support/ticket/{uuid}",
168
+ description="Support ticket URL template. Use {site_url} and {uuid} placeholders",
169
+ )
170
+
171
+ otp_url: str = Field(
172
+ default="{site_url}/auth/otp/{code}",
173
+ description="OTP verification URL template. Use {site_url} and {code} placeholders",
174
+ )
175
+
176
+ # === Core Django Settings ===
177
+ secret_key: str = Field(
178
+ ...,
179
+ description="Django SECRET_KEY",
180
+ min_length=50,
181
+ repr=False, # Don't show in repr for security
182
+ )
183
+
184
+ debug: bool = Field(
185
+ default=False,
186
+ description="Django DEBUG setting",
187
+ )
188
+
189
+ # === URL Configuration ===
190
+ root_urlconf: Optional[str] = Field(
191
+ default=None,
192
+ description="Django ROOT_URLCONF setting",
193
+ )
194
+
195
+ wsgi_application: Optional[str] = Field(
196
+ default=None,
197
+ description="Django WSGI_APPLICATION setting",
198
+ )
199
+
200
+ # === Custom User Model ===
201
+ auth_user_model: Optional[str] = Field(
202
+ default=None,
203
+ description="Custom user model (AUTH_USER_MODEL). If None and enable_accounts=True, uses 'django_cfg.apps.accounts.CustomUser'",
204
+ pattern=r"^[a-zA-Z_][a-zA-Z0-9_]*\.[a-zA-Z_][a-zA-Z0-9_]*$",
205
+ )
206
+
207
+ # === Project Applications ===
208
+ project_apps: List[str] = Field(
209
+ default_factory=list,
210
+ description="List of project-specific Django apps",
211
+ )
212
+
213
+ # === Database Configuration ===
214
+ databases: Dict[str, DatabaseConfig] = Field(
215
+ default_factory=dict,
216
+ description="Database connections",
217
+ )
218
+
219
+ # === Cache Configuration ===
220
+ cache_default: Optional[CacheConfig] = Field(
221
+ default=None,
222
+ description="Default cache backend",
223
+ )
224
+
225
+ cache_sessions: Optional[CacheConfig] = Field(
226
+ default=None,
227
+ description="Sessions cache backend",
228
+ )
229
+
230
+ # === Security Configuration ===
231
+ security_domains: List[str] = Field(
232
+ default_factory=list,
233
+ description="Domains for automatic security configuration (CORS, SSL, etc.)",
234
+ )
235
+
236
+ ssl_redirect: Optional[bool] = Field(
237
+ default=None,
238
+ description="Force SSL redirect on/off (None = auto based on domains and environment)",
239
+ )
240
+
241
+ # === CORS Configuration ===
242
+ cors_allow_headers: List[str] = Field(
243
+ default_factory=lambda: [
244
+ "accept",
245
+ "accept-encoding",
246
+ "authorization",
247
+ "content-type",
248
+ "dnt",
249
+ "origin",
250
+ "user-agent",
251
+ "x-csrftoken",
252
+ "x-requested-with",
253
+ "x-api-key",
254
+ "x-api-token",
255
+ ],
256
+ description="CORS allowed headers with common defaults for API usage",
257
+ )
258
+
259
+ # === Services Configuration ===
260
+ email: Optional[EmailConfig] = Field(
261
+ default=None,
262
+ description="Email service configuration",
263
+ )
264
+
265
+ telegram: Optional[TelegramConfig] = Field(
266
+ default=None,
267
+ description="Telegram service configuration",
268
+ )
269
+
270
+ ngrok: Optional[NgrokConfig] = Field(
271
+ default=None,
272
+ description="Ngrok tunneling service configuration (for development/webhooks)",
273
+ )
274
+
275
+ # === Admin Interface Configuration ===
276
+ unfold: Optional[UnfoldConfig] = Field(
277
+ default=None,
278
+ description="Unfold admin interface configuration",
279
+ )
280
+
281
+ # === Frontend Configuration (Tailwind CSS) ===
282
+ tailwind_app_name: str = Field(
283
+ default="theme",
284
+ description="Name of the Tailwind theme app (django-tailwind integration)",
285
+ min_length=1,
286
+ max_length=50,
287
+ )
288
+
289
+ tailwind_version: int = Field(
290
+ default=4,
291
+ description="Tailwind CSS version (3 or 4)",
292
+ ge=3,
293
+ le=4,
294
+ )
295
+
296
+ enable_drf_tailwind: bool = Field(
297
+ default=True,
298
+ description="Enable modern Tailwind CSS theme for Django REST Framework Browsable API",
299
+ )
300
+
301
+ # === Background Task Processing ===
302
+ tasks: Optional[TaskConfig] = Field(
303
+ default=None,
304
+ description="Background task processing configuration (Dramatiq)",
305
+ )
306
+
307
+ # === RPC Client Configuration ===
308
+ django_cfg_rpc: Optional[DjangoCfgRPCConfig] = Field(
309
+ default=None,
310
+ description="Django-CFG RPC Client configuration (WebSocket RPC communication)",
311
+ )
312
+
313
+ # === API Configuration ===
314
+ drf: Optional[DRFConfig] = Field(
315
+ default=None,
316
+ description="Extended Django REST Framework configuration (supplements Revolution)",
317
+ )
318
+
319
+ spectacular: Optional[SpectacularConfig] = Field(
320
+ default=None,
321
+ description="Extended DRF Spectacular configuration (supplements Revolution)",
322
+ )
323
+
324
+ # === Limits Configuration ===
325
+ limits: Optional[LimitsConfig] = Field(
326
+ default=None,
327
+ description="Application limits configuration (file uploads, requests, etc.)",
328
+ )
329
+
330
+ # === API Keys Configuration ===
331
+ api_keys: Optional[ApiKeys] = Field(
332
+ default=None,
333
+ description="API keys for external services (OpenAI, OpenRouter, etc.)",
334
+ )
335
+
336
+ # === Middleware Configuration ===
337
+ custom_middleware: List[str] = Field(
338
+ default_factory=list,
339
+ description="Custom middleware classes (standard middleware added automatically)",
340
+ )
341
+
342
+ # === Internal State (Private) ===
343
+ _base_dir: Optional[Path] = PrivateAttr(default=None)
344
+ _django_settings: Optional[Dict[str, Any]] = PrivateAttr(default=None)
345
+ _service: Optional[Any] = PrivateAttr(default=None) # ConfigService instance
346
+
347
+ # === Field Validators ===
348
+
349
+ @field_validator("project_name")
350
+ @classmethod
351
+ def validate_project_name(cls, v: str) -> str:
352
+ """Validate project name format."""
353
+ if not v.replace(" ", "").replace("-", "").replace("_", "").isalnum():
354
+ raise ValueError(
355
+ "Project name must contain only alphanumeric characters, "
356
+ "spaces, hyphens, and underscores"
357
+ )
358
+ return v
359
+
360
+ @field_validator("secret_key")
361
+ @classmethod
362
+ def validate_secret_key(cls, v: str) -> str:
363
+ """Validate Django SECRET_KEY."""
364
+ if len(v) < 50:
365
+ raise ValueError("SECRET_KEY must be at least 50 characters long")
366
+
367
+ # Check for common insecure patterns (warning only, not error)
368
+ insecure_patterns = [
369
+ "django-insecure",
370
+ "change-me",
371
+ "your-secret-key",
372
+ "dev-key",
373
+ "test-key",
374
+ ]
375
+
376
+ v_lower = v.lower()
377
+ for pattern in insecure_patterns:
378
+ if pattern in v_lower:
379
+ # This is a warning, not an error - allow for development
380
+ break
381
+
382
+ return v
383
+
384
+ @field_validator("project_apps")
385
+ @classmethod
386
+ def validate_project_apps(cls, v: List[str]) -> List[str]:
387
+ """Validate project apps list."""
388
+ for app in v:
389
+ if not app:
390
+ raise ValueError("Empty app name in project_apps")
391
+
392
+ # Basic app name validation
393
+ if not app.replace(".", "").replace("_", "").isalnum():
394
+ raise ValueError(
395
+ f"Invalid app name '{app}': must contain only letters, "
396
+ f"numbers, dots, and underscores"
397
+ )
398
+
399
+ return v
400
+
401
+ @model_validator(mode="after")
402
+ def validate_configuration_consistency(self) -> "DjangoConfig":
403
+ """Validate overall configuration consistency."""
404
+ # Ensure at least one database is configured
405
+ if not self.databases:
406
+ raise ConfigurationError(
407
+ "At least one database must be configured",
408
+ suggestions=["Add a 'default' database to the databases field"],
409
+ )
410
+
411
+ # Ensure 'default' database exists
412
+ if "default" not in self.databases:
413
+ raise ConfigurationError(
414
+ "'default' database is required",
415
+ context={"available_databases": list(self.databases.keys())},
416
+ suggestions=["Add a database with alias 'default'"],
417
+ )
418
+
419
+ # Validate database routing consistency
420
+ referenced_databases = set()
421
+ for alias, db_config in self.databases.items():
422
+ if db_config.migrate_to:
423
+ referenced_databases.add(db_config.migrate_to)
424
+
425
+ missing_databases = referenced_databases - set(self.databases.keys())
426
+ if missing_databases:
427
+ raise ConfigurationError(
428
+ f"Database routing references non-existent databases: {missing_databases}",
429
+ context={"available_databases": list(self.databases.keys())},
430
+ suggestions=[f"Add database configurations for: {', '.join(missing_databases)}"],
431
+ )
432
+
433
+ return self
434
+
435
+ def model_post_init(self, __context: Any) -> None:
436
+ """
437
+ Initialize configuration after Pydantic validation.
438
+
439
+ Auto-detects environment from DJANGO_ENV, ENVIRONMENT, or ENV variables
440
+ if env_mode was not explicitly set.
441
+ """
442
+ import os
443
+
444
+ # Only auto-detect if using default value (PRODUCTION)
445
+ # This allows explicit setting to override auto-detection
446
+ if self.env_mode == EnvironmentMode.PRODUCTION:
447
+ # Check if any env variable was explicitly set
448
+ env_vars = ['DJANGO_ENV', 'ENVIRONMENT', 'ENV']
449
+ for env_var in env_vars:
450
+ env_value = os.environ.get(env_var)
451
+ if env_value:
452
+ # Try to map to EnvironmentMode
453
+ env_normalized = env_value.lower().strip()
454
+ if env_normalized in ('dev', 'devel', 'develop', 'development', 'local'):
455
+ object.__setattr__(self, 'env_mode', EnvironmentMode.DEVELOPMENT)
456
+ break
457
+ elif env_normalized in ('prod', 'production'):
458
+ object.__setattr__(self, 'env_mode', EnvironmentMode.PRODUCTION)
459
+ break
460
+ elif env_normalized in ('test', 'testing'):
461
+ object.__setattr__(self, 'env_mode', EnvironmentMode.TEST)
462
+ break
463
+
464
+ # === Simple Properties (NO business logic!) ===
465
+
466
+ @property
467
+ def is_development(self) -> bool:
468
+ """Check if running in development mode."""
469
+ return self.env_mode == EnvironmentMode.DEVELOPMENT
470
+
471
+ @property
472
+ def is_production(self) -> bool:
473
+ """Check if running in production mode."""
474
+ return self.env_mode == EnvironmentMode.PRODUCTION
475
+
476
+ @property
477
+ def is_test(self) -> bool:
478
+ """Check if running in test mode."""
479
+ return self.env_mode == EnvironmentMode.TEST
480
+
481
+ @property
482
+ def base_dir(self) -> Path:
483
+ """
484
+ Get the base directory of the project.
485
+
486
+ Looks for manage.py in current directory and parents.
487
+ Falls back to current working directory if not found.
488
+ """
489
+ if self._base_dir is None:
490
+ import os
491
+
492
+ # Start from current working directory
493
+ current_path = Path(os.path.dirname(os.path.abspath(__file__)))
494
+
495
+ # Look for manage.py in current directory and parents
496
+ for path in [current_path] + list(current_path.parents):
497
+ manage_py = path / "manage.py"
498
+ if manage_py.exists() and manage_py.is_file():
499
+ self._base_dir = path
500
+ break
501
+
502
+ # If still not found, use current directory
503
+ if self._base_dir is None:
504
+ self._base_dir = Path.cwd()
505
+
506
+ return self._base_dir
507
+
508
+ # === Facade Methods (delegate to service) ===
509
+
510
+ @property
511
+ def service(self) -> Any:
512
+ """Lazy-load config service."""
513
+ if self._service is None:
514
+ from ..services.config_service import ConfigService
515
+ self._service = ConfigService(self)
516
+ return self._service
517
+
518
+ def get_installed_apps(self) -> List[str]:
519
+ """Get complete INSTALLED_APPS list (delegates to service)."""
520
+ return self.service.get_installed_apps()
521
+
522
+ def get_middleware(self) -> List[str]:
523
+ """Get complete MIDDLEWARE list (delegates to service)."""
524
+ return self.service.get_middleware()
525
+
526
+ def get_allowed_hosts(self) -> List[str]:
527
+ """Get ALLOWED_HOSTS (delegates to service)."""
528
+ return self.service.get_allowed_hosts()
529
+
530
+ def get_all_settings(self) -> Dict[str, Any]:
531
+ """
532
+ Generate complete Django settings dictionary.
533
+
534
+ Delegates to SettingsGenerator for actual generation.
535
+
536
+ Returns:
537
+ Complete Django settings ready for use
538
+
539
+ Raises:
540
+ ConfigurationError: If settings generation fails
541
+ """
542
+ # Set as current config
543
+ from ..state.registry import set_current_config
544
+ set_current_config(self)
545
+
546
+ if self._django_settings is None:
547
+ from ..generation import SettingsGenerator
548
+
549
+ try:
550
+ self._django_settings = SettingsGenerator.generate(self)
551
+ except Exception as e:
552
+ raise ConfigurationError(
553
+ f"Failed to generate Django settings: {e}",
554
+ context={"config": self.model_dump(exclude={"_django_settings"})},
555
+ ) from e
556
+
557
+ return self._django_settings
558
+
559
+ def get_ticket_url(self, ticket_uuid: str) -> str:
560
+ """
561
+ Generate ticket URL using the configured template.
562
+
563
+ Args:
564
+ ticket_uuid: UUID of the support ticket
565
+
566
+ Returns:
567
+ Complete URL to the ticket
568
+ """
569
+ return self.ticket_url.format(
570
+ site_url=self.site_url,
571
+ uuid=ticket_uuid,
572
+ )
573
+
574
+ def get_otp_url(self, otp_code: str) -> str:
575
+ """
576
+ Generate OTP verification URL using the configured template.
577
+
578
+ Args:
579
+ otp_code: OTP verification code
580
+
581
+ Returns:
582
+ Complete URL to the OTP verification page
583
+ """
584
+ return self.otp_url.format(
585
+ site_url=self.site_url,
586
+ code=otp_code,
587
+ )
588
+
589
+ def invalidate_cache(self) -> None:
590
+ """
591
+ Invalidate cached Django settings.
592
+
593
+ Forces regeneration of settings on next call to get_all_settings().
594
+ Useful when configuration has changed and settings need to be regenerated.
595
+
596
+ Example:
597
+ >>> config.invalidate_cache()
598
+ >>> new_settings = config.get_all_settings() # Will regenerate
599
+ """
600
+ self._django_settings = None
601
+
602
+ def model_dump_for_django(self, **kwargs) -> Dict[str, Any]:
603
+ """
604
+ Serialize model data in Django-compatible format.
605
+
606
+ This method provides a dictionary representation suitable for Django settings,
607
+ with proper serialization of nested Pydantic models.
608
+
609
+ Args:
610
+ **kwargs: Additional arguments passed to model_dump()
611
+
612
+ Returns:
613
+ Dictionary with serialized configuration data
614
+
615
+ Example:
616
+ >>> config = DjangoConfig(project_name="My Project", ...)
617
+ >>> dump = config.model_dump_for_django()
618
+ >>> dump["project_name"]
619
+ 'My Project'
620
+ """
621
+ return self.model_dump(
622
+ mode="python",
623
+ exclude_none=False,
624
+ by_alias=False,
625
+ **kwargs
626
+ )
627
+
628
+ def should_enable_tasks(self) -> bool:
629
+ """
630
+ Determine if background tasks should be enabled.
631
+
632
+ Tasks are enabled if:
633
+ 1. Explicitly configured via tasks field
634
+ 2. Knowledge base is enabled (requires background processing)
635
+ 3. Agents are enabled (requires background processing)
636
+
637
+ Returns:
638
+ True if tasks should be enabled, False otherwise
639
+ """
640
+ # Check if explicitly configured
641
+ if hasattr(self, 'tasks') and self.tasks and self.tasks.enabled:
642
+ return True
643
+
644
+ # Check if features that require tasks are enabled
645
+ if self.enable_knowbase or self.enable_agents:
646
+ return True
647
+
648
+ return False
649
+
650
+
651
+ # Export main class
652
+ __all__ = ["DjangoConfig"]
@@ -0,0 +1,11 @@
1
+ """Builders for Django settings generation."""
2
+
3
+ from .apps_builder import InstalledAppsBuilder
4
+ from .middleware_builder import MiddlewareBuilder
5
+ from .security_builder import SecurityBuilder
6
+
7
+ __all__ = [
8
+ "InstalledAppsBuilder",
9
+ "MiddlewareBuilder",
10
+ "SecurityBuilder",
11
+ ]