django-cfg 1.3.13__py3-none-any.whl → 1.4.3__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/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/agents/examples/__init__.py +3 -0
- django_cfg/apps/agents/examples/simple_example.py +161 -0
- 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/examples/__init__.py +3 -0
- django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
- 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/examples/vehicle_model_example.py +199 -0
- 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_currency/examples/__init__.py +3 -0
- django_cfg/modules/django_currency/examples/example_database_usage.py +144 -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_ipc_client/README.md +346 -0
- django_cfg/modules/django_ipc_client/__init__.py +51 -0
- django_cfg/modules/django_ipc_client/client.py +540 -0
- django_cfg/modules/django_ipc_client/config.py +207 -0
- django_cfg/modules/django_ipc_client/dashboard/README.md +517 -0
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +439 -0
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +11 -0
- django_cfg/modules/django_ipc_client/dashboard/apps.py +22 -0
- django_cfg/modules/django_ipc_client/dashboard/monitor.py +435 -0
- django_cfg/modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js +373 -0
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/base.html +76 -0
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +200 -0
- django_cfg/modules/django_ipc_client/dashboard/urls.py +22 -0
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +9 -0
- django_cfg/modules/django_ipc_client/dashboard/views.py +251 -0
- django_cfg/modules/django_ipc_client/exceptions.py +201 -0
- 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/examples/component_class_example.html +156 -0
- 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.3.dist-info/METADATA +533 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/RECORD +432 -195
- 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.13.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.13.dist-info → django_cfg-1.4.3.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.13.dist-info → django_cfg-1.4.3.dist-info}/licenses/LICENSE +0 -0
django_cfg/models/services.py
DELETED
@@ -1,440 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Service configuration models for django_cfg.
|
3
|
-
|
4
|
-
Following CRITICAL_REQUIREMENTS.md:
|
5
|
-
- No raw Dict/Any usage - everything through Pydantic models
|
6
|
-
- Specialized models for each service type (Email, Telegram, etc.)
|
7
|
-
- Proper validation and type safety
|
8
|
-
- Environment-aware backend selection
|
9
|
-
"""
|
10
|
-
|
11
|
-
from typing import Dict, Optional, Any, Literal, List
|
12
|
-
from pydantic import BaseModel, Field, field_validator, model_validator, EmailStr
|
13
|
-
from pathlib import Path
|
14
|
-
|
15
|
-
from django_cfg.core.exceptions import ConfigurationError, ValidationError
|
16
|
-
|
17
|
-
|
18
|
-
class EmailConfig(BaseModel):
|
19
|
-
"""
|
20
|
-
Type-safe email service configuration.
|
21
|
-
|
22
|
-
Supports SMTP, console, and file backends with automatic selection
|
23
|
-
based on environment and configuration completeness.
|
24
|
-
"""
|
25
|
-
|
26
|
-
model_config = {
|
27
|
-
"str_strip_whitespace": True,
|
28
|
-
"validate_assignment": True,
|
29
|
-
"extra": "forbid",
|
30
|
-
}
|
31
|
-
|
32
|
-
# SMTP settings
|
33
|
-
host: str = Field(
|
34
|
-
default="localhost",
|
35
|
-
description="SMTP server hostname",
|
36
|
-
min_length=1,
|
37
|
-
)
|
38
|
-
|
39
|
-
port: int = Field(
|
40
|
-
default=587,
|
41
|
-
description="SMTP server port",
|
42
|
-
ge=1,
|
43
|
-
le=65535,
|
44
|
-
)
|
45
|
-
|
46
|
-
username: Optional[str] = Field(
|
47
|
-
default=None,
|
48
|
-
description="SMTP username",
|
49
|
-
)
|
50
|
-
|
51
|
-
password: Optional[str] = Field(
|
52
|
-
default=None,
|
53
|
-
description="SMTP password",
|
54
|
-
repr=False, # Don't show in repr for security
|
55
|
-
)
|
56
|
-
|
57
|
-
# Security settings
|
58
|
-
use_tls: bool = Field(
|
59
|
-
default=True,
|
60
|
-
description="Use TLS encryption",
|
61
|
-
)
|
62
|
-
|
63
|
-
use_ssl: bool = Field(
|
64
|
-
default=False,
|
65
|
-
description="Use SSL encryption (alternative to TLS)",
|
66
|
-
)
|
67
|
-
|
68
|
-
# Email settings
|
69
|
-
default_from_email: EmailStr = Field(
|
70
|
-
default="webmaster@localhost",
|
71
|
-
description="Default sender email address",
|
72
|
-
)
|
73
|
-
|
74
|
-
default_from_name: str = Field(
|
75
|
-
default="Django Application",
|
76
|
-
description="Default sender name",
|
77
|
-
max_length=100,
|
78
|
-
)
|
79
|
-
|
80
|
-
# Connection settings
|
81
|
-
timeout: int = Field(
|
82
|
-
default=30,
|
83
|
-
description="SMTP connection timeout in seconds",
|
84
|
-
ge=1,
|
85
|
-
le=300,
|
86
|
-
)
|
87
|
-
|
88
|
-
# File backend settings (for development)
|
89
|
-
file_path: Optional[Path] = Field(
|
90
|
-
default=None,
|
91
|
-
description="File path for file-based email backend",
|
92
|
-
)
|
93
|
-
|
94
|
-
# Backend override (for testing)
|
95
|
-
backend_override: Optional[str] = Field(
|
96
|
-
default=None,
|
97
|
-
description="Override automatic backend selection",
|
98
|
-
exclude=True,
|
99
|
-
)
|
100
|
-
|
101
|
-
@field_validator('port')
|
102
|
-
@classmethod
|
103
|
-
def validate_port(cls, v: int) -> int:
|
104
|
-
"""Validate SMTP port ranges."""
|
105
|
-
# Common SMTP ports
|
106
|
-
common_ports = {25, 465, 587, 2525}
|
107
|
-
|
108
|
-
if v not in common_ports and v < 1024:
|
109
|
-
# Warn about unusual low ports (but don't fail)
|
110
|
-
pass
|
111
|
-
|
112
|
-
return v
|
113
|
-
|
114
|
-
@model_validator(mode='after')
|
115
|
-
def validate_security_settings(self) -> 'EmailConfig':
|
116
|
-
"""Validate email security configuration."""
|
117
|
-
if self.use_tls and self.use_ssl:
|
118
|
-
raise ValueError("Cannot use both TLS and SSL simultaneously")
|
119
|
-
|
120
|
-
# Validate port/security combinations
|
121
|
-
if self.port == 465 and not self.use_ssl:
|
122
|
-
# Port 465 typically uses SSL
|
123
|
-
pass # Just a note, not enforced
|
124
|
-
|
125
|
-
if self.port == 587 and not self.use_tls:
|
126
|
-
# Port 587 typically uses TLS
|
127
|
-
pass # Just a note, not enforced
|
128
|
-
|
129
|
-
# Validate authentication requirements
|
130
|
-
if self.username and not self.password:
|
131
|
-
raise ValueError("Password is required when username is provided")
|
132
|
-
|
133
|
-
return self
|
134
|
-
|
135
|
-
def get_backend_type(self, environment: str, debug: bool) -> str:
|
136
|
-
"""
|
137
|
-
Determine appropriate email backend based on environment.
|
138
|
-
|
139
|
-
Args:
|
140
|
-
environment: Current environment
|
141
|
-
debug: Django DEBUG setting
|
142
|
-
|
143
|
-
Returns:
|
144
|
-
Django email backend class path
|
145
|
-
"""
|
146
|
-
if self.backend_override:
|
147
|
-
return self.backend_override
|
148
|
-
|
149
|
-
# Environment-based backend selection
|
150
|
-
if environment == "testing":
|
151
|
-
return "django.core.mail.backends.locmem.EmailBackend"
|
152
|
-
|
153
|
-
elif environment == "development" or debug:
|
154
|
-
# Development: Use SMTP if configured, otherwise console
|
155
|
-
if self.username and self.password:
|
156
|
-
return "django.core.mail.backends.smtp.EmailBackend"
|
157
|
-
elif self.file_path:
|
158
|
-
return "django.core.mail.backends.filebased.EmailBackend"
|
159
|
-
else:
|
160
|
-
return "django.core.mail.backends.console.EmailBackend"
|
161
|
-
|
162
|
-
elif environment in ("production", "staging"):
|
163
|
-
# Production should use SMTP if configured
|
164
|
-
if self.username and self.password:
|
165
|
-
return "django.core.mail.backends.smtp.EmailBackend"
|
166
|
-
else:
|
167
|
-
# Fallback to console for incomplete SMTP config
|
168
|
-
return "django.core.mail.backends.console.EmailBackend"
|
169
|
-
|
170
|
-
else:
|
171
|
-
# Default to SMTP if credentials available
|
172
|
-
if self.username and self.password:
|
173
|
-
return "django.core.mail.backends.smtp.EmailBackend"
|
174
|
-
else:
|
175
|
-
return "django.core.mail.backends.console.EmailBackend"
|
176
|
-
|
177
|
-
def to_django_config(self, environment: str, debug: bool) -> Dict[str, Any]:
|
178
|
-
"""
|
179
|
-
Convert to Django email configuration.
|
180
|
-
|
181
|
-
Args:
|
182
|
-
environment: Current environment
|
183
|
-
debug: Django DEBUG setting
|
184
|
-
|
185
|
-
Returns:
|
186
|
-
Django email settings dictionary
|
187
|
-
"""
|
188
|
-
backend = self.get_backend_type(environment, debug)
|
189
|
-
|
190
|
-
config = {
|
191
|
-
'EMAIL_BACKEND': backend,
|
192
|
-
'DEFAULT_FROM_EMAIL': str(self.default_from_email),
|
193
|
-
'EMAIL_TIMEOUT': self.timeout,
|
194
|
-
}
|
195
|
-
|
196
|
-
# Add sender name to default from email if specified
|
197
|
-
if self.default_from_name and self.default_from_name != "Django Application":
|
198
|
-
config['DEFAULT_FROM_EMAIL'] = f"{self.default_from_name} <{self.default_from_email}>"
|
199
|
-
|
200
|
-
# Backend-specific settings
|
201
|
-
if backend == "django.core.mail.backends.smtp.EmailBackend":
|
202
|
-
config.update({
|
203
|
-
'EMAIL_HOST': self.host,
|
204
|
-
'EMAIL_PORT': self.port,
|
205
|
-
'EMAIL_USE_TLS': self.use_tls,
|
206
|
-
'EMAIL_USE_SSL': self.use_ssl,
|
207
|
-
})
|
208
|
-
|
209
|
-
if self.username:
|
210
|
-
config['EMAIL_HOST_USER'] = self.username
|
211
|
-
|
212
|
-
if self.password:
|
213
|
-
config['EMAIL_HOST_PASSWORD'] = self.password
|
214
|
-
|
215
|
-
elif backend == "django.core.mail.backends.filebased.EmailBackend":
|
216
|
-
if self.file_path:
|
217
|
-
config['EMAIL_FILE_PATH'] = str(self.file_path)
|
218
|
-
else:
|
219
|
-
config['EMAIL_FILE_PATH'] = "tmp/app-messages"
|
220
|
-
|
221
|
-
return config
|
222
|
-
|
223
|
-
|
224
|
-
class TelegramConfig(BaseModel):
|
225
|
-
"""
|
226
|
-
Type-safe Telegram bot configuration.
|
227
|
-
|
228
|
-
Supports Telegram Bot API for notifications and alerts.
|
229
|
-
"""
|
230
|
-
|
231
|
-
model_config = {
|
232
|
-
"str_strip_whitespace": True,
|
233
|
-
"validate_assignment": True,
|
234
|
-
"extra": "forbid",
|
235
|
-
}
|
236
|
-
|
237
|
-
# Bot configuration
|
238
|
-
bot_token: str = Field(
|
239
|
-
...,
|
240
|
-
description="Telegram bot token from @BotFather",
|
241
|
-
min_length=10,
|
242
|
-
repr=False, # Don't show in repr for security
|
243
|
-
)
|
244
|
-
|
245
|
-
chat_id: int = Field(
|
246
|
-
...,
|
247
|
-
description="Telegram chat ID for notifications",
|
248
|
-
)
|
249
|
-
|
250
|
-
# Message settings
|
251
|
-
parse_mode: Literal["HTML", "Markdown", "MarkdownV2", None] = Field(
|
252
|
-
default="HTML",
|
253
|
-
description="Message parse mode",
|
254
|
-
)
|
255
|
-
|
256
|
-
disable_notification: bool = Field(
|
257
|
-
default=False,
|
258
|
-
description="Send messages silently",
|
259
|
-
)
|
260
|
-
|
261
|
-
disable_web_page_preview: bool = Field(
|
262
|
-
default=False,
|
263
|
-
description="Disable link previews in messages",
|
264
|
-
)
|
265
|
-
|
266
|
-
# Connection settings
|
267
|
-
timeout: int = Field(
|
268
|
-
default=30,
|
269
|
-
description="Request timeout in seconds",
|
270
|
-
ge=1,
|
271
|
-
le=300,
|
272
|
-
)
|
273
|
-
|
274
|
-
# Webhook settings (optional)
|
275
|
-
webhook_url: Optional[str] = Field(
|
276
|
-
default=None,
|
277
|
-
description="Webhook URL for receiving updates",
|
278
|
-
)
|
279
|
-
|
280
|
-
webhook_secret: Optional[str] = Field(
|
281
|
-
default=None,
|
282
|
-
description="Webhook secret token",
|
283
|
-
repr=False,
|
284
|
-
)
|
285
|
-
|
286
|
-
# Rate limiting
|
287
|
-
max_retries: int = Field(
|
288
|
-
default=3,
|
289
|
-
description="Maximum retry attempts for failed requests",
|
290
|
-
ge=0,
|
291
|
-
le=10,
|
292
|
-
)
|
293
|
-
|
294
|
-
retry_delay: float = Field(
|
295
|
-
default=1.0,
|
296
|
-
description="Delay between retry attempts in seconds",
|
297
|
-
ge=0.1,
|
298
|
-
le=60.0,
|
299
|
-
)
|
300
|
-
|
301
|
-
@field_validator('bot_token')
|
302
|
-
@classmethod
|
303
|
-
def validate_bot_token(cls, v: str) -> str:
|
304
|
-
"""Validate Telegram bot token format."""
|
305
|
-
# Basic format validation: should be digits:alphanumeric
|
306
|
-
if ':' not in v:
|
307
|
-
raise ValueError("Invalid bot token format: missing ':' separator")
|
308
|
-
|
309
|
-
parts = v.split(':', 1)
|
310
|
-
if len(parts) != 2:
|
311
|
-
raise ValueError("Invalid bot token format: should be 'bot_id:token'")
|
312
|
-
|
313
|
-
bot_id, token = parts
|
314
|
-
|
315
|
-
# Validate bot ID (should be numeric)
|
316
|
-
if not bot_id.isdigit():
|
317
|
-
raise ValueError("Invalid bot token: bot ID must be numeric")
|
318
|
-
|
319
|
-
# Validate token length (should be around 35 characters)
|
320
|
-
if len(token) < 30:
|
321
|
-
raise ValueError("Invalid bot token: token too short")
|
322
|
-
|
323
|
-
return v
|
324
|
-
|
325
|
-
@field_validator('chat_id')
|
326
|
-
@classmethod
|
327
|
-
def validate_chat_id(cls, v: int) -> int:
|
328
|
-
"""Validate Telegram chat ID."""
|
329
|
-
# Chat IDs can be negative (groups/channels) or positive (users)
|
330
|
-
# Just check it's not zero
|
331
|
-
if v == 0:
|
332
|
-
raise ValueError("Chat ID cannot be zero")
|
333
|
-
|
334
|
-
return v
|
335
|
-
|
336
|
-
@field_validator('webhook_url')
|
337
|
-
@classmethod
|
338
|
-
def validate_webhook_url(cls, v: Optional[str]) -> Optional[str]:
|
339
|
-
"""Validate webhook URL format."""
|
340
|
-
if v is None:
|
341
|
-
return v
|
342
|
-
|
343
|
-
if not v.startswith('https://'):
|
344
|
-
raise ValueError("Webhook URL must use HTTPS")
|
345
|
-
|
346
|
-
from urllib.parse import urlparse
|
347
|
-
try:
|
348
|
-
parsed = urlparse(v)
|
349
|
-
if not parsed.netloc:
|
350
|
-
raise ValueError("Invalid webhook URL: missing domain")
|
351
|
-
except Exception as e:
|
352
|
-
raise ValueError(f"Invalid webhook URL: {e}") from e
|
353
|
-
|
354
|
-
return v
|
355
|
-
|
356
|
-
def to_config_dict(self) -> Dict[str, Any]:
|
357
|
-
"""
|
358
|
-
Convert to configuration dictionary.
|
359
|
-
|
360
|
-
Returns:
|
361
|
-
Telegram configuration dictionary
|
362
|
-
"""
|
363
|
-
config = {
|
364
|
-
'bot_token': self.bot_token,
|
365
|
-
'chat_id': self.chat_id,
|
366
|
-
'parse_mode': self.parse_mode,
|
367
|
-
'disable_notification': self.disable_notification,
|
368
|
-
'disable_web_page_preview': self.disable_web_page_preview,
|
369
|
-
'timeout': self.timeout,
|
370
|
-
'max_retries': self.max_retries,
|
371
|
-
'retry_delay': self.retry_delay,
|
372
|
-
}
|
373
|
-
|
374
|
-
if self.webhook_url:
|
375
|
-
config['webhook_url'] = self.webhook_url
|
376
|
-
|
377
|
-
if self.webhook_secret:
|
378
|
-
config['webhook_secret'] = self.webhook_secret
|
379
|
-
|
380
|
-
return config
|
381
|
-
|
382
|
-
|
383
|
-
class ServiceConfig(BaseModel):
|
384
|
-
"""
|
385
|
-
Generic service configuration for custom services.
|
386
|
-
|
387
|
-
This is a fallback for services that don't have specialized models.
|
388
|
-
Prefer specific models like EmailConfig, TelegramConfig when available.
|
389
|
-
"""
|
390
|
-
|
391
|
-
model_config = {
|
392
|
-
"str_strip_whitespace": True,
|
393
|
-
"validate_assignment": True,
|
394
|
-
"extra": "allow", # Allow additional fields for flexibility
|
395
|
-
}
|
396
|
-
|
397
|
-
name: str = Field(
|
398
|
-
...,
|
399
|
-
description="Service name",
|
400
|
-
min_length=1,
|
401
|
-
max_length=50,
|
402
|
-
)
|
403
|
-
|
404
|
-
enabled: bool = Field(
|
405
|
-
default=True,
|
406
|
-
description="Whether service is enabled",
|
407
|
-
)
|
408
|
-
|
409
|
-
config: Dict[str, Any] = Field(
|
410
|
-
default_factory=dict,
|
411
|
-
description="Service-specific configuration",
|
412
|
-
)
|
413
|
-
|
414
|
-
@field_validator('name')
|
415
|
-
@classmethod
|
416
|
-
def validate_name(cls, v: str) -> str:
|
417
|
-
"""Validate service name format."""
|
418
|
-
if not v.replace('_', '').replace('-', '').isalnum():
|
419
|
-
raise ValueError(
|
420
|
-
"Service name must contain only alphanumeric characters, "
|
421
|
-
"underscores, and hyphens"
|
422
|
-
)
|
423
|
-
|
424
|
-
return v
|
425
|
-
|
426
|
-
def to_config_dict(self) -> Dict[str, Any]:
|
427
|
-
"""Convert to configuration dictionary."""
|
428
|
-
return {
|
429
|
-
'name': self.name,
|
430
|
-
'enabled': self.enabled,
|
431
|
-
**self.config,
|
432
|
-
}
|
433
|
-
|
434
|
-
|
435
|
-
# Export all models
|
436
|
-
__all__ = [
|
437
|
-
"EmailConfig",
|
438
|
-
"TelegramConfig",
|
439
|
-
"ServiceConfig",
|
440
|
-
]
|