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,17 @@
1
+ """
2
+ Admin helper modules for knowbase.
3
+
4
+ Provides shared display methods, configurations, and utilities.
5
+ """
6
+
7
+ from .configs import DocumentAdminConfigs
8
+ from .display_helpers import DocumentDisplayHelpers
9
+ from .statistics import DocumentStatistics, ChunkStatistics, CategoryStatistics
10
+
11
+ __all__ = [
12
+ 'DocumentAdminConfigs',
13
+ 'DocumentDisplayHelpers',
14
+ 'DocumentStatistics',
15
+ 'ChunkStatistics',
16
+ 'CategoryStatistics',
17
+ ]
@@ -0,0 +1,72 @@
1
+ """
2
+ Shared configuration objects for admin displays.
3
+
4
+ Provides pre-configured StatusBadgeConfig, MoneyDisplayConfig, etc.
5
+ for consistent display across all document admin interfaces.
6
+ """
7
+
8
+ from django_cfg.modules.django_admin import (
9
+ MoneyDisplayConfig,
10
+ StatusBadgeConfig,
11
+ DateTimeDisplayConfig,
12
+ Icons,
13
+ )
14
+
15
+
16
+ class DocumentAdminConfigs:
17
+ """Shared configuration objects for document admins."""
18
+
19
+ # Visibility badges
20
+ VISIBILITY_PUBLIC = StatusBadgeConfig(show_icons=True, icon=Icons.PUBLIC)
21
+ VISIBILITY_PRIVATE = StatusBadgeConfig(show_icons=True, icon=Icons.LOCK)
22
+
23
+ # Vectorization status badges
24
+ VECTORIZED = StatusBadgeConfig(show_icons=True, icon=Icons.CHECK_CIRCLE)
25
+ NOT_VECTORIZED = StatusBadgeConfig(show_icons=True, icon=Icons.ERROR)
26
+
27
+ # Entity type badges
28
+ DOCUMENT_TITLE = StatusBadgeConfig(show_icons=True, icon=Icons.DESCRIPTION)
29
+ CHUNK = StatusBadgeConfig(show_icons=True, icon=Icons.ARTICLE)
30
+ CATEGORY = StatusBadgeConfig(show_icons=True, icon=Icons.FOLDER)
31
+
32
+ # Processing status
33
+ PROCESSING_STATUS = StatusBadgeConfig(
34
+ custom_mappings={
35
+ 'pending': 'warning',
36
+ 'processing': 'info',
37
+ 'completed': 'success',
38
+ 'failed': 'danger',
39
+ 'cancelled': 'secondary'
40
+ },
41
+ show_icons=True
42
+ )
43
+
44
+ # Money display configuration
45
+ COST_USD = MoneyDisplayConfig(
46
+ currency="USD",
47
+ decimal_places=6,
48
+ show_sign=False
49
+ )
50
+
51
+ # DateTime display configuration
52
+ CREATED_AT = DateTimeDisplayConfig(show_relative=True)
53
+
54
+ @classmethod
55
+ def get_processing_status_icon(cls, status: str) -> str:
56
+ """
57
+ Get appropriate icon for processing status.
58
+
59
+ Args:
60
+ status: Processing status value
61
+
62
+ Returns:
63
+ Icon constant
64
+ """
65
+ status_icons = {
66
+ 'completed': Icons.CHECK_CIRCLE,
67
+ 'failed': Icons.ERROR,
68
+ 'processing': Icons.SCHEDULE,
69
+ 'pending': Icons.SCHEDULE,
70
+ 'cancelled': Icons.CANCEL
71
+ }
72
+ return status_icons.get(status, Icons.SCHEDULE)
@@ -0,0 +1,156 @@
1
+ """
2
+ Shared display helper methods for document admins.
3
+
4
+ Provides reusable display methods to eliminate duplication across
5
+ DocumentAdmin, DocumentChunkAdmin, and DocumentCategoryAdmin.
6
+ """
7
+
8
+ from django_cfg.modules.django_admin import display
9
+ from django_cfg.modules.django_admin.utils.badges import StatusBadge
10
+
11
+ from .configs import DocumentAdminConfigs
12
+
13
+
14
+ class DocumentDisplayHelpers:
15
+ """Shared display methods for document admin interfaces."""
16
+
17
+ @staticmethod
18
+ @display(description="User")
19
+ def display_user(obj, display_mixin):
20
+ """
21
+ Display user with standard formatting.
22
+
23
+ Args:
24
+ obj: Model instance with user field
25
+ display_mixin: DisplayMixin instance for formatting
26
+
27
+ Returns:
28
+ Formatted user display or "—" if no user
29
+ """
30
+ if not obj.user:
31
+ return "—"
32
+ return display_mixin.display_user_simple(obj.user)
33
+
34
+ @staticmethod
35
+ @display(description="Visibility")
36
+ def display_visibility(obj):
37
+ """
38
+ Display visibility status (public/private).
39
+
40
+ Args:
41
+ obj: Model instance with is_public field
42
+
43
+ Returns:
44
+ Status badge showing public or private status
45
+ """
46
+ if obj.is_public:
47
+ return StatusBadge.create(
48
+ text="Public",
49
+ variant="success",
50
+ config=DocumentAdminConfigs.VISIBILITY_PUBLIC
51
+ )
52
+ else:
53
+ return StatusBadge.create(
54
+ text="Private",
55
+ variant="danger",
56
+ config=DocumentAdminConfigs.VISIBILITY_PRIVATE
57
+ )
58
+
59
+ @staticmethod
60
+ @display(description="Tokens")
61
+ def display_token_count(obj, field_name='token_count'):
62
+ """
63
+ Display token count with K formatting.
64
+
65
+ Args:
66
+ obj: Model instance with token count field
67
+ field_name: Name of the token count field
68
+
69
+ Returns:
70
+ Formatted token count (e.g., "1.5K" or "500")
71
+ """
72
+ tokens = getattr(obj, field_name, 0)
73
+ if tokens > 1000:
74
+ return f"{tokens/1000:.1f}K"
75
+ return str(tokens)
76
+
77
+ @staticmethod
78
+ @display(description="Cost (USD)")
79
+ def display_cost_usd(obj, display_mixin, field_name='total_cost_usd'):
80
+ """
81
+ Display cost with currency formatting.
82
+
83
+ Args:
84
+ obj: Model instance with cost field
85
+ display_mixin: DisplayMixin instance for formatting
86
+ field_name: Name of the cost field
87
+
88
+ Returns:
89
+ Formatted cost with currency
90
+ """
91
+ return display_mixin.display_money_amount(
92
+ obj, field_name, DocumentAdminConfigs.COST_USD
93
+ )
94
+
95
+ @staticmethod
96
+ @display(description="Created")
97
+ def display_created_at(obj, display_mixin):
98
+ """
99
+ Display created time with relative display.
100
+
101
+ Args:
102
+ obj: Model instance with created_at field
103
+ display_mixin: DisplayMixin instance for formatting
104
+
105
+ Returns:
106
+ Formatted datetime with relative time
107
+ """
108
+ return display_mixin.display_datetime_relative(
109
+ obj, 'created_at', DocumentAdminConfigs.CREATED_AT
110
+ )
111
+
112
+ @staticmethod
113
+ @display(description="Embedding")
114
+ def display_embedding_status(obj):
115
+ """
116
+ Display embedding vectorization status.
117
+
118
+ Args:
119
+ obj: Model instance with embedding field
120
+
121
+ Returns:
122
+ Status badge showing vectorization status
123
+ """
124
+ has_embedding = obj.embedding is not None and len(obj.embedding) > 0
125
+ if has_embedding:
126
+ return StatusBadge.create(
127
+ text="✓ Vectorized",
128
+ variant="success",
129
+ config=DocumentAdminConfigs.VECTORIZED
130
+ )
131
+ else:
132
+ return StatusBadge.create(
133
+ text="✗ Not vectorized",
134
+ variant="danger",
135
+ config=DocumentAdminConfigs.NOT_VECTORIZED
136
+ )
137
+
138
+ @staticmethod
139
+ @display(description="Content Preview")
140
+ def display_content_preview(obj, max_length=200):
141
+ """
142
+ Display content preview with truncation.
143
+
144
+ Args:
145
+ obj: Model instance with content field
146
+ max_length: Maximum length before truncation
147
+
148
+ Returns:
149
+ Truncated content preview
150
+ """
151
+ if not obj.content:
152
+ return "—"
153
+ content = obj.content
154
+ if len(content) > max_length:
155
+ return content[:max_length] + "..."
156
+ return content
@@ -0,0 +1,108 @@
1
+ """
2
+ Statistics calculation for document admin changelist views.
3
+
4
+ Provides reusable statistics aggregation logic for admin interfaces.
5
+ """
6
+
7
+ from django.db.models import Count, Sum, Avg, Q
8
+
9
+
10
+ class DocumentStatistics:
11
+ """Calculate statistics for document admin."""
12
+
13
+ @staticmethod
14
+ def get_document_stats(queryset):
15
+ """
16
+ Calculate document statistics.
17
+
18
+ Args:
19
+ queryset: Document queryset to aggregate
20
+
21
+ Returns:
22
+ dict: Statistics including counts, tokens, and costs
23
+ """
24
+ stats = queryset.aggregate(
25
+ total_documents=Count('id'),
26
+ total_chunks=Sum('chunks_count'),
27
+ total_tokens=Sum('total_tokens'),
28
+ total_cost=Sum('total_cost_usd')
29
+ )
30
+
31
+ status_counts = dict(
32
+ queryset.values_list('processing_status').annotate(
33
+ count=Count('id')
34
+ )
35
+ )
36
+
37
+ return {
38
+ 'total_documents': stats['total_documents'] or 0,
39
+ 'total_chunks': stats['total_chunks'] or 0,
40
+ 'total_tokens': stats['total_tokens'] or 0,
41
+ 'total_cost': f"${(stats['total_cost'] or 0):.6f}",
42
+ 'status_counts': status_counts
43
+ }
44
+
45
+
46
+ class ChunkStatistics:
47
+ """Calculate statistics for chunk admin."""
48
+
49
+ @staticmethod
50
+ def get_chunk_stats(queryset):
51
+ """
52
+ Calculate chunk statistics.
53
+
54
+ Args:
55
+ queryset: DocumentChunk queryset to aggregate
56
+
57
+ Returns:
58
+ dict: Statistics including counts, tokens, and costs
59
+ """
60
+ stats = queryset.aggregate(
61
+ total_chunks=Count('id'),
62
+ total_tokens=Sum('token_count'),
63
+ total_characters=Sum('character_count'),
64
+ total_embedding_cost=Sum('embedding_cost'),
65
+ avg_tokens_per_chunk=Avg('token_count')
66
+ )
67
+
68
+ model_counts = dict(
69
+ queryset.values_list('embedding_model').annotate(
70
+ count=Count('id')
71
+ )
72
+ )
73
+
74
+ return {
75
+ 'total_chunks': stats['total_chunks'] or 0,
76
+ 'total_tokens': stats['total_tokens'] or 0,
77
+ 'total_characters': stats['total_characters'] or 0,
78
+ 'total_embedding_cost': f"${(stats['total_embedding_cost'] or 0):.6f}",
79
+ 'avg_tokens_per_chunk': f"{(stats['avg_tokens_per_chunk'] or 0):.0f}",
80
+ 'model_counts': model_counts
81
+ }
82
+
83
+
84
+ class CategoryStatistics:
85
+ """Calculate statistics for category admin."""
86
+
87
+ @staticmethod
88
+ def get_category_stats(queryset):
89
+ """
90
+ Calculate category statistics.
91
+
92
+ Args:
93
+ queryset: DocumentCategory queryset to aggregate
94
+
95
+ Returns:
96
+ dict: Statistics including public/private counts
97
+ """
98
+ stats = queryset.aggregate(
99
+ total_categories=Count('id'),
100
+ public_categories=Count('id', filter=Q(is_public=True)),
101
+ private_categories=Count('id', filter=Q(is_public=False))
102
+ )
103
+
104
+ return {
105
+ 'total_categories': stats['total_categories'] or 0,
106
+ 'public_categories': stats['public_categories'] or 0,
107
+ 'private_categories': stats['private_categories'] or 0
108
+ }
@@ -9,7 +9,7 @@ to ensure consistency across the application.
9
9
  """
10
10
 
11
11
  from typing import List
12
- from django_cfg.models.constance import ConstanceField
12
+ from django_cfg.models.django.constance import ConstanceField
13
13
  from .settings import KnowledgeBaseConfig, get_openai_api_key, get_openrouter_api_key
14
14
 
15
15
 
@@ -258,7 +258,7 @@ class KnowledgeBaseConfig(BaseModel):
258
258
  def get_openai_api_key(self) -> Optional[str]:
259
259
  """Get OpenAI API key from django-cfg configuration."""
260
260
  try:
261
- from django_cfg.core.config import get_current_config
261
+ from django_cfg.core.state import get_current_config
262
262
  config = get_current_config()
263
263
  if config and hasattr(config, 'api_keys') and config.api_keys:
264
264
  return config.api_keys.get_openai_key()
@@ -271,7 +271,7 @@ class KnowledgeBaseConfig(BaseModel):
271
271
  def get_openrouter_api_key(self) -> Optional[str]:
272
272
  """Get OpenRouter API key from django-cfg configuration."""
273
273
  try:
274
- from django_cfg.core.config import get_current_config
274
+ from django_cfg.core.state import get_current_config
275
275
  config = get_current_config()
276
276
  if config and hasattr(config, 'api_keys') and config.api_keys:
277
277
  return config.api_keys.get_openrouter_key()
@@ -3,13 +3,30 @@ Mixins for knowbase integration.
3
3
  """
