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,127 @@
1
+ """
2
+ Task service factory and utilities.
3
+
4
+ Provides singleton instance and utility functions.
5
+ """
6
+
7
+ from typing import Optional, Dict, Any
8
+ import logging
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Lazy import to avoid circular dependency
13
+ _task_service_instance = None
14
+
15
+
16
+ def get_task_service():
17
+ """Get the global task service instance."""
18
+ global _task_service_instance
19
+
20
+ if _task_service_instance is None:
21
+ from .service import DjangoTasks
22
+ _task_service_instance = DjangoTasks()
23
+
24
+ return _task_service_instance
25
+
26
+
27
+ def reset_task_service():
28
+ """Reset the global task service instance (useful for testing)."""
29
+ global _task_service_instance
30
+ _task_service_instance = None
31
+
32
+
33
+ def is_task_system_available() -> bool:
34
+ """Check if task system is available and properly configured."""
35
+ try:
36
+ service = get_task_service()
37
+ return service.is_enabled()
38
+ except Exception:
39
+ return False
40
+
41
+
42
+ def get_task_health() -> Dict[str, Any]:
43
+ """Get task system health status."""
44
+ try:
45
+ service = get_task_service()
46
+ return service.get_health_status()
47
+ except Exception as e:
48
+ return {
49
+ "enabled": False,
50
+ "error": str(e),
51
+ "redis_connection": False,
52
+ "configuration_valid": False,
53
+ }
54
+
55
+
56
+ def initialize_task_system():
57
+ """
58
+ Initialize the task system during Django app startup.
59
+ This function is called from Django AppConfig.ready() method.
60
+ """
61
+ try:
62
+ service = get_task_service()
63
+
64
+ # Force config reload to ensure we have fresh config
65
+ service._config = None
66
+ config = service.config
67
+
68
+ if config and config.enabled:
69
+ logger.info("🔧 Initializing Django-CFG task system...")
70
+
71
+ # Set up Dramatiq broker from Django settings
72
+ try:
73
+ import dramatiq
74
+ from django.conf import settings
75
+
76
+ # Django-dramatiq automatically configures the broker from DRAMATIQ_BROKER setting
77
+ if hasattr(settings, 'DRAMATIQ_BROKER'):
78
+ # Configure broker with middleware
79
+ broker_config = settings.DRAMATIQ_BROKER
80
+ middleware_list = getattr(settings, 'DRAMATIQ_MIDDLEWARE', [])
81
+
82
+ # Import and instantiate middleware
83
+ middleware_instances = []
84
+ for middleware_path in middleware_list:
85
+ try:
86
+ module_path, class_name = middleware_path.rsplit('.', 1)
87
+ module = __import__(module_path, fromlist=[class_name])
88
+ middleware_class = getattr(module, class_name)
89
+ middleware_instances.append(middleware_class())
90
+ except Exception as e:
91
+ logger.warning(f"Failed to load middleware {middleware_path}: {e}")
92
+
93
+ # Create broker with middleware
94
+ broker_class_path = broker_config['BROKER']
95
+ module_path, class_name = broker_class_path.rsplit('.', 1)
96
+ module = __import__(module_path, fromlist=[class_name])
97
+ broker_class = getattr(module, class_name)
98
+
99
+ broker_options = broker_config.get('OPTIONS', {})
100
+ broker = broker_class(middleware=middleware_instances, **broker_options)
101
+
102
+ # Set as default broker
103
+ dramatiq.set_broker(broker)
104
+
105
+ logger.debug(f"✅ Dramatiq broker configured with {len(middleware_instances)} middleware")
106
+ else:
107
+ logger.warning("DRAMATIQ_BROKER not found in Django settings")
108
+
109
+ except Exception as e:
110
+ logger.warning(f"Failed to configure Dramatiq: {e}")
111
+
112
+ logger.info("✅ Task system initialized successfully")
113
+ logger.info("💡 To start workers, run: python manage.py rundramatiq")
114
+ else:
115
+ logger.debug(f"Task system not enabled (config: {config}), skipping initialization")
116
+
117
+ except Exception as e:
118
+ logger.error(f"Failed to initialize task system: {e}")
119
+
120
+
121
+ __all__ = [
122
+ "get_task_service",
123
+ "reset_task_service",
124
+ "is_task_system_available",
125
+ "get_task_health",
126
+ "initialize_task_system",
127
+ ]
@@ -1,19 +1,18 @@
1
1
  """
2
- Django-CFG Task Service Module.
2
+ Django-CFG Task Service.
3
3
 
4
- Simplified and focused task service for Dramatiq integration.
5
- Provides essential functionality without unnecessary complexity.
4
+ Main DjangoTasks class for Dramatiq integration.
6
5
  """
