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.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/admin/inlines.py +11 -5
- django_cfg/apps/accounts/admin/user_admin.py +39 -16
- django_cfg/apps/accounts/serializers/profile.py +1 -1
- django_cfg/apps/accounts/services/otp_service.py +18 -11
- django_cfg/apps/accounts/signals.py +15 -24
- django_cfg/apps/accounts/utils/notifications.py +217 -358
- django_cfg/apps/accounts/views/otp.py +2 -2
- django_cfg/apps/accounts/views/webhook.py +1 -1
- django_cfg/apps/agents/core/django_agent.py +1 -1
- django_cfg/apps/api/commands/views.py +66 -83
- django_cfg/apps/api/health/drf_views.py +269 -0
- django_cfg/apps/api/health/serializers.py +45 -0
- django_cfg/apps/api/health/urls.py +6 -1
- django_cfg/apps/knowbase/admin/actions/__init__.py +13 -0
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +56 -0
- django_cfg/apps/knowbase/admin/document_admin.py +136 -270
- django_cfg/apps/knowbase/admin/helpers/__init__.py +17 -0
- django_cfg/apps/knowbase/admin/helpers/configs.py +72 -0
- django_cfg/apps/knowbase/admin/helpers/display_helpers.py +156 -0
- django_cfg/apps/knowbase/admin/helpers/statistics.py +108 -0
- django_cfg/apps/knowbase/config/constance_fields.py +1 -1
- django_cfg/apps/knowbase/config/settings.py +2 -2
- django_cfg/apps/knowbase/mixins/__init__.py +19 -2
- django_cfg/apps/knowbase/mixins/config/__init__.py +14 -0
- django_cfg/apps/knowbase/mixins/config/defaults.py +75 -0
- django_cfg/apps/knowbase/mixins/config/meta_config.py +120 -0
- django_cfg/apps/knowbase/mixins/creator.py +10 -10
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +105 -403
- django_cfg/apps/knowbase/mixins/generators/__init__.py +16 -0
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +218 -0
- django_cfg/apps/knowbase/mixins/generators/field_analyzer.py +76 -0
- django_cfg/apps/knowbase/mixins/generators/metadata_generator.py +124 -0
- django_cfg/apps/knowbase/mixins/service.py +2 -2
- django_cfg/apps/knowbase/services/archive/__init__.py +1 -0
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +17 -0
- django_cfg/apps/knowbase/services/archive/analyzers/complexity_analyzer.py +33 -0
- django_cfg/apps/knowbase/services/archive/analyzers/purpose_detector.py +36 -0
- django_cfg/apps/knowbase/services/archive/analyzers/quality_analyzer.py +39 -0
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +103 -0
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +19 -0
- django_cfg/apps/knowbase/services/archive/chunking/base.py +81 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +62 -0
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +107 -0
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +248 -0
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +70 -0
- django_cfg/apps/knowbase/services/archive/chunking_service.py +110 -729
- django_cfg/apps/knowbase/services/archive/context/__init__.py +14 -0
- django_cfg/apps/knowbase/services/archive/context/builders.py +220 -0
- django_cfg/apps/knowbase/services/archive/context/models.py +38 -0
- django_cfg/apps/knowbase/services/embedding/models.py +18 -14
- django_cfg/apps/knowbase/services/embedding/processors.py +6 -3
- django_cfg/apps/knowbase/tasks/document_processing.py +11 -3
- django_cfg/apps/leads/tests.py +1 -1
- django_cfg/apps/payments/admin/api_keys_admin.py +1 -1
- django_cfg/apps/payments/admin/balance_admin.py +1 -1
- django_cfg/apps/payments/admin/currencies_admin.py +1 -1
- django_cfg/apps/payments/admin/payments_admin.py +1 -1
- django_cfg/apps/payments/admin/subscriptions_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +59 -126
- django_cfg/apps/payments/admin_interface/views/api/payments.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/stats.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/users.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +1 -1
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +1 -1
- django_cfg/apps/payments/admin_interface/views/base.py +29 -2
- django_cfg/apps/payments/apps.py +1 -1
- django_cfg/apps/payments/config/django_cfg_integration.py +2 -2
- django_cfg/apps/payments/config/helpers.py +3 -2
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +1 -1
- django_cfg/apps/payments/management/commands/currency_stats.py +1 -1
- django_cfg/apps/payments/management/commands/manage_currencies.py +1 -1
- django_cfg/apps/payments/management/commands/manage_providers.py +1 -1
- django_cfg/apps/payments/management/commands/process_pending_payments.py +1 -1
- django_cfg/apps/payments/management/commands/test_providers.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +1 -1
- django_cfg/apps/payments/middleware/rate_limiting.py +1 -1
- django_cfg/apps/payments/middleware/usage_tracking.py +1 -1
- django_cfg/apps/payments/models/balance.py +2 -2
- django_cfg/apps/payments/models/managers/api_key_managers.py +1 -1
- django_cfg/apps/payments/models/managers/balance_managers.py +1 -1
- django_cfg/apps/payments/models/managers/currency_managers.py +1 -1
- django_cfg/apps/payments/models/managers/payment_managers.py +1 -1
- django_cfg/apps/payments/models/managers/subscription_managers.py +1 -1
- django_cfg/apps/payments/models/payments.py +2 -2
- django_cfg/apps/payments/services/cache_service/__init__.py +1 -1
- django_cfg/apps/payments/services/cache_service/simple_cache.py +10 -5
- django_cfg/apps/payments/services/core/base.py +1 -1
- django_cfg/apps/payments/services/core/currency/__init__.py +13 -0
- django_cfg/apps/payments/services/core/currency/currency_converter.py +57 -0
- django_cfg/apps/payments/services/core/currency/currency_validator.py +61 -0
- django_cfg/apps/payments/services/core/operations/__init__.py +15 -0
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +100 -0
- django_cfg/apps/payments/services/core/operations/payment_creator.py +196 -0
- django_cfg/apps/payments/services/core/operations/status_checker.py +100 -0
- django_cfg/apps/payments/services/core/payment_service.py +124 -612
- django_cfg/apps/payments/services/core/providers/__init__.py +13 -0
- django_cfg/apps/payments/services/core/providers/provider_client.py +132 -0
- django_cfg/apps/payments/services/core/providers/status_mapper.py +89 -0
- django_cfg/apps/payments/services/core/utils/__init__.py +13 -0
- django_cfg/apps/payments/services/core/utils/data_converter.py +48 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +69 -0
- django_cfg/apps/payments/services/providers/base.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +3 -3
- django_cfg/apps/payments/services/providers/nowpayments/parsers/__init__.py +9 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/constants.py +23 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/currency_names.py +244 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +511 -0
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +168 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +1 -1
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +1 -1
- django_cfg/apps/payments/services/providers/registry.py +1 -1
- django_cfg/apps/payments/services/providers/sync_service.py +1 -1
- django_cfg/apps/payments/signals/__init__.py +1 -1
- django_cfg/apps/payments/signals/api_key_signals.py +1 -1
- django_cfg/apps/payments/signals/balance_signals.py +1 -1
- django_cfg/apps/payments/signals/payment_signals.py +1 -1
- django_cfg/apps/payments/signals/subscription_signals.py +1 -1
- django_cfg/apps/payments/views/api/api_keys.py +1 -1
- django_cfg/apps/payments/views/api/balances.py +1 -1
- django_cfg/apps/payments/views/api/base.py +1 -1
- django_cfg/apps/payments/views/api/currencies.py +1 -1
- django_cfg/apps/payments/views/api/payments.py +1 -1
- django_cfg/apps/payments/views/api/subscriptions.py +1 -1
- django_cfg/apps/payments/views/api/webhooks.py +1 -1
- django_cfg/apps/payments/views/serializers/api_keys.py +1 -1
- django_cfg/apps/payments/views/serializers/balances.py +1 -1
- django_cfg/apps/payments/views/serializers/currencies.py +1 -1
- django_cfg/apps/payments/views/serializers/payments.py +1 -1
- django_cfg/apps/payments/views/serializers/subscriptions.py +1 -1
- django_cfg/apps/payments/views/serializers/webhooks.py +1 -1
- django_cfg/apps/support/admin/support_admin.py +21 -13
- django_cfg/apps/support/templates/support/chat/access_denied.html +21 -27
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +183 -254
- django_cfg/apps/support/utils/support_email_service.py +1 -1
- django_cfg/apps/tasks/templates/tasks/layout/base.html +20 -115
- django_cfg/apps/tasks/utils/simulator.py +1 -1
- django_cfg/apps/tasks/views/dashboard.py +33 -3
- django_cfg/apps/urls.py +5 -1
- django_cfg/cli/README.md +57 -471
- django_cfg/cli/commands/create_project.py +140 -529
- django_cfg/cli/main.py +13 -10
- django_cfg/core/__init__.py +63 -6
- django_cfg/core/base/__init__.py +5 -0
- django_cfg/core/base/config_model.py +652 -0
- django_cfg/core/builders/__init__.py +11 -0
- django_cfg/core/builders/apps_builder.py +258 -0
- django_cfg/core/builders/middleware_builder.py +115 -0
- django_cfg/core/builders/security_builder.py +96 -0
- django_cfg/core/config.py +20 -892
- django_cfg/core/constants.py +69 -0
- django_cfg/core/environment/__init__.py +9 -0
- django_cfg/core/exceptions.py +45 -298
- django_cfg/core/generation/__init__.py +51 -0
- django_cfg/core/generation/core_generators/__init__.py +0 -0
- django_cfg/core/generation/core_generators/settings.py +90 -0
- django_cfg/core/generation/core_generators/static.py +82 -0
- django_cfg/core/generation/core_generators/templates.py +141 -0
- django_cfg/core/generation/data_generators/__init__.py +15 -0
- django_cfg/core/generation/data_generators/cache.py +132 -0
- django_cfg/core/generation/data_generators/database.py +117 -0
- django_cfg/core/generation/generation.py +92 -0
- django_cfg/core/generation/integration_generators/__init__.py +21 -0
- django_cfg/core/generation/integration_generators/api.py +237 -0
- django_cfg/core/generation/integration_generators/sessions.py +65 -0
- django_cfg/core/generation/integration_generators/tailwind.py +54 -0
- django_cfg/core/generation/integration_generators/tasks.py +92 -0
- django_cfg/core/generation/integration_generators/third_party.py +144 -0
- django_cfg/core/generation/orchestrator.py +285 -0
- django_cfg/core/generation/protocols.py +30 -0
- django_cfg/core/generation/security_generators/__init__.py +0 -0
- django_cfg/core/generation/utility_generators/__init__.py +24 -0
- django_cfg/core/generation/utility_generators/email.py +58 -0
- django_cfg/core/generation/utility_generators/i18n.py +66 -0
- django_cfg/core/generation/utility_generators/limits.py +58 -0
- django_cfg/core/generation/utility_generators/logging.py +66 -0
- django_cfg/core/generation/utility_generators/security.py +101 -0
- django_cfg/core/generation/utils/__init__.py +0 -0
- django_cfg/core/generation/utils/helpers.py +32 -0
- django_cfg/core/integration/__init__.py +18 -25
- django_cfg/core/integration/display/startup.py +146 -133
- django_cfg/core/integration/url_integration.py +13 -2
- django_cfg/core/services/__init__.py +5 -0
- django_cfg/core/services/config_service.py +121 -0
- django_cfg/core/state/__init__.py +9 -0
- django_cfg/core/state/registry.py +84 -0
- django_cfg/core/types/__init__.py +15 -0
- django_cfg/core/types/aliases.py +15 -0
- django_cfg/core/types/enums.py +49 -0
- django_cfg/dashboard/DEBUG_README.md +105 -0
- django_cfg/dashboard/REFACTORING_SUMMARY.md +237 -0
- django_cfg/dashboard/__init__.py +24 -0
- django_cfg/dashboard/components.py +308 -0
- django_cfg/dashboard/debug.py +176 -0
- django_cfg/dashboard/management/__init__.py +0 -0
- django_cfg/dashboard/management/commands/__init__.py +0 -0
- django_cfg/dashboard/management/commands/debug_dashboard.py +109 -0
- django_cfg/dashboard/sections/__init__.py +1 -0
- django_cfg/dashboard/sections/base.py +128 -0
- django_cfg/dashboard/sections/commands.py +32 -0
- django_cfg/dashboard/sections/overview.py +394 -0
- django_cfg/dashboard/sections/stats.py +48 -0
- django_cfg/dashboard/sections/system.py +73 -0
- django_cfg/management/commands/check_settings.py +6 -2
- django_cfg/management/commands/clear_constance.py +6 -1
- django_cfg/management/commands/create_token.py +5 -4
- django_cfg/management/commands/generate.py +5 -0
- django_cfg/management/commands/list_urls.py +7 -2
- django_cfg/management/commands/migrate_all.py +6 -2
- django_cfg/management/commands/migrator.py +6 -1
- django_cfg/management/commands/rundramatiq.py +6 -1
- django_cfg/management/commands/rundramatiq_simulator.py +11 -4
- django_cfg/management/commands/runserver_ngrok.py +9 -7
- django_cfg/management/commands/script.py +25 -21
- django_cfg/management/commands/show_config.py +6 -1
- django_cfg/management/commands/show_urls.py +8 -3
- django_cfg/management/commands/superuser.py +5 -4
- django_cfg/management/commands/task_clear.py +8 -3
- django_cfg/management/commands/task_status.py +8 -3
- django_cfg/management/commands/test_email.py +6 -1
- django_cfg/management/commands/test_telegram.py +6 -1
- django_cfg/management/commands/test_twilio.py +6 -1
- django_cfg/management/commands/tree.py +7 -4
- django_cfg/models/__init__.py +88 -3
- django_cfg/models/api/__init__.py +27 -0
- django_cfg/models/{api.py → api/config.py} +1 -1
- django_cfg/models/api/drf/__init__.py +21 -0
- django_cfg/models/api/drf/config.py +101 -0
- django_cfg/models/api/drf/redoc.py +31 -0
- django_cfg/models/api/drf/spectacular.py +129 -0
- django_cfg/models/api/drf/swagger.py +59 -0
- django_cfg/models/{api_keys.py → api/keys.py} +16 -6
- django_cfg/models/{limits.py → api/limits.py} +0 -1
- django_cfg/models/base/__init__.py +14 -0
- django_cfg/models/django/__init__.py +16 -0
- django_cfg/models/{constance.py → django/constance.py} +1 -1
- django_cfg/models/{environment.py → django/environment.py} +1 -1
- django_cfg/models/infrastructure/__init__.py +17 -0
- django_cfg/models/{cache.py → infrastructure/cache.py} +3 -2
- django_cfg/models/infrastructure/database/__init__.py +22 -0
- django_cfg/models/infrastructure/database/config.py +265 -0
- django_cfg/models/infrastructure/database/converters.py +91 -0
- django_cfg/models/infrastructure/database/parsers.py +96 -0
- django_cfg/models/infrastructure/database/routing.py +85 -0
- django_cfg/models/infrastructure/database/validators.py +170 -0
- django_cfg/models/{logging.py → infrastructure/logging.py} +1 -1
- django_cfg/models/{security.py → infrastructure/security.py} +2 -2
- django_cfg/models/ngrok/__init__.py +11 -0
- django_cfg/models/ngrok/auth.py +37 -0
- django_cfg/models/ngrok/config.py +77 -0
- django_cfg/models/ngrok/tunnel.py +35 -0
- django_cfg/models/payments/__init__.py +20 -0
- django_cfg/models/payments/api_keys.py +57 -0
- django_cfg/models/{payments.py → payments/config.py} +56 -154
- django_cfg/models/payments/providers/__init__.py +15 -0
- django_cfg/models/payments/providers/base.py +25 -0
- django_cfg/models/payments/providers/nowpayments.py +48 -0
- django_cfg/models/services/__init__.py +18 -0
- django_cfg/models/services/base.py +65 -0
- django_cfg/models/{email.py → services/email.py} +1 -1
- django_cfg/models/services/telegram.py +172 -0
- django_cfg/models/tasks/__init__.py +51 -0
- django_cfg/models/tasks/backends.py +250 -0
- django_cfg/models/tasks/config.py +314 -0
- django_cfg/models/tasks/utils.py +174 -0
- django_cfg/modules/base.py +18 -3
- django_cfg/modules/django_admin/decorators/actions.py +1 -1
- django_cfg/modules/django_admin/decorators/display.py +1 -1
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +1 -1
- django_cfg/modules/django_cfg_rpc_client/README.md +346 -0
- django_cfg/modules/django_cfg_rpc_client/__init__.py +51 -0
- django_cfg/modules/django_cfg_rpc_client/client.py +540 -0
- django_cfg/modules/django_cfg_rpc_client/config.py +207 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/README.md +517 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/__init__.py +11 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/apps.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/monitor.py +435 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/static/django_cfg_rpc_dashboard/js/dashboard.js +373 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/base.html +76 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/templates/django_cfg_rpc_dashboard/dashboard.html +200 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls.py +22 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/urls_admin.py +9 -0
- django_cfg/modules/django_cfg_rpc_client/dashboard/views.py +251 -0
- django_cfg/modules/django_cfg_rpc_client/exceptions.py +201 -0
- django_cfg/modules/django_drf_theme/CHANGELOG.md +210 -0
- django_cfg/modules/django_drf_theme/EXAMPLE.md +465 -0
- django_cfg/modules/django_drf_theme/IMPLEMENTATION.md +232 -0
- django_cfg/modules/django_drf_theme/README.md +207 -0
- django_cfg/modules/django_drf_theme/TAILWIND_CDN_GUIDE.md +274 -0
- django_cfg/modules/django_drf_theme/__init__.py +23 -0
- django_cfg/modules/django_drf_theme/apps.py +15 -0
- django_cfg/modules/django_drf_theme/renderers.py +58 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/api.html +375 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/base.html +938 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/filter_form.html +132 -0
- django_cfg/modules/django_drf_theme/templates/rest_framework/tailwind/forms/raw_data_form.html +123 -0
- django_cfg/modules/django_drf_theme/templatetags/__init__.py +1 -0
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +57 -0
- django_cfg/modules/django_email/__init__.py +14 -0
- django_cfg/modules/{django_email.py → django_email/service.py} +78 -113
- django_cfg/modules/django_email/utils.py +40 -0
- django_cfg/modules/django_health/__init__.py +9 -0
- django_cfg/modules/{django_health.py → django_health/service.py} +23 -21
- django_cfg/modules/django_llm/llm/client.py +155 -550
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +13 -0
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +106 -0
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +79 -0
- django_cfg/modules/django_llm/llm/models_api/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/models_api/models_query.py +163 -0
- django_cfg/modules/django_llm/llm/providers/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/providers/config_builder.py +103 -0
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +148 -0
- django_cfg/modules/django_llm/llm/providers/provider_selector.py +60 -0
- django_cfg/modules/django_llm/llm/requests/__init__.py +15 -0
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +170 -0
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +199 -0
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +113 -0
- django_cfg/modules/django_llm/llm/responses/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/responses/response_builder.py +131 -0
- django_cfg/modules/django_llm/llm/stats/__init__.py +9 -0
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +107 -0
- django_cfg/modules/django_llm/translator/detectors/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/detectors/language_detector.py +90 -0
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +153 -0
- django_cfg/modules/django_llm/translator/stats/__init__.py +11 -0
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +85 -0
- django_cfg/modules/django_llm/translator/translator.py +150 -603
- django_cfg/modules/django_llm/translator/translators/__init__.py +15 -0
- django_cfg/modules/django_llm/translator/translators/json_translator.py +316 -0
- django_cfg/modules/django_llm/translator/translators/text_translator.py +139 -0
- django_cfg/modules/django_llm/translator/utils/__init__.py +13 -0
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +110 -0
- django_cfg/modules/django_llm/translator/utils/text_utils.py +114 -0
- django_cfg/modules/django_logging/FIXES_SUMMARY.md +276 -0
- django_cfg/modules/django_logging/LOGGING_GUIDE.md +504 -0
- django_cfg/modules/django_logging/__init__.py +14 -0
- django_cfg/modules/{django_logger.py → django_logging/django_logger.py} +13 -13
- django_cfg/modules/{logger.py → django_logging/logger.py} +14 -4
- django_cfg/modules/django_ngrok/__init__.py +39 -0
- django_cfg/modules/{django_ngrok.py → django_ngrok/service.py} +14 -42
- django_cfg/modules/django_rpc_old/POETRY.md +344 -0
- django_cfg/modules/django_rpc_old/README.md +397 -0
- django_cfg/modules/django_rpc_old/TESTING.md +358 -0
- django_cfg/modules/django_rpc_old/__init__.py +39 -0
- django_cfg/modules/django_rpc_old/client.py +531 -0
- django_cfg/modules/django_rpc_old/config.py +279 -0
- django_cfg/modules/django_rpc_old/exceptions.py +172 -0
- django_cfg/modules/django_tailwind/README.md +478 -0
- django_cfg/modules/django_tailwind/__init__.py +7 -0
- django_cfg/modules/django_tailwind/apps.py +10 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/app.html +5 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +117 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +124 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/theme_toggle.html +54 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/user_menu.html +116 -0
- django_cfg/modules/django_tailwind/templates/django_tailwind/simple.html +46 -0
- django_cfg/modules/django_tailwind/templatetags/__init__.py +1 -0
- django_cfg/modules/django_tailwind/templatetags/tailwind_info.py +185 -0
- django_cfg/modules/django_tasks/__init__.py +29 -0
- django_cfg/modules/django_tasks/factory.py +127 -0
- django_cfg/modules/{django_tasks.py → django_tasks/service.py} +45 -274
- django_cfg/modules/django_tasks/settings.py +107 -0
- django_cfg/modules/django_telegram/__init__.py +29 -0
- django_cfg/modules/{django_telegram.py → django_telegram/service.py} +45 -113
- django_cfg/modules/django_telegram/utils.py +62 -0
- django_cfg/modules/django_twilio/__init__.py +54 -107
- django_cfg/modules/django_twilio/_imports.py +30 -0
- django_cfg/modules/django_twilio/base.py +192 -0
- django_cfg/modules/django_twilio/email_otp.py +227 -0
- django_cfg/modules/django_twilio/sendgrid_service.py +1 -1
- django_cfg/modules/django_twilio/simple_service.py +1 -2
- django_cfg/modules/django_twilio/sms.py +94 -0
- django_cfg/modules/django_twilio/twilio_service.py +2 -3
- django_cfg/modules/django_twilio/unified.py +310 -0
- django_cfg/modules/django_twilio/utils.py +190 -0
- django_cfg/modules/django_twilio/whatsapp.py +137 -0
- django_cfg/modules/django_unfold/callbacks/base.py +198 -7
- django_cfg/modules/django_unfold/callbacks/main.py +102 -10
- django_cfg/modules/django_unfold/dashboard.py +65 -43
- django_cfg/modules/django_unfold/models/config.py +13 -12
- django_cfg/modules/django_unfold/models/navigation.py +8 -3
- django_cfg/modules/django_unfold/models/tabs.py +2 -2
- django_cfg/modules/django_unfold/templates/unfold/helpers/app_list.html +102 -0
- django_cfg/registry/core.py +24 -26
- django_cfg/registry/modules.py +5 -2
- django_cfg/registry/services.py +20 -3
- django_cfg/registry/third_party.py +8 -8
- django_cfg/static/admin/css/dashboard.css +260 -0
- django_cfg/static/admin/js/commands.js +171 -0
- django_cfg/static/admin/js/dashboard.js +126 -0
- django_cfg/templates/admin/components/management_commands.js +375 -0
- django_cfg/templates/admin/components/progress_bar.html +18 -23
- django_cfg/templates/admin/index.html +48 -20
- django_cfg/templates/admin/index_new.html +106 -0
- django_cfg/templates/admin/layouts/base_dashboard.html +60 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +1 -20
- django_cfg/templates/admin/sections/commands_section.html +626 -0
- django_cfg/templates/admin/sections/overview_section.html +112 -0
- django_cfg/templates/admin/sections/stats_section.html +35 -0
- django_cfg/templates/admin/sections/system_section.html +99 -0
- django_cfg/templates/admin/snippets/components/CHARTS_GUIDE.md +322 -0
- django_cfg/templates/admin/snippets/components/activity_tracker.html +85 -47
- django_cfg/templates/admin/snippets/components/charts_section.html +154 -64
- django_cfg/templates/admin/snippets/components/django_commands.html +3 -3
- django_cfg/templates/admin/snippets/components/recent_activity_improved.html +25 -0
- django_cfg/templates/admin/snippets/components/recent_users_table.html +1 -1
- django_cfg/templates/admin/snippets/components/system_metrics.html +179 -93
- django_cfg/templates/admin/snippets/zones/zones_table.html +2 -2
- django_cfg/templatetags/django_cfg.py +7 -1
- django_cfg/utils/smart_defaults.py +4 -4
- django_cfg-1.4.0.dist-info/METADATA +920 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/RECORD +425 -196
- django_cfg/apps/accounts/utils/auth_email_service.py +0 -84
- django_cfg/apps/payments/services/providers/nowpayments/parsers.py +0 -879
- django_cfg/core/generation.py +0 -621
- django_cfg/management/commands/validate_config.py +0 -189
- django_cfg/models/database.py +0 -480
- django_cfg/models/drf.py +0 -272
- django_cfg/models/ngrok.py +0 -122
- django_cfg/models/services.py +0 -440
- django_cfg/models/tasks.py +0 -550
- django_cfg/modules/django_twilio/service.py +0 -942
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/rest_framework/api.html +0 -12
- django_cfg/utils/toolkit.py +0 -703
- django_cfg-1.3.11.dist-info/METADATA +0 -1029
- /django_cfg/apps/accounts/management/commands/{test_otp.py → otp_test.py} +0 -0
- /django_cfg/core/{environment.py → environment/detector.py} +0 -0
- /django_cfg/models/{cors.py → api/cors.py} +0 -0
- /django_cfg/models/{jwt.py → api/jwt.py} +0 -0
- /django_cfg/models/{base.py → base/config.py} +0 -0
- /django_cfg/models/{cfg.py → base/module.py} +0 -0
- /django_cfg/models/{revolution.py → django/revolution.py} +0 -0
- /django_cfg/modules/{dramatiq_setup.py → django_tasks/dramatiq_setup.py} +0 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.11.dist-info → django_cfg-1.4.0.dist-info}/entry_points.txt +0 -0
- {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.
|
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.
|
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
|
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
|
-
|
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
|
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:
|
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
|
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
|
-
|
78
|
-
if
|
79
|
-
return
|
80
|
-
|
81
|
-
raise ValueError("No user provided and no
|
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")
|