django-cfg 1.4.21__py3-none-any.whl → 1.4.24__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 +4 -4
- django_cfg/apps/accounts/__init__.py +1 -1
- django_cfg/apps/accounts/__models.py +30 -29
- django_cfg/apps/accounts/admin/__init__.py +14 -3
- django_cfg/apps/accounts/admin/activity_admin.py +19 -19
- django_cfg/apps/accounts/admin/filters.py +7 -6
- django_cfg/apps/accounts/admin/group_admin.py +10 -16
- django_cfg/apps/accounts/admin/inlines.py +21 -19
- django_cfg/apps/accounts/admin/otp_admin.py +12 -12
- django_cfg/apps/accounts/admin/registration_admin.py +24 -24
- django_cfg/apps/accounts/admin/resources.py +49 -48
- django_cfg/apps/accounts/admin/twilio_admin.py +37 -37
- django_cfg/apps/accounts/admin/user_admin.py +45 -41
- django_cfg/apps/accounts/management/commands/otp_test.py +11 -11
- django_cfg/apps/accounts/managers/__init__.py +1 -1
- django_cfg/apps/accounts/managers/user_manager.py +6 -7
- django_cfg/apps/accounts/migrations/0001_initial.py +3 -2
- django_cfg/apps/accounts/models/__init__.py +15 -16
- django_cfg/apps/accounts/models/activity.py +5 -5
- django_cfg/apps/accounts/models/integrations.py +15 -15
- django_cfg/apps/accounts/models/registration.py +3 -2
- django_cfg/apps/accounts/models/user.py +3 -2
- django_cfg/apps/accounts/serializers/__init__.py +10 -3
- django_cfg/apps/accounts/serializers/otp.py +5 -4
- django_cfg/apps/accounts/serializers/profile.py +4 -5
- django_cfg/apps/accounts/serializers/webhook.py +13 -13
- django_cfg/apps/accounts/services/activity_service.py +13 -12
- django_cfg/apps/accounts/services/otp_service.py +16 -14
- django_cfg/apps/accounts/signals.py +18 -16
- django_cfg/apps/accounts/urls.py +10 -5
- django_cfg/apps/accounts/utils/notifications.py +22 -22
- django_cfg/apps/accounts/views/__init__.py +1 -1
- django_cfg/apps/accounts/views/otp.py +15 -14
- django_cfg/apps/accounts/views/profile.py +14 -10
- django_cfg/apps/accounts/views/webhook.py +46 -48
- django_cfg/apps/agents/__init__.py +3 -3
- django_cfg/apps/agents/admin/__init__.py +1 -1
- django_cfg/apps/agents/admin/execution_admin.py +68 -72
- django_cfg/apps/agents/admin/registry_admin.py +50 -54
- django_cfg/apps/agents/admin/toolsets_admin.py +63 -67
- django_cfg/apps/agents/apps.py +3 -3
- django_cfg/apps/agents/core/__init__.py +4 -4
- django_cfg/apps/agents/core/dependencies.py +24 -23
- django_cfg/apps/agents/core/django_agent.py +41 -39
- django_cfg/apps/agents/core/exceptions.py +12 -12
- django_cfg/apps/agents/core/models.py +16 -15
- django_cfg/apps/agents/core/orchestrator.py +58 -58
- django_cfg/apps/agents/examples/simple_example.py +24 -19
- django_cfg/apps/agents/integration/__init__.py +1 -1
- django_cfg/apps/agents/integration/middleware.py +12 -11
- django_cfg/apps/agents/integration/registry.py +52 -49
- django_cfg/apps/agents/integration/signals.py +5 -5
- django_cfg/apps/agents/management/commands/create_agent.py +39 -38
- django_cfg/apps/agents/management/commands/orchestrator_status.py +40 -39
- django_cfg/apps/agents/managers/__init__.py +8 -3
- django_cfg/apps/agents/managers/execution.py +42 -41
- django_cfg/apps/agents/managers/registry.py +40 -39
- django_cfg/apps/agents/managers/toolsets.py +87 -86
- django_cfg/apps/agents/migrations/0001_initial.py +2 -1
- django_cfg/apps/agents/models/__init__.py +2 -2
- django_cfg/apps/agents/models/execution.py +43 -42
- django_cfg/apps/agents/models/registry.py +46 -45
- django_cfg/apps/agents/models/toolsets.py +63 -62
- django_cfg/apps/agents/patterns/__init__.py +5 -5
- django_cfg/apps/agents/patterns/content_agents.py +17 -16
- django_cfg/apps/agents/toolsets/__init__.py +3 -3
- django_cfg/apps/agents/toolsets/cache_toolset.py +56 -55
- django_cfg/apps/agents/toolsets/django_toolset.py +43 -42
- django_cfg/apps/agents/toolsets/file_toolset.py +64 -63
- django_cfg/apps/agents/toolsets/orm_toolset.py +75 -74
- django_cfg/apps/agents/urls.py +3 -2
- django_cfg/apps/api/commands/urls.py +1 -0
- django_cfg/apps/api/commands/views.py +23 -26
- django_cfg/apps/api/endpoints/checker.py +5 -4
- django_cfg/apps/api/endpoints/drf_views.py +2 -2
- django_cfg/apps/api/endpoints/tests.py +6 -5
- django_cfg/apps/api/endpoints/urls.py +2 -1
- django_cfg/apps/api/endpoints/views.py +1 -0
- django_cfg/apps/api/health/drf_views.py +6 -6
- django_cfg/apps/api/health/urls.py +2 -1
- django_cfg/apps/api/health/views.py +41 -41
- django_cfg/{modules/django_ipc_client → apps/ipc}/__init__.py +6 -6
- django_cfg/apps/ipc/apps.py +28 -0
- django_cfg/apps/ipc/serializers/__init__.py +19 -0
- django_cfg/apps/ipc/serializers/serializers.py +229 -0
- django_cfg/apps/ipc/services/__init__.py +7 -0
- django_cfg/apps/ipc/services/client/__init__.py +23 -0
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/client.py +7 -6
- django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/exceptions.py +1 -1
- django_cfg/{modules/django_ipc_client/dashboard → apps/ipc/services}/monitor.py +36 -7
- django_cfg/{modules/django_ipc_client/dashboard/static/django_ipc_dashboard/js/dashboard.js → apps/ipc/static/django_cfg_ipc/js/dashboard.mjs} +131 -63
- django_cfg/{modules/django_ipc_client/dashboard/templates/django_ipc_dashboard → apps/ipc/templates/django_cfg_ipc}/base.html +5 -10
- django_cfg/apps/ipc/templates/django_cfg_ipc/dashboard.html +202 -0
- django_cfg/apps/ipc/urls.py +21 -0
- django_cfg/apps/ipc/urls_admin.py +20 -0
- django_cfg/apps/ipc/views/__init__.py +8 -0
- django_cfg/apps/ipc/views/dashboard.py +15 -0
- django_cfg/apps/ipc/views/viewsets.py +245 -0
- django_cfg/apps/knowbase/admin/__init__.py +2 -2
- django_cfg/apps/knowbase/admin/actions/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/actions/visibility_actions.py +2 -1
- django_cfg/apps/knowbase/admin/archive_admin.py +81 -84
- django_cfg/apps/knowbase/admin/chat_admin.py +70 -72
- django_cfg/apps/knowbase/admin/document_admin.py +10 -11
- django_cfg/apps/knowbase/admin/external_data_admin.py +69 -71
- django_cfg/apps/knowbase/admin/helpers/__init__.py +1 -1
- django_cfg/apps/knowbase/admin/helpers/configs.py +2 -2
- django_cfg/apps/knowbase/admin/helpers/statistics.py +1 -1
- django_cfg/apps/knowbase/apps.py +13 -13
- django_cfg/apps/knowbase/config/__init__.py +7 -6
- django_cfg/apps/knowbase/config/constance_fields.py +14 -12
- django_cfg/apps/knowbase/config/constance_settings.py +32 -31
- django_cfg/apps/knowbase/config/settings.py +28 -28
- django_cfg/apps/knowbase/examples/external_data_usage.py +35 -32
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +33 -32
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +11 -13
- django_cfg/apps/knowbase/managers/__init__.py +2 -2
- django_cfg/apps/knowbase/managers/archive.py +86 -85
- django_cfg/apps/knowbase/managers/base.py +5 -5
- django_cfg/apps/knowbase/managers/chat.py +29 -28
- django_cfg/apps/knowbase/managers/document.py +39 -39
- django_cfg/apps/knowbase/managers/external_data.py +74 -73
- django_cfg/apps/knowbase/migrations/0001_initial.py +2 -1
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +2 -1
- django_cfg/apps/knowbase/mixins/__init__.py +4 -4
- django_cfg/apps/knowbase/mixins/config/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/config/meta_config.py +1 -1
- django_cfg/apps/knowbase/mixins/config.py +19 -18
- django_cfg/apps/knowbase/mixins/creator.py +7 -7
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +29 -28
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +6 -5
- django_cfg/apps/knowbase/mixins/generators/__init__.py +1 -1
- django_cfg/apps/knowbase/mixins/generators/content_generator.py +2 -2
- django_cfg/apps/knowbase/mixins/service.py +47 -45
- django_cfg/apps/knowbase/models/__init__.py +7 -7
- django_cfg/apps/knowbase/models/archive.py +72 -72
- django_cfg/apps/knowbase/models/base.py +12 -13
- django_cfg/apps/knowbase/models/chat.py +20 -19
- django_cfg/apps/knowbase/models/document.py +37 -35
- django_cfg/apps/knowbase/models/external_data.py +41 -42
- django_cfg/apps/knowbase/serializers/__init__.py +7 -7
- django_cfg/apps/knowbase/serializers/archive_serializers.py +50 -42
- django_cfg/apps/knowbase/serializers/chat_serializers.py +16 -15
- django_cfg/apps/knowbase/serializers/document_serializers.py +13 -12
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +31 -31
- django_cfg/apps/knowbase/serializers/public_serializers.py +10 -9
- django_cfg/apps/knowbase/services/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/__init__.py +7 -7
- django_cfg/apps/knowbase/services/archive/analyzers/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/analyzers/tag_generator.py +1 -1
- django_cfg/apps/knowbase/services/archive/archive_service.py +109 -112
- django_cfg/apps/knowbase/services/archive/chunking/__init__.py +3 -3
- django_cfg/apps/knowbase/services/archive/chunking/base.py +1 -0
- django_cfg/apps/knowbase/services/archive/chunking/json_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking/markdown_chunker.py +5 -4
- django_cfg/apps/knowbase/services/archive/chunking/python_chunker.py +6 -5
- django_cfg/apps/knowbase/services/archive/chunking/text_chunker.py +4 -3
- django_cfg/apps/knowbase/services/archive/chunking_service.py +3 -7
- django_cfg/apps/knowbase/services/archive/context/__init__.py +1 -1
- django_cfg/apps/knowbase/services/archive/context/builders.py +2 -1
- django_cfg/apps/knowbase/services/archive/context/models.py +2 -1
- django_cfg/apps/knowbase/services/archive/exceptions.py +5 -5
- django_cfg/apps/knowbase/services/archive/extraction_service.py +111 -110
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +80 -77
- django_cfg/apps/knowbase/services/base.py +11 -9
- django_cfg/apps/knowbase/services/chat_service.py +40 -39
- django_cfg/apps/knowbase/services/document_service.py +28 -27
- django_cfg/apps/knowbase/services/embedding/__init__.py +9 -9
- django_cfg/apps/knowbase/services/embedding/async_processor.py +38 -40
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +45 -42
- django_cfg/apps/knowbase/services/embedding/batch_result.py +7 -6
- django_cfg/apps/knowbase/services/embedding/models.py +52 -51
- django_cfg/apps/knowbase/services/embedding/processors.py +24 -23
- django_cfg/apps/knowbase/services/embedding/utils.py +17 -17
- django_cfg/apps/knowbase/services/prompt_builder.py +24 -23
- django_cfg/apps/knowbase/services/search_service.py +52 -49
- django_cfg/apps/knowbase/signals/__init__.py +2 -5
- django_cfg/apps/knowbase/signals/archive_signals.py +35 -34
- django_cfg/apps/knowbase/signals/chat_signals.py +6 -5
- django_cfg/apps/knowbase/signals/document_signals.py +22 -22
- django_cfg/apps/knowbase/signals/external_data_signals.py +22 -22
- django_cfg/apps/knowbase/tasks/__init__.py +6 -7
- django_cfg/apps/knowbase/tasks/archive_tasks.py +41 -41
- django_cfg/apps/knowbase/tasks/document_processing.py +49 -44
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +46 -44
- django_cfg/apps/knowbase/tasks/maintenance.py +26 -24
- django_cfg/apps/knowbase/urls.py +3 -2
- django_cfg/apps/knowbase/urls_admin.py +6 -3
- django_cfg/apps/knowbase/urls_system.py +4 -5
- django_cfg/apps/knowbase/utils/chunk_settings.py +22 -20
- django_cfg/apps/knowbase/utils/text_processing.py +76 -75
- django_cfg/apps/knowbase/utils/validation.py +9 -9
- django_cfg/apps/knowbase/views/__init__.py +5 -5
- django_cfg/apps/knowbase/views/archive_views.py +90 -87
- django_cfg/apps/knowbase/views/base.py +9 -12
- django_cfg/apps/knowbase/views/chat_views.py +32 -32
- django_cfg/apps/knowbase/views/document_views.py +27 -28
- django_cfg/apps/knowbase/views/public_views.py +19 -19
- django_cfg/apps/leads/admin/leads_admin.py +41 -45
- django_cfg/apps/leads/admin/resources.py +14 -14
- django_cfg/apps/leads/admin.py +7 -9
- django_cfg/apps/leads/apps.py +1 -1
- django_cfg/apps/leads/models.py +17 -17
- django_cfg/apps/leads/serializers.py +5 -4
- django_cfg/apps/leads/signals.py +7 -7
- django_cfg/apps/leads/tests.py +47 -47
- django_cfg/apps/leads/urls.py +2 -2
- django_cfg/apps/leads/views.py +11 -11
- django_cfg/apps/maintenance/__init__.py +3 -3
- django_cfg/apps/maintenance/admin/__init__.py +1 -1
- django_cfg/apps/maintenance/admin/api_key_admin.py +36 -36
- django_cfg/apps/maintenance/admin/log_admin.py +35 -37
- django_cfg/apps/maintenance/admin/scheduled_admin.py +47 -51
- django_cfg/apps/maintenance/admin/site_admin.py +49 -52
- django_cfg/apps/maintenance/apps.py +2 -2
- django_cfg/apps/maintenance/management/commands/maintenance.py +53 -52
- django_cfg/apps/maintenance/management/commands/process_scheduled_maintenance.py +44 -44
- django_cfg/apps/maintenance/management/commands/sync_cloudflare.py +32 -32
- django_cfg/apps/maintenance/managers/__init__.py +1 -1
- django_cfg/apps/maintenance/managers/cloudflare_site_manager.py +39 -38
- django_cfg/apps/maintenance/managers/maintenance_log_manager.py +32 -31
- django_cfg/apps/maintenance/migrations/0001_initial.py +1 -0
- django_cfg/apps/maintenance/models/__init__.py +2 -2
- django_cfg/apps/maintenance/models/cloudflare_api_key.py +15 -15
- django_cfg/apps/maintenance/models/cloudflare_site.py +24 -22
- django_cfg/apps/maintenance/models/maintenance_log.py +15 -14
- django_cfg/apps/maintenance/models/scheduled_maintenance.py +53 -52
- django_cfg/apps/maintenance/services/__init__.py +3 -3
- django_cfg/apps/maintenance/services/bulk_operations_service.py +68 -68
- django_cfg/apps/maintenance/services/maintenance_service.py +59 -58
- django_cfg/apps/maintenance/services/scheduled_maintenance_service.py +52 -52
- django_cfg/apps/maintenance/services/site_sync_service.py +64 -65
- django_cfg/apps/maintenance/utils/__init__.py +1 -1
- django_cfg/apps/maintenance/utils/retry_utils.py +17 -17
- django_cfg/apps/newsletter/admin/__init__.py +12 -16
- django_cfg/apps/newsletter/admin/newsletter_admin.py +90 -87
- django_cfg/apps/newsletter/admin/resources.py +29 -29
- django_cfg/apps/newsletter/admin.py +39 -32
- django_cfg/apps/newsletter/management/commands/test_newsletter.py +3 -3
- django_cfg/apps/newsletter/managers/__init__.py +1 -1
- django_cfg/apps/newsletter/migrations/0001_initial.py +2 -1
- django_cfg/apps/newsletter/models.py +34 -33
- django_cfg/apps/newsletter/serializers.py +13 -13
- django_cfg/apps/newsletter/services/email_service.py +42 -40
- django_cfg/apps/newsletter/signals.py +4 -3
- django_cfg/apps/newsletter/urls.py +7 -7
- django_cfg/apps/newsletter/views/__init__.py +14 -19
- django_cfg/apps/newsletter/views/campaigns.py +19 -19
- django_cfg/apps/newsletter/views/emails.py +20 -20
- django_cfg/apps/newsletter/views/newsletters.py +5 -5
- django_cfg/apps/newsletter/views/subscriptions.py +24 -24
- django_cfg/apps/newsletter/views/tracking.py +6 -5
- django_cfg/apps/payments/admin/__init__.py +6 -5
- django_cfg/apps/payments/admin/api_keys_admin.py +43 -45
- django_cfg/apps/payments/admin/balance_admin.py +41 -47
- django_cfg/apps/payments/admin/currencies_admin.py +60 -62
- django_cfg/apps/payments/admin/endpoint_groups_admin.py +14 -28
- django_cfg/apps/payments/admin/filters.py +59 -59
- django_cfg/apps/payments/admin/networks_admin.py +36 -50
- django_cfg/apps/payments/admin/payments_admin.py +47 -49
- django_cfg/apps/payments/admin/subscriptions_admin.py +30 -32
- django_cfg/apps/payments/admin/tariffs_admin.py +37 -42
- django_cfg/apps/payments/admin_interface/serializers/__init__.py +12 -13
- django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +28 -27
- django_cfg/apps/payments/admin_interface/serializers/webhook_serializers.py +4 -5
- django_cfg/apps/payments/admin_interface/templates/payments/base.html +407 -3
- django_cfg/apps/payments/admin_interface/templates/payments/components/ngrok_status.html +13 -13
- django_cfg/apps/payments/admin_interface/templates/payments/payment_dashboard.html +5 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +105 -49
- django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +4 -1
- django_cfg/apps/payments/admin_interface/templates/payments/payment_list.html +16 -8
- django_cfg/apps/payments/admin_interface/templates/payments/webhook_dashboard.html +16 -8
- django_cfg/apps/payments/admin_interface/views/__init__.py +8 -9
- django_cfg/apps/payments/admin_interface/views/api/__init__.py +3 -3
- django_cfg/apps/payments/admin_interface/views/api/payments.py +52 -54
- django_cfg/apps/payments/admin_interface/views/api/stats.py +33 -30
- django_cfg/apps/payments/admin_interface/views/api/users.py +10 -11
- django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +46 -51
- django_cfg/apps/payments/admin_interface/views/api/webhook_public.py +9 -9
- django_cfg/apps/payments/admin_interface/views/base.py +17 -19
- django_cfg/apps/payments/admin_interface/views/dashboard.py +10 -10
- django_cfg/apps/payments/admin_interface/views/forms.py +21 -20
- django_cfg/apps/payments/apps.py +7 -6
- django_cfg/apps/payments/config/__init__.py +4 -4
- django_cfg/apps/payments/config/django_cfg_integration.py +22 -21
- django_cfg/apps/payments/config/helpers.py +14 -12
- django_cfg/apps/payments/management/commands/cleanup_expired_data.py +85 -86
- django_cfg/apps/payments/management/commands/currency_stats.py +84 -87
- django_cfg/apps/payments/management/commands/manage_currencies.py +59 -58
- django_cfg/apps/payments/management/commands/manage_providers.py +103 -105
- django_cfg/apps/payments/management/commands/process_pending_payments.py +67 -70
- django_cfg/apps/payments/management/commands/test_providers.py +83 -84
- django_cfg/apps/payments/middleware/__init__.py +1 -1
- django_cfg/apps/payments/middleware/api_access.py +77 -78
- django_cfg/apps/payments/middleware/rate_limiting.py +72 -72
- django_cfg/apps/payments/middleware/usage_tracking.py +66 -64
- django_cfg/apps/payments/migrations/0001_initial.py +2 -1
- django_cfg/apps/payments/models/__init__.py +11 -12
- django_cfg/apps/payments/models/api_keys.py +29 -27
- django_cfg/apps/payments/models/balance.py +38 -38
- django_cfg/apps/payments/models/base.py +12 -11
- django_cfg/apps/payments/models/currencies.py +53 -52
- django_cfg/apps/payments/models/managers/__init__.py +13 -14
- django_cfg/apps/payments/models/managers/api_key_managers.py +55 -53
- django_cfg/apps/payments/models/managers/balance_managers.py +98 -97
- django_cfg/apps/payments/models/managers/currency_managers.py +70 -69
- django_cfg/apps/payments/models/managers/payment_managers.py +113 -111
- django_cfg/apps/payments/models/managers/subscription_managers.py +99 -97
- django_cfg/apps/payments/models/payments.py +167 -73
- django_cfg/apps/payments/models/subscriptions.py +56 -54
- django_cfg/apps/payments/models/tariffs.py +35 -34
- django_cfg/apps/payments/services/__init__.py +33 -36
- django_cfg/apps/payments/services/cache/__init__.py +7 -1
- django_cfg/apps/payments/services/cache_service/__init__.py +22 -20
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +6 -5
- django_cfg/apps/payments/services/cache_service/interfaces.py +5 -5
- django_cfg/apps/payments/services/cache_service/keys.py +8 -8
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +8 -7
- django_cfg/apps/payments/services/cache_service/simple_cache.py +17 -14
- django_cfg/apps/payments/services/core/__init__.py +3 -3
- django_cfg/apps/payments/services/core/balance_service.py +69 -65
- django_cfg/apps/payments/services/core/base.py +25 -22
- django_cfg/apps/payments/services/core/currency/__init__.py +1 -1
- django_cfg/apps/payments/services/core/currency/currency_converter.py +2 -0
- django_cfg/apps/payments/services/core/currency_service.py +68 -66
- django_cfg/apps/payments/services/core/operations/__init__.py +1 -1
- django_cfg/apps/payments/services/core/operations/payment_canceller.py +2 -1
- django_cfg/apps/payments/services/core/operations/payment_creator.py +2 -1
- django_cfg/apps/payments/services/core/operations/status_checker.py +2 -1
- django_cfg/apps/payments/services/core/payment_service.py +10 -7
- django_cfg/apps/payments/services/core/providers/provider_client.py +2 -2
- django_cfg/apps/payments/services/core/subscription_service.py +77 -74
- django_cfg/apps/payments/services/core/utils/data_converter.py +1 -0
- django_cfg/apps/payments/services/core/utils/statistics_calculator.py +1 -0
- django_cfg/apps/payments/services/core/webhook_service.py +67 -63
- django_cfg/apps/payments/services/integrations/__init__.py +3 -3
- django_cfg/apps/payments/services/integrations/ngrok_service.py +1 -0
- django_cfg/apps/payments/services/integrations/providers_config.py +3 -2
- django_cfg/apps/payments/services/providers/base.py +59 -57
- django_cfg/apps/payments/services/providers/models/__init__.py +7 -14
- django_cfg/apps/payments/services/providers/models/base.py +15 -15
- django_cfg/apps/payments/services/providers/models/providers.py +13 -12
- django_cfg/apps/payments/services/providers/models/universal.py +6 -5
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -4
- django_cfg/apps/payments/services/providers/nowpayments/config.py +9 -8
- django_cfg/apps/payments/services/providers/nowpayments/models.py +15 -15
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/__init__.py +2 -2
- django_cfg/apps/payments/services/providers/nowpayments/parsers/data/patterns.py +26 -26
- django_cfg/apps/payments/services/providers/nowpayments/parsers/parser.py +3 -2
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +95 -99
- django_cfg/apps/payments/services/providers/nowpayments/sync.py +41 -40
- django_cfg/apps/payments/services/providers/registry.py +65 -63
- django_cfg/apps/payments/services/providers/sync_service.py +50 -50
- django_cfg/apps/payments/services/types/__init__.py +21 -22
- django_cfg/apps/payments/services/types/data.py +14 -13
- django_cfg/apps/payments/services/types/requests.py +21 -22
- django_cfg/apps/payments/services/types/responses.py +16 -15
- django_cfg/apps/payments/services/types/webhooks.py +30 -30
- django_cfg/apps/payments/signals/__init__.py +4 -6
- django_cfg/apps/payments/signals/api_key_signals.py +33 -32
- django_cfg/apps/payments/signals/balance_signals.py +28 -26
- django_cfg/apps/payments/signals/payment_signals.py +29 -28
- django_cfg/apps/payments/signals/subscription_signals.py +39 -38
- django_cfg/apps/payments/static/payments/js/ngrok-status.js +12 -8
- django_cfg/apps/payments/static/payments/js/payment-detail.js +1 -1
- django_cfg/apps/payments/static/payments/js/payment-form.js +3 -3
- django_cfg/apps/payments/static/payments/js/payment-list.js +13 -6
- django_cfg/apps/payments/static/payments/js/webhook-dashboard-mjs.js +241 -0
- django_cfg/apps/payments/tasks/__init__.py +11 -12
- django_cfg/apps/payments/tasks/types.py +10 -9
- django_cfg/apps/payments/tasks/usage_tracking.py +44 -46
- django_cfg/apps/payments/templatetags/payment_tags.py +27 -27
- django_cfg/apps/payments/urls.py +31 -14
- django_cfg/apps/payments/urls_admin.py +10 -10
- django_cfg/apps/payments/views/api/__init__.py +32 -33
- django_cfg/apps/payments/views/api/api_keys.py +62 -62
- django_cfg/apps/payments/views/api/balances.py +63 -64
- django_cfg/apps/payments/views/api/base.py +52 -52
- django_cfg/apps/payments/views/api/currencies.py +75 -63
- django_cfg/apps/payments/views/api/payments.py +73 -74
- django_cfg/apps/payments/views/api/subscriptions.py +71 -72
- django_cfg/apps/payments/views/api/webhooks.py +85 -84
- django_cfg/apps/payments/views/overview/__init__.py +7 -7
- django_cfg/apps/payments/views/overview/serializers.py +13 -14
- django_cfg/apps/payments/views/overview/services.py +66 -67
- django_cfg/apps/payments/views/overview/urls.py +2 -1
- django_cfg/apps/payments/views/overview/views.py +31 -31
- django_cfg/apps/payments/views/serializers/__init__.py +35 -36
- django_cfg/apps/payments/views/serializers/api_keys.py +59 -57
- django_cfg/apps/payments/views/serializers/balances.py +34 -33
- django_cfg/apps/payments/views/serializers/currencies.py +36 -34
- django_cfg/apps/payments/views/serializers/payments.py +48 -47
- django_cfg/apps/payments/views/serializers/subscriptions.py +50 -45
- django_cfg/apps/payments/views/serializers/webhooks.py +17 -16
- django_cfg/apps/support/admin/__init__.py +3 -3
- django_cfg/apps/support/admin/resources.py +26 -26
- django_cfg/apps/support/admin/support_admin.py +44 -48
- django_cfg/apps/support/admin.py +16 -15
- django_cfg/apps/support/apps.py +1 -1
- django_cfg/apps/support/managers/message_manager.py +4 -4
- django_cfg/apps/support/managers/ticket_manager.py +13 -12
- django_cfg/apps/support/migrations/0001_initial.py +2 -1
- django_cfg/apps/support/models.py +3 -1
- django_cfg/apps/support/serializers.py +4 -2
- django_cfg/apps/support/signals.py +12 -10
- django_cfg/apps/support/urls.py +4 -3
- django_cfg/apps/support/utils/support_email_service.py +11 -9
- django_cfg/apps/support/views/__init__.py +3 -3
- django_cfg/apps/support/views/admin.py +9 -9
- django_cfg/apps/support/views/api.py +10 -9
- django_cfg/apps/support/views/chat.py +14 -14
- django_cfg/apps/tasks/admin/tasks_admin.py +65 -74
- django_cfg/apps/tasks/apps.py +2 -2
- django_cfg/apps/tasks/serializers.py +6 -6
- django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +44 -20
- django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +7 -5
- django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +5 -3
- django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +5 -3
- django_cfg/apps/tasks/tasks/demo_tasks.py +12 -11
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +269 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +168 -0
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +21 -2
- django_cfg/apps/tasks/urls.py +3 -2
- django_cfg/apps/tasks/urls_admin.py +1 -0
- django_cfg/apps/tasks/utils/simulator.py +49 -52
- django_cfg/apps/tasks/views/api.py +75 -73
- django_cfg/apps/tasks/views/dashboard.py +5 -4
- django_cfg/apps/urls.py +20 -11
- django_cfg/apps.py +6 -5
- django_cfg/cli/commands/create_project.py +7 -6
- django_cfg/cli/commands/info.py +25 -25
- django_cfg/cli/utils.py +27 -27
- django_cfg/config.py +1 -1
- django_cfg/core/__init__.py +8 -8
- django_cfg/core/base/config_model.py +13 -12
- django_cfg/core/builders/apps_builder.py +2 -2
- django_cfg/core/builders/middleware_builder.py +1 -1
- django_cfg/core/builders/security_builder.py +1 -1
- django_cfg/core/config.py +2 -2
- django_cfg/core/environment/detector.py +27 -28
- django_cfg/core/exceptions.py +1 -1
- django_cfg/core/generation/core_generators/settings.py +1 -1
- django_cfg/core/generation/core_generators/static.py +11 -5
- django_cfg/core/generation/core_generators/templates.py +1 -1
- django_cfg/core/generation/data_generators/__init__.py +1 -1
- django_cfg/core/generation/data_generators/cache.py +1 -1
- django_cfg/core/generation/data_generators/database.py +1 -1
- django_cfg/core/generation/generation.py +1 -3
- django_cfg/core/generation/integration_generators/__init__.py +2 -2
- django_cfg/core/generation/integration_generators/api.py +12 -2
- django_cfg/core/generation/integration_generators/sessions.py +1 -1
- django_cfg/core/generation/integration_generators/tailwind.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +1 -1
- django_cfg/core/generation/integration_generators/third_party.py +1 -1
- django_cfg/core/generation/orchestrator.py +1 -1
- django_cfg/core/generation/protocols.py +1 -1
- django_cfg/core/generation/utility_generators/__init__.py +1 -1
- django_cfg/core/generation/utility_generators/email.py +1 -1
- django_cfg/core/generation/utility_generators/i18n.py +1 -1
- django_cfg/core/generation/utility_generators/limits.py +1 -1
- django_cfg/core/generation/utility_generators/logging.py +1 -1
- django_cfg/core/generation/utility_generators/security.py +1 -1
- django_cfg/core/generation/utils/helpers.py +1 -1
- django_cfg/core/integration/__init__.py +5 -5
- django_cfg/core/integration/commands_collector.py +38 -39
- django_cfg/core/integration/display/__init__.py +2 -2
- django_cfg/core/integration/display/base.py +30 -30
- django_cfg/core/integration/display/ngrok.py +35 -36
- django_cfg/core/integration/display/startup.py +149 -139
- django_cfg/core/integration/url_integration.py +10 -10
- django_cfg/core/integration/version_checker.py +20 -19
- django_cfg/core/services/config_service.py +4 -4
- django_cfg/core/state/__init__.py +1 -1
- django_cfg/core/state/registry.py +1 -1
- django_cfg/core/types/__init__.py +8 -1
- django_cfg/core/validation.py +36 -39
- django_cfg/management/commands/check_endpoints.py +3 -1
- django_cfg/management/commands/check_settings.py +3 -1
- django_cfg/management/commands/clear_constance.py +3 -1
- django_cfg/management/commands/create_token.py +3 -1
- django_cfg/management/commands/generate_clients.py +3 -1
- django_cfg/management/commands/migrate_all.py +3 -1
- django_cfg/management/commands/rundramatiq.py +3 -1
- django_cfg/management/commands/rundramatiq_simulator.py +3 -1
- django_cfg/management/commands/runserver_ngrok.py +3 -1
- django_cfg/management/commands/show_config.py +3 -1
- django_cfg/management/commands/superuser.py +3 -1
- django_cfg/management/commands/task_clear.py +3 -1
- django_cfg/management/commands/task_status.py +3 -1
- django_cfg/management/commands/test_email.py +3 -1
- django_cfg/management/commands/test_telegram.py +3 -1
- django_cfg/management/commands/test_twilio.py +3 -1
- django_cfg/management/commands/validate_openapi.py +3 -1
- django_cfg/middleware/pagination.py +8 -8
- django_cfg/middleware/public_endpoints.py +24 -23
- django_cfg/middleware/user_activity.py +27 -25
- django_cfg/models/__init__.py +19 -20
- django_cfg/models/api/__init__.py +4 -4
- django_cfg/models/api/config.py +23 -21
- django_cfg/models/api/cors.py +17 -16
- django_cfg/models/api/drf/__init__.py +1 -1
- django_cfg/models/api/drf/config.py +2 -1
- django_cfg/models/api/drf/redoc.py +2 -1
- django_cfg/models/api/drf/spectacular.py +4 -2
- django_cfg/models/api/drf/swagger.py +2 -1
- django_cfg/models/api/jwt.py +37 -36
- django_cfg/models/api/keys.py +13 -12
- django_cfg/models/api/limits.py +31 -30
- django_cfg/models/base/config.py +40 -41
- django_cfg/models/base/module.py +8 -8
- django_cfg/models/django/__init__.py +1 -1
- django_cfg/models/django/constance.py +8 -7
- django_cfg/models/django/environment.py +5 -3
- django_cfg/models/django/openapi.py +6 -16
- django_cfg/models/django/revolution_legacy.py +17 -16
- django_cfg/models/infrastructure/__init__.py +1 -1
- django_cfg/models/infrastructure/cache.py +46 -45
- django_cfg/models/infrastructure/database/config.py +4 -6
- django_cfg/models/infrastructure/database/converters.py +1 -1
- django_cfg/models/infrastructure/database/parsers.py +1 -1
- django_cfg/models/infrastructure/database/validators.py +1 -1
- django_cfg/models/infrastructure/logging.py +59 -57
- django_cfg/models/infrastructure/security.py +26 -24
- django_cfg/models/ngrok/auth.py +2 -1
- django_cfg/models/ngrok/config.py +3 -2
- django_cfg/models/ngrok/tunnel.py +2 -1
- django_cfg/models/payments/__init__.py +1 -1
- django_cfg/models/payments/api_keys.py +3 -1
- django_cfg/models/payments/config.py +4 -1
- django_cfg/models/payments/providers/base.py +2 -1
- django_cfg/models/payments/providers/nowpayments.py +3 -1
- django_cfg/models/services/__init__.py +1 -1
- django_cfg/models/services/base.py +2 -1
- django_cfg/models/services/email.py +28 -26
- django_cfg/models/services/telegram.py +2 -1
- django_cfg/models/tasks/__init__.py +2 -2
- django_cfg/models/tasks/backends.py +4 -3
- django_cfg/models/tasks/config.py +6 -4
- django_cfg/models/tasks/utils.py +3 -3
- django_cfg/modules/base.py +18 -17
- django_cfg/modules/django_admin/__init__.py +14 -15
- django_cfg/modules/django_admin/decorators/__init__.py +1 -1
- django_cfg/modules/django_admin/decorators/actions.py +8 -7
- django_cfg/modules/django_admin/decorators/display.py +9 -7
- django_cfg/modules/django_admin/icons/__init__.py +1 -1
- django_cfg/modules/django_admin/icons/constants.py +27 -27
- django_cfg/modules/django_admin/icons/generate_icons.py +54 -54
- django_cfg/modules/django_admin/management/commands/check_endpoints.py +5 -3
- django_cfg/modules/django_admin/management/commands/check_settings.py +40 -44
- django_cfg/modules/django_admin/management/commands/clear_constance.py +29 -30
- django_cfg/modules/django_admin/management/commands/create_token.py +42 -42
- django_cfg/modules/django_admin/management/commands/list_urls.py +37 -38
- django_cfg/modules/django_admin/management/commands/migrate_all.py +13 -15
- django_cfg/modules/django_admin/management/commands/migrator.py +17 -17
- django_cfg/modules/django_admin/management/commands/script.py +58 -60
- django_cfg/modules/django_admin/management/commands/show_config.py +32 -30
- django_cfg/modules/django_admin/management/commands/show_urls.py +46 -44
- django_cfg/modules/django_admin/management/commands/superuser.py +47 -48
- django_cfg/modules/django_admin/management/commands/tree.py +50 -54
- django_cfg/modules/django_admin/mixins/display_mixin.py +16 -15
- django_cfg/modules/django_admin/mixins/optimization_mixin.py +9 -8
- django_cfg/modules/django_admin/mixins/standalone_actions_mixin.py +25 -24
- django_cfg/modules/django_admin/models/__init__.py +4 -4
- django_cfg/modules/django_admin/models/action_models.py +3 -1
- django_cfg/modules/django_admin/models/badge_models.py +4 -2
- django_cfg/modules/django_admin/models/base.py +3 -3
- django_cfg/modules/django_admin/models/display_models.py +1 -0
- django_cfg/modules/django_admin/utils/badges.py +27 -26
- django_cfg/modules/django_admin/utils/displays.py +49 -49
- django_cfg/modules/django_client/apps.py +21 -3
- django_cfg/modules/django_client/core/__init__.py +9 -10
- django_cfg/modules/django_client/core/archive/manager.py +2 -2
- django_cfg/modules/django_client/core/cli/main.py +1 -3
- django_cfg/modules/django_client/core/config/config.py +3 -1
- django_cfg/modules/django_client/core/config/group.py +1 -0
- django_cfg/modules/django_client/core/config/service.py +2 -1
- django_cfg/modules/django_client/core/generator/__init__.py +1 -1
- django_cfg/modules/django_client/core/generator/base.py +2 -2
- django_cfg/modules/django_client/core/generator/python/async_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/python/files_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/generator.py +4 -4
- django_cfg/modules/django_client/core/generator/python/models_generator.py +1 -1
- django_cfg/modules/django_client/core/generator/python/operations_generator.py +2 -2
- django_cfg/modules/django_client/core/generator/python/sync_client_gen.py +1 -1
- django_cfg/modules/django_client/core/generator/typescript/client_generator.py +3 -1
- django_cfg/modules/django_client/core/generator/typescript/fetchers_generator.py +14 -13
- django_cfg/modules/django_client/core/generator/typescript/files_generator.py +1 -0
- django_cfg/modules/django_client/core/generator/typescript/generator.py +6 -6
- django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/models_generator.py +2 -1
- django_cfg/modules/django_client/core/generator/typescript/naming.py +2 -3
- django_cfg/modules/django_client/core/generator/typescript/operations_generator.py +12 -10
- django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +3 -2
- django_cfg/modules/django_client/core/generator/typescript/templates/client/client.ts.jinja +14 -6
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +4 -10
- django_cfg/modules/django_client/core/groups/__init__.py +1 -1
- django_cfg/modules/django_client/core/groups/detector.py +2 -1
- django_cfg/modules/django_client/core/groups/manager.py +2 -1
- django_cfg/modules/django_client/core/ir/schema.py +1 -1
- django_cfg/modules/django_client/core/parser/base.py +0 -2
- django_cfg/modules/django_client/core/parser/models/schema.py +1 -1
- django_cfg/modules/django_client/core/validation/__init__.py +1 -1
- django_cfg/modules/django_client/core/validation/fixer.py +1 -2
- django_cfg/modules/django_client/core/validation/reporter.py +2 -2
- django_cfg/modules/django_client/core/validation/safety.py +1 -1
- django_cfg/modules/django_client/management/commands/generate_client.py +14 -11
- django_cfg/modules/django_client/management/commands/validate_openapi.py +4 -6
- django_cfg/modules/django_client/spectacular/__init__.py +1 -1
- django_cfg/modules/django_client/spectacular/async_detection.py +3 -2
- django_cfg/modules/django_client/spectacular/enum_naming.py +1 -1
- django_cfg/modules/django_client/spectacular/schema.py +5 -5
- django_cfg/modules/django_client/system/__init__.py +24 -0
- django_cfg/modules/django_client/system/base_generator.py +123 -0
- django_cfg/modules/django_client/system/generate_mjs_clients.py +174 -0
- django_cfg/modules/django_client/system/mjs_generator.py +219 -0
- django_cfg/modules/django_client/system/schema_parser.py +195 -0
- django_cfg/modules/django_client/system/templates/api_client.js.j2 +87 -0
- django_cfg/modules/django_client/system/templates/app_index.js.j2 +13 -0
- django_cfg/modules/django_client/system/templates/base_client.js.j2 +166 -0
- django_cfg/modules/django_client/system/templates/main_index.js.j2 +80 -0
- django_cfg/modules/django_client/system/templates/types.js.j2 +24 -0
- django_cfg/modules/django_client/urls.py +3 -2
- django_cfg/modules/django_currency/__init__.py +17 -18
- django_cfg/modules/django_currency/clients/__init__.py +2 -2
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +48 -48
- django_cfg/modules/django_currency/clients/hybrid_client.py +76 -75
- django_cfg/modules/django_currency/core/__init__.py +7 -13
- django_cfg/modules/django_currency/core/converter.py +25 -24
- django_cfg/modules/django_currency/core/models.py +9 -8
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +65 -66
- django_cfg/modules/django_currency/examples/example_database_usage.py +29 -28
- django_cfg/modules/django_currency/utils/cache.py +10 -11
- django_cfg/modules/django_dashboard/__init__.py +4 -5
- django_cfg/modules/django_dashboard/components.py +11 -7
- django_cfg/modules/django_dashboard/debug.py +1 -3
- django_cfg/modules/django_dashboard/management/commands/debug_dashboard.py +3 -3
- django_cfg/modules/django_dashboard/sections/base.py +2 -1
- django_cfg/modules/django_dashboard/sections/commands.py +3 -2
- django_cfg/modules/django_dashboard/sections/documentation.py +8 -6
- django_cfg/modules/django_dashboard/sections/overview.py +13 -9
- django_cfg/modules/django_dashboard/sections/stats.py +2 -2
- django_cfg/modules/django_dashboard/sections/system.py +2 -1
- django_cfg/modules/django_drf_theme/templatetags/tailwind_tags.py +12 -4
- django_cfg/modules/django_email/management/commands/test_email.py +8 -7
- django_cfg/modules/django_email/service.py +5 -4
- django_cfg/modules/django_health/service.py +46 -44
- django_cfg/modules/django_import_export/__init__.py +7 -3
- django_cfg/modules/django_llm/__init__.py +3 -2
- django_cfg/modules/django_llm/example.py +58 -56
- django_cfg/modules/django_llm/llm/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/cache.py +21 -20
- django_cfg/modules/django_llm/llm/client.py +9 -9
- django_cfg/modules/django_llm/llm/costs.py +14 -14
- django_cfg/modules/django_llm/llm/embeddings/__init__.py +1 -1
- django_cfg/modules/django_llm/llm/embeddings/mock_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/embeddings/openai_embedder.py +1 -2
- django_cfg/modules/django_llm/llm/extractor.py +8 -8
- django_cfg/modules/django_llm/llm/models.py +5 -5
- django_cfg/modules/django_llm/llm/models_api/models_query.py +2 -2
- django_cfg/modules/django_llm/llm/models_cache.py +91 -92
- django_cfg/modules/django_llm/llm/providers/config_builder.py +1 -1
- django_cfg/modules/django_llm/llm/providers/provider_manager.py +2 -1
- django_cfg/modules/django_llm/llm/requests/cache_manager.py +1 -1
- django_cfg/modules/django_llm/llm/requests/chat_handler.py +2 -2
- django_cfg/modules/django_llm/llm/requests/embedding_handler.py +1 -1
- django_cfg/modules/django_llm/llm/responses/response_builder.py +2 -2
- django_cfg/modules/django_llm/llm/stats/stats_manager.py +1 -1
- django_cfg/modules/django_llm/llm/tokenizer.py +10 -9
- django_cfg/modules/django_llm/translator/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/cache.py +36 -35
- django_cfg/modules/django_llm/translator/detectors/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/detectors/script_detector.py +0 -1
- django_cfg/modules/django_llm/translator/stats/stats_tracker.py +1 -1
- django_cfg/modules/django_llm/translator/translator.py +5 -4
- django_cfg/modules/django_llm/translator/translators/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/translators/json_translator.py +1 -1
- django_cfg/modules/django_llm/translator/utils/__init__.py +1 -1
- django_cfg/modules/django_llm/translator/utils/prompt_builder.py +0 -1
- django_cfg/modules/django_logging/__init__.py +1 -1
- django_cfg/modules/django_logging/django_logger.py +33 -34
- django_cfg/modules/django_logging/logger.py +3 -7
- django_cfg/modules/django_ngrok/__init__.py +7 -7
- django_cfg/modules/django_ngrok/management/commands/runserver_ngrok.py +33 -30
- django_cfg/modules/django_ngrok/service.py +33 -32
- django_cfg/modules/django_tailwind/templates/django_tailwind/base.html +4 -36
- django_cfg/modules/django_tailwind/templates/django_tailwind/components/navbar.html +1 -1
- django_cfg/modules/django_tasks/__init__.py +5 -5
- django_cfg/modules/django_tasks/dramatiq_setup.py +1 -1
- django_cfg/modules/django_tasks/factory.py +1 -1
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +39 -40
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +79 -80
- django_cfg/modules/django_tasks/management/commands/task_clear.py +34 -34
- django_cfg/modules/django_tasks/management/commands/task_status.py +34 -34
- django_cfg/modules/django_tasks/service.py +4 -3
- django_cfg/modules/django_tasks/settings.py +1 -1
- django_cfg/modules/django_telegram/__init__.py +4 -4
- django_cfg/modules/django_telegram/management/commands/test_telegram.py +4 -5
- django_cfg/modules/django_telegram/service.py +4 -3
- django_cfg/modules/django_telegram/utils.py +1 -1
- django_cfg/modules/django_twilio/__init__.py +15 -16
- django_cfg/modules/django_twilio/_imports.py +1 -1
- django_cfg/modules/django_twilio/base.py +9 -5
- django_cfg/modules/django_twilio/email_otp.py +4 -3
- django_cfg/modules/django_twilio/exceptions.py +36 -36
- django_cfg/modules/django_twilio/management/commands/test_twilio.py +6 -7
- django_cfg/modules/django_twilio/models.py +54 -53
- django_cfg/modules/django_twilio/sendgrid_service.py +70 -72
- django_cfg/modules/django_twilio/simple_service.py +42 -41
- django_cfg/modules/django_twilio/sms.py +1 -0
- django_cfg/modules/django_twilio/twilio_service.py +79 -83
- django_cfg/modules/django_twilio/unified.py +6 -5
- django_cfg/modules/django_twilio/utils.py +2 -3
- django_cfg/modules/django_twilio/whatsapp.py +3 -2
- django_cfg/modules/django_unfold/__init__.py +7 -6
- django_cfg/modules/django_unfold/callbacks/actions.py +6 -5
- django_cfg/modules/django_unfold/callbacks/apizones.py +122 -0
- django_cfg/modules/django_unfold/callbacks/base.py +9 -8
- django_cfg/modules/django_unfold/callbacks/charts.py +36 -37
- django_cfg/modules/django_unfold/callbacks/commands.py +2 -2
- django_cfg/modules/django_unfold/callbacks/main.py +27 -27
- django_cfg/modules/django_unfold/callbacks/statistics.py +12 -12
- django_cfg/modules/django_unfold/callbacks/system.py +5 -5
- django_cfg/modules/django_unfold/callbacks/users.py +4 -4
- django_cfg/modules/django_unfold/dashboard.py +29 -29
- django_cfg/modules/django_unfold/models/__init__.py +23 -8
- django_cfg/modules/django_unfold/models/config.py +84 -81
- django_cfg/modules/django_unfold/models/dashboard.py +20 -19
- django_cfg/modules/django_unfold/models/dropdown.py +6 -4
- django_cfg/modules/django_unfold/models/navigation.py +6 -4
- django_cfg/modules/django_unfold/models/tabs.py +4 -3
- django_cfg/modules/django_unfold/models.py +2 -3
- django_cfg/modules/django_unfold/system_monitor.py +27 -25
- django_cfg/modules/django_unfold/tailwind.py +12 -14
- django_cfg/modules/django_unfold/utils.py +7 -6
- django_cfg/pyproject.toml +1 -1
- django_cfg/registry/__init__.py +3 -3
- django_cfg/registry/core.py +8 -8
- django_cfg/registry/modules.py +2 -2
- django_cfg/registry/services.py +2 -2
- django_cfg/registry/third_party.py +3 -3
- django_cfg/routing/__init__.py +3 -3
- django_cfg/routing/callbacks.py +27 -26
- django_cfg/routing/routers.py +2 -2
- django_cfg/static/js/api/accounts/client.mjs +69 -0
- django_cfg/static/js/api/accounts/index.mjs +13 -0
- django_cfg/static/js/api/base.mjs +166 -0
- django_cfg/static/js/api/index.mjs +100 -0
- django_cfg/static/js/api/ipc/client.mjs +74 -0
- django_cfg/static/js/api/ipc/index.mjs +13 -0
- django_cfg/static/js/api/leads/client.mjs +71 -0
- django_cfg/static/js/api/leads/index.mjs +13 -0
- django_cfg/static/js/api/newsletter/client.mjs +109 -0
- django_cfg/static/js/api/newsletter/index.mjs +13 -0
- django_cfg/static/js/api/payments/client.mjs +1264 -0
- django_cfg/static/js/api/payments/index.mjs +13 -0
- django_cfg/static/js/api/support/client.mjs +84 -0
- django_cfg/static/js/api/support/index.mjs +13 -0
- django_cfg/static/js/api/tasks/client.mjs +74 -0
- django_cfg/static/js/api/tasks/index.mjs +13 -0
- django_cfg/static/js/api/types.mjs +729 -0
- django_cfg/static/js/api-loader.mjs +169 -0
- django_cfg/templates/admin/snippets/zones/zones_table.html +4 -3
- django_cfg/templatetags/django_cfg.py +4 -4
- django_cfg/utils/path_resolution.py +49 -50
- django_cfg/utils/smart_defaults.py +27 -29
- django_cfg/utils/version_check.py +14 -14
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/METADATA +1 -1
- django_cfg-1.4.24.dist-info/RECORD +1137 -0
- django_cfg/apps/payments/static/payments/js/api-client.js +0 -408
- django_cfg/modules/django_ipc_client/dashboard/README.md +0 -517
- django_cfg/modules/django_ipc_client/dashboard/UNFOLD_INTEGRATION.md +0 -439
- django_cfg/modules/django_ipc_client/dashboard/__init__.py +0 -11
- django_cfg/modules/django_ipc_client/dashboard/apps.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/templates/django_ipc_dashboard/dashboard.html +0 -200
- django_cfg/modules/django_ipc_client/dashboard/urls.py +0 -22
- django_cfg/modules/django_ipc_client/dashboard/urls_admin.py +0 -9
- django_cfg/modules/django_ipc_client/dashboard/views.py +0 -251
- django_cfg/modules/django_rpc_old/POETRY.md +0 -344
- django_cfg/modules/django_rpc_old/README.md +0 -397
- django_cfg/modules/django_rpc_old/TESTING.md +0 -358
- django_cfg/modules/django_rpc_old/__init__.py +0 -39
- django_cfg/modules/django_rpc_old/client.py +0 -531
- django_cfg/modules/django_rpc_old/config.py +0 -279
- django_cfg/modules/django_rpc_old/exceptions.py +0 -172
- django_cfg/modules/django_unfold/callbacks/revolution.py +0 -81
- django_cfg-1.4.21.dist-info/RECORD +0 -1111
- /django_cfg/{modules/django_ipc_client → apps/ipc}/README.md +0 -0
- /django_cfg/{modules/django_ipc_client → apps/ipc/services/client}/config.py +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.21.dist-info → django_cfg-1.4.24.dist-info}/licenses/LICENSE +0 -0
@@ -15,10 +15,10 @@ from django.apps import apps
|
|
15
15
|
from django.conf import settings
|
16
16
|
from django.core.management.base import BaseCommand
|
17
17
|
from django.utils.module_loading import module_has_submodule
|
18
|
+
|
18
19
|
from django_cfg.modules.django_logging import get_logger
|
19
20
|
from django_cfg.modules.django_tasks import get_task_service
|
20
21
|
|
21
|
-
|
22
22
|
# Default values
|
23
23
|
NPROCS = multiprocessing.cpu_count()
|
24
24
|
NTHREADS = 8
|
@@ -37,7 +37,7 @@ class Command(BaseCommand):
|
|
37
37
|
|
38
38
|
def add_arguments(self, parser):
|
39
39
|
parser.formatter_class = argparse.ArgumentDefaultsHelpFormatter
|
40
|
-
|
40
|
+
|
41
41
|
parser.add_argument(
|
42
42
|
"--processes", "-p",
|
43
43
|
default=NPROCS,
|
@@ -72,8 +72,8 @@ class Command(BaseCommand):
|
|
72
72
|
help="Write all logs to a file, or stderr when empty",
|
73
73
|
)
|
74
74
|
parser.add_argument(
|
75
|
-
"--worker-shutdown-timeout",
|
76
|
-
type=int,
|
75
|
+
"--worker-shutdown-timeout",
|
76
|
+
type=int,
|
77
77
|
default=600000,
|
78
78
|
help="Timeout for worker shutdown, in milliseconds"
|
79
79
|
)
|
@@ -83,10 +83,10 @@ class Command(BaseCommand):
|
|
83
83
|
help="Show configuration without starting workers",
|
84
84
|
)
|
85
85
|
|
86
|
-
def handle(self, watch_dir, processes, threads, verbosity, queues,
|
86
|
+
def handle(self, watch_dir, processes, threads, verbosity, queues,
|
87
87
|
pid_file, log_file, worker_shutdown_timeout, dry_run, **options):
|
88
88
|
logger.info("Starting rundramatiq command")
|
89
|
-
|
89
|
+
|
90
90
|
# Get task service and validate
|
91
91
|
task_service = get_task_service()
|
92
92
|
if not task_service.is_enabled():
|
@@ -94,10 +94,10 @@ class Command(BaseCommand):
|
|
94
94
|
self.style.ERROR("Task system is not enabled in Django-CFG configuration")
|
95
95
|
)
|
96
96
|
return
|
97
|
-
|
97
|
+
|
98
98
|
# Discover task modules
|
99
99
|
tasks_modules = self._discover_tasks_modules()
|
100
|
-
|
100
|
+
|
101
101
|
# Show configuration info
|
102
102
|
self.stdout.write(self.style.SUCCESS("Dramatiq Worker Configuration:"))
|
103
103
|
self.stdout.write(f"Processes: {processes}")
|
@@ -106,15 +106,15 @@ class Command(BaseCommand):
|
|
106
106
|
self.stdout.write(f"Queues: {', '.join(queues)}")
|
107
107
|
else:
|
108
108
|
self.stdout.write("Queues: all")
|
109
|
-
|
110
|
-
self.stdout.write(
|
109
|
+
|
110
|
+
self.stdout.write("\nDiscovered task modules:")
|
111
111
|
for module in tasks_modules:
|
112
112
|
self.stdout.write(f" - {module}")
|
113
|
-
|
113
|
+
|
114
114
|
# If dry run, show command and exit
|
115
115
|
if dry_run:
|
116
116
|
executable_name = "dramatiq"
|
117
|
-
|
117
|
+
|
118
118
|
process_args = [
|
119
119
|
executable_name,
|
120
120
|
"django_cfg.modules.django_tasks.dramatiq_setup", # Broker module
|
@@ -122,36 +122,36 @@ class Command(BaseCommand):
|
|
122
122
|
"--threads", str(threads),
|
123
123
|
"--worker-shutdown-timeout", str(worker_shutdown_timeout),
|
124
124
|
]
|
125
|
-
|
125
|
+
|
126
126
|
if watch_dir:
|
127
127
|
process_args.extend(["--watch", watch_dir])
|
128
|
-
|
128
|
+
|
129
129
|
verbosity_args = ["-v"] * (verbosity - 1)
|
130
130
|
process_args.extend(verbosity_args)
|
131
|
-
|
131
|
+
|
132
132
|
if queues:
|
133
133
|
process_args.extend(["--queues"] + queues)
|
134
|
-
|
134
|
+
|
135
135
|
if pid_file:
|
136
136
|
process_args.extend(["--pid-file", pid_file])
|
137
|
-
|
137
|
+
|
138
138
|
if log_file:
|
139
139
|
process_args.extend(["--log-file", log_file])
|
140
|
-
|
140
|
+
|
141
141
|
# Add task modules (broker module is already first in tasks_modules)
|
142
142
|
process_args.extend(tasks_modules)
|
143
|
-
|
144
|
-
self.stdout.write(
|
143
|
+
|
144
|
+
self.stdout.write("\nCommand that would be executed:")
|
145
145
|
self.stdout.write(f' {" ".join(process_args)}')
|
146
146
|
return
|
147
|
-
|
147
|
+
|
148
148
|
# Show startup info
|
149
149
|
self.stdout.write(self.style.SUCCESS("\nStarting Dramatiq workers..."))
|
150
|
-
|
150
|
+
|
151
151
|
# Build dramatiq command
|
152
152
|
executable_name = "dramatiq"
|
153
153
|
executable_path = self._resolve_executable(executable_name)
|
154
|
-
|
154
|
+
|
155
155
|
# Build process arguments exactly like django_dramatiq
|
156
156
|
process_args = [
|
157
157
|
executable_name,
|
@@ -160,39 +160,38 @@ class Command(BaseCommand):
|
|
160
160
|
"--threads", str(threads),
|
161
161
|
"--worker-shutdown-timeout", str(worker_shutdown_timeout),
|
162
162
|
]
|
163
|
-
|
163
|
+
|
164
164
|
# Add watch directory if specified
|
165
165
|
if watch_dir:
|
166
166
|
process_args.extend(["--watch", watch_dir])
|
167
|
-
|
167
|
+
|
168
168
|
# Add verbosity
|
169
169
|
verbosity_args = ["-v"] * (verbosity - 1)
|
170
170
|
process_args.extend(verbosity_args)
|
171
|
-
|
171
|
+
|
172
172
|
# Add queues if specified
|
173
173
|
if queues:
|
174
174
|
process_args.extend(["--queues"] + queues)
|
175
|
-
|
175
|
+
|
176
176
|
# Add PID file if specified
|
177
177
|
if pid_file:
|
178
178
|
process_args.extend(["--pid-file", pid_file])
|
179
|
-
|
179
|
+
|
180
180
|
# Add log file if specified
|
181
181
|
if log_file:
|
182
182
|
process_args.extend(["--log-file", log_file])
|
183
|
-
|
183
|
+
|
184
184
|
# Add task modules (broker module is already first in tasks_modules)
|
185
185
|
process_args.extend(tasks_modules)
|
186
|
-
|
186
|
+
|
187
187
|
self.stdout.write(f'Running dramatiq: "{" ".join(process_args)}"\n')
|
188
|
-
|
188
|
+
|
189
189
|
# Ensure DJANGO_SETTINGS_MODULE is set for worker processes
|
190
190
|
if not os.environ.get('DJANGO_SETTINGS_MODULE'):
|
191
191
|
if hasattr(settings, 'SETTINGS_MODULE'):
|
192
192
|
os.environ['DJANGO_SETTINGS_MODULE'] = settings.SETTINGS_MODULE
|
193
193
|
else:
|
194
194
|
# Try to detect from manage.py or current settings
|
195
|
-
import django
|
196
195
|
from django.conf import settings as django_settings
|
197
196
|
if hasattr(django_settings, '_wrapped') and hasattr(django_settings._wrapped, '__module__'):
|
198
197
|
module_name = django_settings._wrapped.__module__
|
@@ -201,34 +200,34 @@ class Command(BaseCommand):
|
|
201
200
|
self.stdout.write(
|
202
201
|
self.style.WARNING("Could not detect DJANGO_SETTINGS_MODULE")
|
203
202
|
)
|
204
|
-
|
203
|
+
|
205
204
|
# Use os.execvp like django_dramatiq to preserve environment
|
206
205
|
if sys.platform == "win32":
|
207
206
|
import subprocess
|
208
207
|
command = [executable_path] + process_args[1:]
|
209
208
|
sys.exit(subprocess.run(command))
|
210
|
-
|
209
|
+
|
211
210
|
os.execvp(executable_path, process_args)
|
212
211
|
|
213
212
|
def _discover_tasks_modules(self):
|
214
213
|
"""Discover task modules like django_dramatiq does."""
|
215
214
|
# Always include our broker setup module first
|
216
215
|
tasks_modules = ["django_cfg.modules.django_tasks.dramatiq_setup"]
|
217
|
-
|
216
|
+
|
218
217
|
# Get task service for configuration
|
219
218
|
task_service = get_task_service()
|
220
|
-
|
219
|
+
|
221
220
|
# Try to get task modules from Django-CFG config
|
222
221
|
if task_service.config and task_service.config.auto_discover_tasks:
|
223
222
|
discovered = task_service.discover_tasks()
|
224
223
|
for module_name in discovered:
|
225
224
|
self.stdout.write(f"Discovered tasks module: '{module_name}'")
|
226
225
|
tasks_modules.append(module_name)
|
227
|
-
|
226
|
+
|
228
227
|
# Fallback: use django_dramatiq discovery logic
|
229
228
|
if len(tasks_modules) == 1: # Only broker module found
|
230
229
|
task_module_names = getattr(settings, "DRAMATIQ_AUTODISCOVER_MODULES", ("tasks",))
|
231
|
-
|
230
|
+
|
232
231
|
for app_config in apps.get_app_configs():
|
233
232
|
for task_module in task_module_names:
|
234
233
|
if module_has_submodule(app_config.module, task_module):
|
@@ -240,7 +239,7 @@ class Command(BaseCommand):
|
|
240
239
|
except ImportError:
|
241
240
|
# Module exists but has import errors, skip it
|
242
241
|
pass
|
243
|
-
|
242
|
+
|
244
243
|
return tasks_modules
|
245
244
|
|
246
245
|
def _resolve_executable(self, exec_name):
|
@@ -251,4 +250,4 @@ class Command(BaseCommand):
|
|
251
250
|
exec_path = os.path.join(d, exec_name)
|
252
251
|
if os.path.isfile(exec_path):
|
253
252
|
return exec_path
|
254
|
-
return exec_name
|
253
|
+
return exec_name
|
@@ -8,54 +8,53 @@ Usage:
|
|
8
8
|
python manage.py rundramatiq_simulator --show-keys
|
9
9
|
"""
|
10
10
|
|
11
|
-
import redis
|
12
11
|
import json
|
12
|
+
import random
|
13
13
|
import time
|
14
14
|
from datetime import datetime, timezone
|
15
|
-
import
|
16
|
-
from typing import Dict, Any, Optional
|
15
|
+
from typing import Any, Dict
|
17
16
|
|
17
|
+
import redis
|
18
18
|
from django.core.management.base import BaseCommand, CommandError
|
19
|
-
from django.conf import settings
|
20
19
|
|
21
20
|
from django_cfg.modules.django_tasks import DjangoTasks
|
22
21
|
|
23
22
|
|
24
23
|
class TaskSimulator:
|
25
24
|
"""Task data simulator for Tasks Dashboard."""
|
26
|
-
|
25
|
+
|
27
26
|
def __init__(self):
|
28
27
|
"""Initialize the simulator."""
|
29
28
|
self.tasks_service = DjangoTasks()
|
30
|
-
|
29
|
+
|
31
30
|
# Get Redis client using the same logic as DjangoTasks
|
32
31
|
try:
|
33
32
|
redis_url = self.tasks_service.get_redis_url()
|
34
33
|
if not redis_url:
|
35
34
|
raise RuntimeError("No Redis URL available")
|
36
|
-
|
35
|
+
|
37
36
|
# Parse URL for connection
|
38
37
|
from urllib.parse import urlparse
|
39
38
|
parsed = urlparse(redis_url)
|
40
|
-
|
39
|
+
|
41
40
|
self.redis_client = redis.Redis(
|
42
41
|
host=parsed.hostname or 'localhost',
|
43
42
|
port=parsed.port or 6379,
|
44
43
|
db=int(parsed.path.lstrip('/')) if parsed.path else 1,
|
45
44
|
decode_responses=True
|
46
45
|
)
|
47
|
-
|
46
|
+
|
48
47
|
except Exception as e:
|
49
48
|
raise CommandError(f"Failed to connect to Redis: {e}")
|
50
|
-
|
49
|
+
|
51
50
|
# Get queue configuration
|
52
51
|
try:
|
53
52
|
config = self.tasks_service.get_config()
|
54
53
|
self.queues = config.tasks.dramatiq.queues
|
55
|
-
except Exception
|
54
|
+
except Exception:
|
56
55
|
# Use default queues if we can't get configuration
|
57
56
|
self.queues = ['critical', 'high', 'default', 'low', 'background', 'payments', 'agents', 'knowbase']
|
58
|
-
|
57
|
+
|
59
58
|
def clear_all_data(self) -> int:
|
60
59
|
"""
|
61
60
|
Clear all test data.
|
@@ -68,7 +67,7 @@ class TaskSimulator:
|
|
68
67
|
deleted = self.redis_client.delete(*keys)
|
69
68
|
return deleted
|
70
69
|
return 0
|
71
|
-
|
70
|
+
|
72
71
|
def simulate_queues(self, pending_tasks_per_queue=None, failed_tasks_per_queue=None) -> Dict[str, Dict[str, int]]:
|
73
72
|
"""
|
74
73
|
Simulate queues with tasks.
|
@@ -91,7 +90,7 @@ class TaskSimulator:
|
|
91
90
|
'agents': 7,
|
92
91
|
'knowbase': 4
|
93
92
|
}
|
94
|
-
|
93
|
+
|
95
94
|
if failed_tasks_per_queue is None:
|
96
95
|
failed_tasks_per_queue = {
|
97
96
|
'critical': 0,
|
@@ -103,17 +102,17 @@ class TaskSimulator:
|
|
103
102
|
'agents': 1,
|
104
103
|
'knowbase': 0
|
105
104
|
}
|
106
|
-
|
105
|
+
|
107
106
|
results = {}
|
108
|
-
|
107
|
+
|
109
108
|
for queue_name in self.queues:
|
110
109
|
queue_results = {'pending': 0, 'failed': 0}
|
111
|
-
|
110
|
+
|
112
111
|
# Pending tasks
|
113
112
|
pending_count = pending_tasks_per_queue.get(queue_name, 0)
|
114
113
|
if pending_count > 0:
|
115
114
|
queue_key = f"dramatiq:default.DQ.{queue_name}"
|
116
|
-
|
115
|
+
|
117
116
|
# Add fake tasks to queue
|
118
117
|
for i in range(pending_count):
|
119
118
|
task_data = {
|
@@ -126,14 +125,14 @@ class TaskSimulator:
|
|
126
125
|
"message_timestamp": int(time.time() * 1000)
|
127
126
|
}
|
128
127
|
self.redis_client.lpush(queue_key, json.dumps(task_data))
|
129
|
-
|
128
|
+
|
130
129
|
queue_results['pending'] = pending_count
|
131
|
-
|
130
|
+
|
132
131
|
# Failed tasks
|
133
132
|
failed_count = failed_tasks_per_queue.get(queue_name, 0)
|
134
133
|
if failed_count > 0:
|
135
134
|
failed_key = f"dramatiq:default.DQ.{queue_name}.failed"
|
136
|
-
|
135
|
+
|
137
136
|
# Add fake failed tasks
|
138
137
|
for i in range(failed_count):
|
139
138
|
failed_task_data = {
|
@@ -147,14 +146,14 @@ class TaskSimulator:
|
|
147
146
|
"error": f"Simulated error for {queue_name} task {i}"
|
148
147
|
}
|
149
148
|
self.redis_client.lpush(failed_key, json.dumps(failed_task_data))
|
150
|
-
|
149
|
+
|
151
150
|
queue_results['failed'] = failed_count
|
152
|
-
|
151
|
+
|
153
152
|
if queue_results['pending'] > 0 or queue_results['failed'] > 0:
|
154
153
|
results[queue_name] = queue_results
|
155
|
-
|
154
|
+
|
156
155
|
return results
|
157
|
-
|
156
|
+
|
158
157
|
def simulate_workers(self, worker_count=3) -> list:
|
159
158
|
"""
|
160
159
|
Симулировать активных воркеров.
|
@@ -166,32 +165,32 @@ class TaskSimulator:
|
|
166
165
|
Список ID созданных воркеров
|
167
166
|
"""
|
168
167
|
worker_ids = []
|
169
|
-
|
168
|
+
|
170
169
|
for i in range(worker_count):
|
171
170
|
worker_id = f"worker_{i}_{int(time.time())}"
|
172
171
|
worker_key = f"dramatiq:worker:{worker_id}"
|
173
|
-
|
172
|
+
|
174
173
|
worker_data = {
|
175
174
|
"worker_id": worker_id,
|
176
|
-
"hostname":
|
175
|
+
"hostname": "localhost",
|
177
176
|
"pid": 1000 + i,
|
178
177
|
"queues": self.queues,
|
179
178
|
"started_at": datetime.now(timezone.utc).isoformat(),
|
180
179
|
"last_heartbeat": datetime.now(timezone.utc).isoformat(),
|
181
180
|
"status": "active"
|
182
181
|
}
|
183
|
-
|
182
|
+
|
184
183
|
# Устанавливаем данные воркера с TTL
|
185
184
|
self.redis_client.setex(
|
186
|
-
worker_key,
|
185
|
+
worker_key,
|
187
186
|
300, # 5 минут TTL
|
188
187
|
json.dumps(worker_data)
|
189
188
|
)
|
190
|
-
|
189
|
+
|
191
190
|
worker_ids.append(worker_id)
|
192
|
-
|
191
|
+
|
193
192
|
return worker_ids
|
194
|
-
|
193
|
+
|
195
194
|
def simulate_task_statistics(self) -> Dict[str, Any]:
|
196
195
|
"""
|
197
196
|
Симулировать статистику задач.
|
@@ -206,12 +205,12 @@ class TaskSimulator:
|
|
206
205
|
"processing_time_avg": round(random.uniform(1.5, 4.0), 2),
|
207
206
|
"last_updated": datetime.now(timezone.utc).isoformat()
|
208
207
|
}
|
209
|
-
|
208
|
+
|
210
209
|
stats_key = "dramatiq:stats"
|
211
210
|
self.redis_client.setex(stats_key, 3600, json.dumps(stats_data))
|
212
|
-
|
211
|
+
|
213
212
|
return stats_data
|
214
|
-
|
213
|
+
|
215
214
|
def run_simulation(self, workers=3, clear_first=True) -> Dict[str, Any]:
|
216
215
|
"""
|
217
216
|
Запустить полную симуляцию.
|
@@ -229,16 +228,16 @@ class TaskSimulator:
|
|
229
228
|
'workers': [],
|
230
229
|
'statistics': {}
|
231
230
|
}
|
232
|
-
|
231
|
+
|
233
232
|
if clear_first:
|
234
233
|
results['cleared_keys'] = self.clear_all_data()
|
235
|
-
|
234
|
+
|
236
235
|
results['queues'] = self.simulate_queues()
|
237
236
|
results['workers'] = self.simulate_workers(workers)
|
238
237
|
results['statistics'] = self.simulate_task_statistics()
|
239
|
-
|
238
|
+
|
240
239
|
return results
|
241
|
-
|
240
|
+
|
242
241
|
def get_redis_summary(self) -> Dict[str, Any]:
|
243
242
|
"""Получить сводку по данным в Redis."""
|
244
243
|
summary = {
|
@@ -247,29 +246,29 @@ class TaskSimulator:
|
|
247
246
|
'workers': 0,
|
248
247
|
'statistics': None
|
249
248
|
}
|
250
|
-
|
249
|
+
|
251
250
|
# Подсчитываем все ключи
|
252
251
|
all_keys = self.redis_client.keys("dramatiq:*")
|
253
252
|
summary['total_keys'] = len(all_keys)
|
254
|
-
|
253
|
+
|
255
254
|
# Анализируем очереди
|
256
255
|
for queue_name in self.queues:
|
257
256
|
pending_key = f"dramatiq:default.DQ.{queue_name}"
|
258
257
|
failed_key = f"dramatiq:default.DQ.{queue_name}.failed"
|
259
|
-
|
258
|
+
|
260
259
|
pending = self.redis_client.llen(pending_key)
|
261
260
|
failed = self.redis_client.llen(failed_key)
|
262
|
-
|
261
|
+
|
263
262
|
if pending > 0 or failed > 0:
|
264
263
|
summary['queues'][queue_name] = {
|
265
264
|
'pending': pending,
|
266
265
|
'failed': failed
|
267
266
|
}
|
268
|
-
|
267
|
+
|
269
268
|
# Подсчитываем воркеров
|
270
269
|
worker_keys = self.redis_client.keys("dramatiq:worker:*")
|
271
270
|
summary['workers'] = len(worker_keys)
|
272
|
-
|
271
|
+
|
273
272
|
# Получаем статистику
|
274
273
|
stats_key = "dramatiq:stats"
|
275
274
|
if self.redis_client.exists(stats_key):
|
@@ -278,7 +277,7 @@ class TaskSimulator:
|
|
278
277
|
summary['statistics'] = json.loads(stats_data)
|
279
278
|
except:
|
280
279
|
pass
|
281
|
-
|
280
|
+
|
282
281
|
return summary
|
283
282
|
|
284
283
|
|
@@ -291,7 +290,7 @@ class Command(BaseCommand):
|
|
291
290
|
is_destructive = False
|
292
291
|
|
293
292
|
help = 'Simulate Dramatiq tasks and workers for dashboard testing'
|
294
|
-
|
293
|
+
|
295
294
|
def add_arguments(self, parser):
|
296
295
|
"""Добавить аргументы команды."""
|
297
296
|
parser.add_argument(
|
@@ -300,41 +299,41 @@ class Command(BaseCommand):
|
|
300
299
|
default=3,
|
301
300
|
help='Number of workers to simulate (default: 3)'
|
302
301
|
)
|
303
|
-
|
302
|
+
|
304
303
|
parser.add_argument(
|
305
304
|
'--no-clear',
|
306
305
|
action='store_true',
|
307
306
|
help='Do not clear existing data before simulation'
|
308
307
|
)
|
309
|
-
|
308
|
+
|
310
309
|
parser.add_argument(
|
311
310
|
'--clear-only',
|
312
311
|
action='store_true',
|
313
312
|
help='Only clear data, do not simulate'
|
314
313
|
)
|
315
|
-
|
314
|
+
|
316
315
|
parser.add_argument(
|
317
316
|
'--show-keys',
|
318
317
|
action='store_true',
|
319
318
|
help='Show Redis keys after operation'
|
320
319
|
)
|
321
|
-
|
320
|
+
|
322
321
|
parser.add_argument(
|
323
322
|
'--summary',
|
324
323
|
action='store_true',
|
325
324
|
help='Show summary of current Redis data'
|
326
325
|
)
|
327
|
-
|
326
|
+
|
328
327
|
def handle(self, *args, **options):
|
329
328
|
"""Выполнить команду."""
|
330
329
|
try:
|
331
330
|
simulator = TaskSimulator()
|
332
|
-
|
331
|
+
|
333
332
|
# Показать только сводку
|
334
333
|
if options['summary']:
|
335
334
|
self.show_summary(simulator)
|
336
335
|
return
|
337
|
-
|
336
|
+
|
338
337
|
# Только очистка
|
339
338
|
if options['clear_only']:
|
340
339
|
self.stdout.write("🧹 Clearing all test data...")
|
@@ -343,87 +342,87 @@ class Command(BaseCommand):
|
|
343
342
|
self.style.SUCCESS(f"✅ Cleared {cleared} Redis keys")
|
344
343
|
)
|
345
344
|
return
|
346
|
-
|
345
|
+
|
347
346
|
# Полная симуляция
|
348
347
|
self.stdout.write("🎭 Starting Dramatiq Task Simulation")
|
349
348
|
self.stdout.write("=" * 50)
|
350
|
-
|
349
|
+
|
351
350
|
results = simulator.run_simulation(
|
352
351
|
workers=options['workers'],
|
353
352
|
clear_first=not options['no_clear']
|
354
353
|
)
|
355
|
-
|
354
|
+
|
356
355
|
# Показываем результаты
|
357
356
|
if results['cleared_keys'] > 0:
|
358
357
|
self.stdout.write(f"🧹 Cleared {results['cleared_keys']} existing keys")
|
359
|
-
|
360
|
-
self.stdout.write(
|
358
|
+
|
359
|
+
self.stdout.write("📋 Created queues:")
|
361
360
|
total_pending = 0
|
362
361
|
total_failed = 0
|
363
|
-
|
362
|
+
|
364
363
|
for queue_name, counts in results['queues'].items():
|
365
364
|
pending = counts['pending']
|
366
365
|
failed = counts['failed']
|
367
366
|
total_pending += pending
|
368
367
|
total_failed += failed
|
369
|
-
|
368
|
+
|
370
369
|
self.stdout.write(f" {queue_name}: {pending} pending, {failed} failed")
|
371
|
-
|
370
|
+
|
372
371
|
self.stdout.write(f"👷 Created {len(results['workers'])} workers")
|
373
|
-
self.stdout.write(
|
374
|
-
|
372
|
+
self.stdout.write("📊 Added task statistics")
|
373
|
+
|
375
374
|
self.stdout.write("=" * 50)
|
376
375
|
self.stdout.write(self.style.SUCCESS("✅ Simulation completed!"))
|
377
|
-
|
378
|
-
self.stdout.write(
|
376
|
+
|
377
|
+
self.stdout.write("\n📊 Summary:")
|
379
378
|
active_queues = len(results['queues'])
|
380
379
|
self.stdout.write(f" Active Queues: {active_queues}")
|
381
380
|
self.stdout.write(f" Active Workers: {len(results['workers'])}")
|
382
381
|
self.stdout.write(f" Pending Tasks: {total_pending}")
|
383
382
|
self.stdout.write(f" Failed Tasks: {total_failed}")
|
384
|
-
|
385
|
-
self.stdout.write(
|
386
|
-
|
383
|
+
|
384
|
+
self.stdout.write("\n🌐 Dashboard URL: http://localhost:8000/cfg/admin/django_cfg_tasks/admin/dashboard/")
|
385
|
+
|
387
386
|
# Показать ключи если запрошено
|
388
387
|
if options['show_keys']:
|
389
388
|
self.show_redis_keys(simulator)
|
390
|
-
|
389
|
+
|
391
390
|
except Exception as e:
|
392
391
|
raise CommandError(f"Simulation failed: {e}")
|
393
|
-
|
392
|
+
|
394
393
|
def show_summary(self, simulator: TaskSimulator):
|
395
394
|
"""Показать сводку текущих данных."""
|
396
395
|
self.stdout.write("📊 Current Redis Data Summary")
|
397
396
|
self.stdout.write("=" * 40)
|
398
|
-
|
397
|
+
|
399
398
|
summary = simulator.get_redis_summary()
|
400
|
-
|
399
|
+
|
401
400
|
self.stdout.write(f"Total Redis keys: {summary['total_keys']}")
|
402
401
|
self.stdout.write(f"Active workers: {summary['workers']}")
|
403
|
-
|
402
|
+
|
404
403
|
if summary['queues']:
|
405
404
|
self.stdout.write("\nQueues:")
|
406
405
|
for queue_name, counts in summary['queues'].items():
|
407
406
|
self.stdout.write(f" {queue_name}: {counts['pending']} pending, {counts['failed']} failed")
|
408
407
|
else:
|
409
408
|
self.stdout.write("\nNo active queues found")
|
410
|
-
|
409
|
+
|
411
410
|
if summary['statistics']:
|
412
411
|
stats = summary['statistics']
|
413
|
-
self.stdout.write(
|
412
|
+
self.stdout.write("\nStatistics:")
|
414
413
|
self.stdout.write(f" Total processed: {stats.get('total_processed', 'N/A')}")
|
415
414
|
self.stdout.write(f" Total failed: {stats.get('total_failed', 'N/A')}")
|
416
415
|
self.stdout.write(f" Avg processing time: {stats.get('processing_time_avg', 'N/A')}s")
|
417
|
-
|
416
|
+
|
418
417
|
def show_redis_keys(self, simulator: TaskSimulator):
|
419
418
|
"""Показать все Redis ключи."""
|
420
419
|
self.stdout.write("\n🔍 Redis Keys:")
|
421
420
|
keys = simulator.redis_client.keys("dramatiq:*")
|
422
|
-
|
421
|
+
|
423
422
|
if not keys:
|
424
423
|
self.stdout.write(" No Dramatiq keys found")
|
425
424
|
return
|
426
|
-
|
425
|
+
|
427
426
|
for key in sorted(keys):
|
428
427
|
key_type = simulator.redis_client.type(key)
|
429
428
|
if key_type == 'list':
|