7
6
 
8
7
  from typing import Optional, Dict, Any, List
9
8
  import logging
10
9
  from urllib.parse import urlparse
11
10
 
12
- from . import BaseCfgModule
11
+ from ..base import BaseCfgModule
13
12
  from django_cfg.models.tasks import TaskConfig, validate_task_config
14
- from django_cfg.models.constance import ConstanceField
13
+ from django_cfg.models.django.constance import ConstanceField
15
14
 
16
- # Django imports (will be available when Django is configured)
15
+ # Django imports
17
16
  try:
18
17
  from django.apps import apps
19
18
  except ImportError:
@@ -36,25 +35,24 @@ logger = logging.getLogger(__name__)
36
35
  class DjangoTasks(BaseCfgModule):
37
36
  """
38
37
  Simplified Django-CFG task service.
39
-
38
+
40
39
  Focuses on essential functionality:
41
40
  - Configuration management
42
41
  - Task discovery
43
42
  - Health checks
44
43
  - Constance integration
45
44
  """
46
-
45
+
47
46
  def __init__(self):
48
47
  super().__init__()
49
48
  self._config: Optional[TaskConfig] = None
50
49
  self._redis_url: Optional[str] = None
51
-
50
+
52
51
  @property
53
52
  def config(self) -> Optional[TaskConfig]:
54
53
  """Get task configuration (lazy-loaded)."""
55
54
  if self._config is None:
56
55
  try:
57
- # Get config from django-cfg
58
56
  django_config = self.get_config()
59
57
  if django_config and hasattr(django_config, 'tasks'):
60
58
  self._config = django_config.tasks
@@ -70,38 +68,36 @@ class DjangoTasks(BaseCfgModule):
70
68
  logger.debug("Could not import api.config")
71
69
  except Exception as e:
72
70
  logger.warning(f"Failed to get task config: {e}")
73
-
71
+
74
72
  return self._config
75
-
73
+
76
74
  def is_enabled(self) -> bool:
77
75
  """Check if task system is enabled and properly configured."""
78
76
  if not self.config or not self.config.enabled:
79
77
  return False
80
-
81
- # Check if required dependencies are available
78
+
82
79
  if dramatiq is None:
83
80
  logger.warning("Dramatiq not available")
84
81
  return False
85
-
82
+
86
83
  return True
87
-
84
+
88
85
  def get_redis_url(self) -> Optional[str]:
89
86
  """Get Redis URL using the same logic as Dramatiq settings generation."""
90
87
  if self._redis_url is None:
91
- # Use BaseCfgModule to get config (same as generate_dramatiq_settings_from_config)
92
88
  config = self.get_config()
93
-
89
+
94
90
  if not config:
95
91
  raise RuntimeError("No Django-CFG configuration available")
96
-
97
- # Get Redis URL from cache config (same logic as generate_dramatiq_settings_from_config)
92
+
93
+ # Get Redis URL from cache config
98
94
  if hasattr(config, 'cache_default') and config.cache_default:
99
95
  self._redis_url = getattr(config.cache_default, 'redis_url', None)
100
96
  if self._redis_url:
101
97
  logger.debug(f"Got Redis URL from cache config: {self._redis_url}")
102
98
  return self._redis_url
103
-
104
- # If no cache_default, try to get from Django cache settings
99
+
100
+ # If no cache_default, try Django cache settings
105
101
  try:
106
102
  from django.conf import settings
107
103
  if hasattr(settings, 'CACHES') and 'default' in settings.CACHES:
@@ -113,8 +109,8 @@ class DjangoTasks(BaseCfgModule):
113
109
  return self._redis_url
114
110
  except Exception as e:
115
111
  logger.debug(f"Could not get Redis URL from Django settings: {e}")
116
-
117
- # Try to get from DRAMATIQ_BROKER settings
112
+
113
+ # Try DRAMATIQ_BROKER settings
118
114
  try:
119
115
  from django.conf import settings
120
116
  if hasattr(settings, 'DRAMATIQ_BROKER'):
@@ -126,22 +122,21 @@ class DjangoTasks(BaseCfgModule):
126
122
  return self._redis_url