4
4
 
5
5
  from .external_data_mixin import ExternalDataMixin
6
- from .config import ExternalDataConfig
6
+ from .config import ExternalDataMetaConfig, ExternalDataMetaParser, ExternalDataDefaults
7
7
  from .creator import ExternalDataCreator
8
8
  from .service import ExternalDataService
9
+ from .generators import (
10
+ ExternalDataContentGenerator,
11
+ ExternalDataMetadataGenerator,
12
+ ExternalDataFieldAnalyzer,
13
+ )
9
14
 
10
15
  __all__ = [
16
+ # Core mixin
11
17
  'ExternalDataMixin',
12
- 'ExternalDataConfig',
18
+
19
+ # Configuration
20
+ 'ExternalDataMetaConfig',
21
+ 'ExternalDataMetaParser',
22
+ 'ExternalDataDefaults',
23
+
24
+ # Service layer
13
25
  'ExternalDataCreator',
14
26
  'ExternalDataService',
27
+
28
+ # Generators (for advanced usage)
29
+ 'ExternalDataContentGenerator',
30
+ 'ExternalDataMetadataGenerator',
31
+ 'ExternalDataFieldAnalyzer',
15
32
  ]
@@ -0,0 +1,14 @@
1
+ """
2
+ Configuration utilities for ExternalData.
3
+
4
+ Parsing and defaults for ExternalDataMeta configuration.
5
+ """
6
+
7
+ from .meta_config import ExternalDataMetaConfig, ExternalDataMetaParser
8
+ from .defaults import ExternalDataDefaults
9
+
10
+ __all__ = [
11
+ 'ExternalDataMetaConfig',
12
+ 'ExternalDataMetaParser',
13
+ 'ExternalDataDefaults',
14
+ ]
@@ -0,0 +1,75 @@
1
+ """
2
+ Smart defaults for ExternalData configuration.
3
+
4
+ Provides sensible defaults for ExternalData configuration when not explicitly specified.
5
+ """
6
+
7
+ from typing import List
8
+
9
+ from ...models.external_data import ExternalDataType
10
+ from ..generators import ExternalDataFieldAnalyzer
11
+
12
+
13
+ class ExternalDataDefaults:
14
+ """
15
+ Provide smart defaults for ExternalData configuration.
16
+
17
+ Offers utilities to get sensible defaults when ExternalDataMeta
18
+ is not provided or incomplete.
19
+ """
20
+
21
+ @staticmethod
22
+ def get_default_watch_fields(model_class) -> List[str]:
23
+ """
24
+ Get default watch fields for a model class.
25
+
26
+ Uses field analyzer to detect important fields.
27
+
28
+ Args:
29
+ model_class: Django model class
30
+
31
+ Returns:
32
+ List of field names to watch
33
+ """
34
+ analyzer = ExternalDataFieldAnalyzer(model_class)
35
+ return analyzer.auto_detect_watch_fields()
36
+
37
+ @staticmethod
38
+ def get_default_source_type() -> ExternalDataType:
39
+ """
40
+ Get default source type.
41
+
42
+ Returns:
43
+ ExternalDataType.MODEL as default
44
+ """
45
+ return ExternalDataType.MODEL
46
+
47
+ @staticmethod
48
+ def get_default_similarity_threshold() -> float:
49
+ """
50
+ Get default similarity threshold.
51
+
52
+ Returns:
53
+ 0.5 as balanced default threshold
54
+ """
55
+ return 0.5
56
+
57
+ @staticmethod
58
+ def get_default_auto_sync() -> bool:
59
+ """
60
+ Get default auto_sync setting.
61
+
62
+ Returns:
63
+ True (enabled by default)
64
+ """
65
+ return True
66
+
67
+ @staticmethod
68
+ def get_default_is_public() -> bool:
69
+ """
70
+ Get default is_public setting.
71
+
72
+ Returns:
73
+ False (private by default for security)
74
+ """
75
+ return False
@@ -0,0 +1,120 @@
1
+ """
2
+ ExternalDataMeta configuration parser.
3
+
4
+ Handles parsing and processing of ExternalDataMeta configuration from model classes.
5
+ """
6
+
7
+ from dataclasses import dataclass, field
8
+ from typing import List, Dict, Any
9
+
10
+ from ...models.external_data import ExternalDataType
11
+ from ..generators import ExternalDataFieldAnalyzer
12
+
13
+
14
+ @dataclass
15
+ class ExternalDataMetaConfig:
16
+ """
17
+ Configuration from ExternalDataMeta class.
18
+
19
+ Attributes:
20
+ watch_fields: List of field names to watch for changes
21
+ similarity_threshold: Threshold for similarity search (0.0-1.0)
22
+ source_type: Type of external data source
23
+ auto_sync: Whether to automatically sync on changes
24
+ is_public: Whether data is public
25
+ title: Title for the external data (for create_from_config)
26
+ description: Description for the external data
27
+ content: Content for the external data
28
+ source_identifier: Source identifier
29
+ is_active: Whether the data is active
30
+ metadata: Additional metadata
31
+ tags: List of tags
32
+ source_config: Source configuration dict
33
+ """
34
+ # Core configuration fields
35
+ watch_fields: List[str] = field(default_factory=list)
36
+ similarity_threshold: float = 0.5
37
+ source_type: ExternalDataType = ExternalDataType.MODEL
38
+ auto_sync: bool = True
39
+ is_public: bool = False
40
+
41
+ # ExternalData creation fields (used by ExternalDataCreator)
42
+ title: str = ""
43
+ description: str = ""
44
+ content: str = ""
45
+ source_identifier: str = ""
46
+ is_active: bool = True
47
+ metadata: Dict[str, Any] = field(default_factory=dict)
48
+ tags: List[str] = field(default_factory=list)
49
+ source_config: Dict[str, Any] = field(default_factory=dict)
50
+
51
+
52
+ class ExternalDataMetaParser:
53
+ """
54
+ Parse ExternalDataMeta from model class.
55
+
56
+ Extracts configuration from model's ExternalDataMeta inner class
57
+ and applies smart defaults where needed.
58
+ """
59
+
60
+ @staticmethod
61
+ def parse(model_class) -> Dict[str, Any]:
62
+ """
63
+ Parse ExternalDataMeta configuration from model class.
64
+
65
+ Args:
66
+ model_class: Django model class with optional ExternalDataMeta
67
+
68
+ Returns:
69
+ Dictionary with parsed configuration and smart defaults
70
+ """
71
+ config = {}
72
+
73
+ # If ExternalDataMeta exists, use it
74
+ if hasattr(model_class, 'ExternalDataMeta'):
75
+ meta_class = model_class.ExternalDataMeta
76
+ # Extract configuration from ExternalDataMeta
77
+ for attr in dir(meta_class):
78
+ if not attr.startswith('_'):
79
+ value = getattr(meta_class, attr)
80
+ if not callable(value): # Only properties, not methods
81
+ config[attr] = value
82
+
83
+ # Smart defaults based on model analysis
84
+ if 'watch_fields' not in config:
85
+ analyzer = ExternalDataFieldAnalyzer(model_class)
86
+ config['watch_fields'] = analyzer.auto_detect_watch_fields()
87
+
88
+ if 'similarity_threshold' not in config:
89
+ config['similarity_threshold'] = 0.5 # Balanced default
90
+
91
+ if 'source_type' not in config:
92
+ config['source_type'] = ExternalDataType.MODEL # Smart default
93
+
94
+ if 'auto_sync' not in config:
95
+ config['auto_sync'] = True # Enable by default
96
+
97
+ if 'is_public' not in config:
98
+ config['is_public'] = False # Private by default for security
99
+
100
+ return config
101
+
102
+ @staticmethod
103
+ def to_dataclass(model_class) -> ExternalDataMetaConfig:
104
+ """
105
+ Parse configuration and return as dataclass.
106
+
107
+ Args:
108
+ model_class: Django model class
109
+
110
+ Returns:
111
+ ExternalDataMetaConfig dataclass instance
112
+ """
113
+ config_dict = ExternalDataMetaParser.parse(model_class)
114
+ return ExternalDataMetaConfig(
115
+ watch_fields=config_dict.get('watch_fields', []),
116
+ similarity_threshold=config_dict.get('similarity_threshold', 0.5),
117
+ source_type=config_dict.get('source_type', ExternalDataType.MODEL),
118
+ auto_sync=config_dict.get('auto_sync', True),
119
+ is_public=config_dict.get('is_public', False),
120
+ )
@@ -8,7 +8,7 @@ from django.contrib.auth import get_user_model
8
8
  from django.db import transaction