127
123
  except Exception as e:
128
124
  logger.debug(f"Could not get Redis URL from DRAMATIQ_BROKER settings: {e}")
129
-
130
- # If still no Redis URL found, raise error (no fallbacks)
125
+
131
126
  raise RuntimeError("No Redis URL found in cache configuration, Django settings, or DRAMATIQ_BROKER")
132
-
127
+
133
128
  return self._redis_url
134
-
129
+
135
130
  def get_redis_client(self):
136
131
  """Get Redis client instance."""
137
132
  redis_url = self.get_redis_url()
138
133
  if not redis_url or redis is None:
139
134
  return None
140
-
135
+
141
136
  try:
142
137
  parsed = urlparse(redis_url)
143
-
144
- # Extract database from URL path, fallback to config or default
138
+
139
+ # Extract database from URL path
145
140
  db = 1 # Default
146
141
  if parsed.path and parsed.path != "/":
147
142
  try:
@@ -150,9 +145,9 @@ class DjangoTasks(BaseCfgModule):
150
145
  pass
151
146
  elif self.config and self.config.dramatiq:
152
147
  db = self.config.dramatiq.redis_db
153
-
148
+
154
149
  logger.debug(f"Using Redis DB: {db} from URL: {redis_url}")
155
-
150
+
156
151
  return redis.Redis(
157
152
  host=parsed.hostname or 'localhost',
158
153
  port=parsed.port or 6379,
@@ -163,49 +158,44 @@ class DjangoTasks(BaseCfgModule):
163
158
  except Exception as e:
164
159
  logger.error(f"Failed to create Redis client: {e}")
165
160
  return None
166
-
167
- def _get_current_timestamp(self) -> str:
168
- """Get current timestamp in ISO format."""
169
- from datetime import datetime
170
- return datetime.now().isoformat()
171
-
161
+
172
162
  def check_redis_connection(self) -> bool:
173
163
  """Check if Redis connection is available."""
174
164
  redis_client = self.get_redis_client()
175
165
  if not redis_client:
176
166
  return False
177
-
167
+
178
168
  try:
179
169
  redis_client.ping()
180
170
  return True
181
171
  except Exception as e:
182
172
  logger.error(f"Redis connection failed: {e}")
183
173
  return False
184
-
174
+
185
175
  def validate_configuration(self) -> bool:
186
176
  """Validate complete task system configuration."""
187
177
  if not self.config:
188
178
  logger.error("Task configuration not available")
189
179
  return False
190
-
180
+
191
181
  redis_url = self.get_redis_url()
192
182
  if not redis_url:
193
183
  logger.error("Redis URL not configured")
194
184
  return False
195
-
185
+
196
186
  return validate_task_config(self.config, redis_url)
197
-
187
+
198
188
  def discover_tasks(self) -> List[str]:
199
189
  """Discover task modules in Django apps."""
200
190
  if not self.config or not self.config.auto_discover_tasks:
201
191
  return []
202
-
192
+
203
193
  discovered = []
204
-
194
+
205
195
  if apps is None:
206
196
  logger.warning("Django apps not available")
207
197
  return []
208
-
198
+
209
199
  try:
210
200
  for app_config in apps.get_app_configs():
211
201
  for module_name in self.config.task_modules:
@@ -215,20 +205,19 @@ class DjangoTasks(BaseCfgModule):
215
205
  discovered.append(module_path)
216
206
  logger.debug(f"Discovered task module: {module_path}")
217
207
  except ImportError:
218
- # Module doesn't exist, which is fine
219
208
  pass
220
209
  except Exception as e:
221
210
  logger.warning(f"Error importing task module {module_path}: {e}")
222
211
  except Exception as e:
223
212
  logger.error(f"Task discovery failed: {e}")
224
-
213
+
225
214
  return discovered
226
-
215
+
227
216
  def get_constance_fields(self) -> List[ConstanceField]:
228
217
  """Get Constance fields for Dramatiq configuration."""
229
218
  if not self.is_enabled():
230
219
  return []
231
-
220
+
232
221
  fields = [
233
222
  ConstanceField(
234
223
  name="DRAMATIQ_WORKER_PROCESSES",
@@ -267,10 +256,10 @@ class DjangoTasks(BaseCfgModule):
267
256
  required=False,
268
257
  ),
269
258
  ]
270
-
259
+
271
260
  logger.debug(f"Generated {len(fields)} Constance fields for Dramatiq")
272
261
  return fields
273
-
262
+
274
263
  def get_health_status(self) -> Dict[str, Any]:
275
264
  """Get comprehensive health status of task system."""
276
265
  status = {
@@ -279,231 +268,13 @@ class DjangoTasks(BaseCfgModule):
279
268
  "configuration_valid": False,
280
269
  "discovered_modules": [],
281
270
  }
282
-
271
+
283
272
  if self.is_enabled():
284
273
  status["redis_connection"] = self.check_redis_connection()
285
274
  status["configuration_valid"] = self.validate_configuration()
286
275
  status["discovered_modules"] = self.discover_tasks()
287
-
288
- return status
289
-
290
-
291
- # === Service Factory ===
292
-
293
- _task_service_instance: Optional[DjangoTasks] = None
294
-
295
-
296
- def get_task_service() -> DjangoTasks:
297
- """Get the global task service instance."""
298
- global _task_service_instance
299
-
300
- if _task_service_instance is None:
301
- _task_service_instance = DjangoTasks()
302
-
303
- return _task_service_instance
304
-
305
-
306
- def reset_task_service():
307
- """Reset the global task service instance (useful for testing)."""
308
- global _task_service_instance
309
- _task_service_instance = None
310
-
311
-
312
- # === Utility Functions ===
313
-
314
- def is_task_system_available() -> bool:
315
- """Check if task system is available and properly configured."""
316
- try:
317
- service = get_task_service()
318
- return service.is_enabled()
319
- except Exception:
320
- return False
321
-
322
-
323
- def get_task_health() -> Dict[str, Any]:
324
- """Get task system health status."""
325
- try:
326
- service = get_task_service()
327
- return service.get_health_status()
328
- except Exception as e:
329
- return {
330
- "enabled": False,
331
- "error": str(e),
332
- "redis_connection": False,
333
- "configuration_valid": False,
334
- }
335
-
336
-
337
- def initialize_task_system():
338
- """
339
- Initialize the task system during Django app startup.
340
- This function is called from Django AppConfig.ready() method.
341
- """
342
- try:
343
- service = get_task_service()
344
-
345
- # Force config reload to ensure we have fresh config
346
- service._config = None
347
- config = service.config
348
-
349
- if config and config.enabled:
350
- logger.info("🔧 Initializing Django-CFG task system...")
351
-
352
- # Set up Dramatiq broker from Django settings
353
- try:
354
- import dramatiq
355
- from django.conf import settings
356
-
357
- # Django-dramatiq automatically configures the broker from DRAMATIQ_BROKER setting
358
- if hasattr(settings, 'DRAMATIQ_BROKER'):
359
- # Configure broker with middleware
360
- broker_config = settings.DRAMATIQ_BROKER
361
- middleware_list = getattr(settings, 'DRAMATIQ_MIDDLEWARE', [])
362
-
363
- # Import and instantiate middleware
364
- middleware_instances = []
365
- for middleware_path in middleware_list:
366
- try:
367
- module_path, class_name = middleware_path.rsplit('.', 1)
368
- module = __import__(module_path, fromlist=[class_name])
369
- middleware_class = getattr(module, class_name)
370
- middleware_instances.append(middleware_class())
371
- except Exception as e:
372
- logger.warning(f"Failed to load middleware {middleware_path}: {e}")
373
-
374
- # Create broker with middleware
375
- broker_class_path = broker_config['BROKER']
376
- module_path, class_name = broker_class_path.rsplit('.', 1)
377
- module = __import__(module_path, fromlist=[class_name])
378
- broker_class = getattr(module, class_name)
379
-
380
- broker_options = broker_config.get('OPTIONS', {})
381
- broker = broker_class(middleware=middleware_instances, **broker_options)
382
-
383
- # Set as default broker
384
- dramatiq.set_broker(broker)
385
-
386
- logger.debug(f"✅ Dramatiq broker configured with {len(middleware_instances)} middleware")
387
- else:
388
- logger.warning("DRAMATIQ_BROKER not found in Django settings")
389
-
390
- except Exception as e:
391
- logger.warning(f"Failed to configure Dramatiq: {e}")
392
-
393
- logger.info("✅ Task system initialized successfully")
394
- logger.info("💡 To start workers, run: python manage.py rundramatiq")
395
- else:
396
- logger.debug(f"Task system not enabled (config: {config}), skipping initialization")
397
-
398
- except Exception as e:
399
- logger.error(f"Failed to initialize task system: {e}")
400
-
401
-
402
- def generate_dramatiq_settings_from_config(config):
403
- """
404
- Generate Dramatiq settings from DjangoConfig instance.
405
-
406
- Args:
407
- config: DjangoConfig instance with tasks configuration
408
-
409
- Returns:
410
- Dict[str, Any]: Dramatiq settings dictionary or empty dict if not enabled
411
- """
412
- try:
413
- if not hasattr(config, "tasks") or not config.tasks or not config.tasks.enabled:
414
- return {}
415
-
416
- # Get Redis URL from cache configuration
417
- redis_url = None
418
- if config.cache_default and hasattr(config.cache_default, 'redis_url'):
419
- redis_url = config.cache_default.redis_url
420
- elif config.cache_default and hasattr(config.cache_default, 'location'):
421
- redis_url = config.cache_default.location
422
- else:
423
- # Fallback to default Redis URL
424
- redis_url = "redis://localhost:6379"
425
-
426
- if redis_url:
427
- dramatiq_settings = config.tasks.get_dramatiq_settings(redis_url)
428
- logger.debug(f"Generated Dramatiq settings with Redis URL: {redis_url}")
429
- return dramatiq_settings
430
- else:
431
- logger.warning("Tasks enabled but no Redis URL available for Dramatiq")
432
- return {}
433
-
434
- except Exception as e:
435
- logger.error(f"Failed to generate Dramatiq settings: {e}")
436
- return {}
437
-
438
-
439
- def extend_constance_config_with_tasks():
440
- """
441
- Extend Constance configuration with Dramatiq task fields if tasks are enabled.
442
- """
443
- try:
444
- service = get_task_service()
445
- if not service.is_enabled():
446
- logger.debug("Task system not enabled, skipping Constance extension")
447
- return []
448
-
449
- fields = service.get_constance_fields()
450
- logger.info(f"🔧 Extended Constance with {len(fields)} task configuration fields")
451
- return fields
452
-
453
- except Exception as e:
454
- logger.error(f"Failed to extend Constance config with tasks: {e}")
455
- return []
456
276
 
277
+ return status
457
278
 
458
- # === Exports ===
459
279
 
460
- def generate_dramatiq_settings_from_config() -> Optional[Dict[str, Any]]:
461
- """
462
- Generate Dramatiq settings from auto-discovered DjangoConfig.
463
-
464
- Returns:
465
- Dictionary of Dramatiq settings or None if tasks disabled
466
- """
467
- try:
468
- # Get config through BaseCfgModule
469
- base_module = BaseCfgModule()
470
- config = base_module.get_config()
471
-
472
- if not config or not hasattr(config, 'tasks') or not config.tasks or not config.tasks.enabled:
473
- return None
474
-
475
- # Get Redis URL from cache config or environment
476
- redis_url = None
477
- if hasattr(config, 'cache_default') and config.cache_default:
478
- redis_url = getattr(config.cache_default, 'redis_url', None)
479
-
480
- if not redis_url:
481
- # Fallback to environment or default
482
- import os
483
- redis_url = os.getenv('REDIS_URL', 'redis://localhost:6379/1')
484
-
485
- # Generate Dramatiq settings
486
- dramatiq_settings = config.tasks.get_dramatiq_settings(redis_url)
487
-
488
- # Ensure we only use Redis broker (no RabbitMQ)
489
- if 'DRAMATIQ_BROKER' in dramatiq_settings:
490
- dramatiq_settings['DRAMATIQ_BROKER']['BROKER'] = 'dramatiq.brokers.redis.RedisBroker'
491
-
492
- logger.info(f"✅ Generated Dramatiq settings with Redis broker and {len(config.tasks.dramatiq.queues)} queues")
493
- return dramatiq_settings
494
-
495
- except Exception as e:
496
- logger.error(f"Failed to generate Dramatiq settings: {e}")
497
- return None
498
-
499
-
500
- __all__ = [
501
- "DjangoTasks",
502
- "get_task_service",
503
- "reset_task_service",
504
- "is_task_system_available",
505
- "get_task_health",
506
- "generate_dramatiq_settings_from_config",
507
- "extend_constance_config_with_tasks",
508
- "initialize_task_system",
509
- ]
280
+ __all__ = ["DjangoTasks"]