9
9
  from django.utils import timezone
10
10
 
11
- from .config import ExternalDataConfig
11
+ from .config import ExternalDataMetaConfig
12
12
  from ..models.external_data import ExternalData, ExternalDataStatus
13
13
 
14
14
  logger = logging.getLogger(__name__)
@@ -25,12 +25,12 @@ class ExternalDataCreator:
25
25
  else:
26
26
  self.user = user
27
27
 
28
- def create_from_config(self, config: ExternalDataConfig) -> Dict[str, Any]:
28
+ def create_from_config(self, config: ExternalDataMetaConfig) -> Dict[str, Any]:
29
29
  """
30
30
  Create an ExternalData object from a Pydantic configuration.
31
31
 
32
32
  Args:
33
- config: An instance of ExternalDataConfig.
33
+ config: An instance of ExternalDataMetaConfig.
34
34
 
35
35
  Returns:
36
36
  dict: Result with success status, external_data object, and message/error.
@@ -72,10 +72,10 @@ class ExternalDataCreator:
72
72
  def _get_default_user(self):
73
73
  """Get default user for ExternalData ownership."""
74
74
  User = get_user_model()
75
-
76
- # Try to find a superuser
77
- superuser = User.objects.filter(is_superuser=True).first()
78
- if superuser:
79
- return superuser
80
-
81
- raise ValueError("No user provided and no superuser found for ExternalData ownership")
75
+
76
+ # Try to find a staff user (staff or superuser)
77
+ staff_user = User.objects.filter(is_staff=True).first()
78
+ if staff_user:
79
+ return staff_user
80
+
81
+ raise ValueError("No user provided and no staff user found for ExternalData ownership")