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
@@ -3,23 +3,24 @@ Data models for currency conversion and API responses.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
from datetime import datetime
|
6
|
-
from typing import
|
6
|
+
from typing import List, Optional
|
7
|
+
|
7
8
|
from pydantic import BaseModel, Field, RootModel
|
8
9
|
|
9
10
|
|
10
11
|
class Rate(BaseModel):
|
11
12
|
"""Currency exchange rate model."""
|
12
|
-
|
13
|
+
|
13
14
|
source: str = Field(description="Data source (yahoo, coinpaprika)")
|
14
15
|
base_currency: str = Field(description="Base currency code")
|
15
|
-
quote_currency: str = Field(description="Quote currency code")
|
16
|
+
quote_currency: str = Field(description="Quote currency code")
|
16
17
|
rate: float = Field(description="Exchange rate")
|
17
18
|
timestamp: datetime = Field(default_factory=datetime.now, description="Rate timestamp")
|
18
19
|
|
19
20
|
|
20
21
|
class ConversionRequest(BaseModel):
|
21
22
|
"""Currency conversion request model."""
|
22
|
-
|
23
|
+
|
23
24
|
amount: float = Field(gt=0, description="Amount to convert")
|
24
25
|
from_currency: str = Field(description="Source currency code")
|
25
26
|
to_currency: str = Field(description="Target currency code")
|
@@ -27,7 +28,7 @@ class ConversionRequest(BaseModel):
|
|
27
28
|
|
28
29
|
class ConversionResult(BaseModel):
|
29
30
|
"""Currency conversion result model."""
|
30
|
-
|
31
|
+
|
31
32
|
request: ConversionRequest = Field(description="Original request")
|
32
33
|
result: float = Field(description="Converted amount")
|
33
34
|
rate: Rate = Field(description="Exchange rate used")
|
@@ -36,19 +37,19 @@ class ConversionResult(BaseModel):
|
|
36
37
|
|
37
38
|
class YahooFinanceCurrencies(BaseModel):
|
38
39
|
"""Yahoo Finance supported currencies model."""
|
39
|
-
|
40
|
+
|
40
41
|
fiat: List[str] = Field(description="Supported fiat currencies")
|
41
42
|
|
42
43
|
|
43
44
|
class CoinPaprikaCurrencies(BaseModel):
|
44
45
|
"""CoinPaprika supported currencies model."""
|
45
|
-
|
46
|
+
|
46
47
|
crypto: List[str] = Field(description="Supported cryptocurrencies")
|
47
48
|
|
48
49
|
|
49
50
|
class SupportedCurrencies(BaseModel):
|
50
51
|
"""All supported currencies model."""
|
51
|
-
|
52
|
+
|
52
53
|
yahoo: YahooFinanceCurrencies = Field(description="Yahoo Finance currencies")
|
53
54
|
coinpaprika: CoinPaprikaCurrencies = Field(description="CoinPaprika currencies")
|
54
55
|
|
@@ -3,19 +3,19 @@ Database utilities for currency management.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
from .database_loader import (
|
6
|
+
CoinPaprikaCoinInfo,
|
6
7
|
CurrencyDatabaseLoader,
|
8
|
+
CurrencyRateInfo,
|
7
9
|
DatabaseLoaderConfig,
|
8
|
-
CoinPaprikaCoinInfo,
|
9
10
|
HybridCurrencyInfo,
|
10
|
-
CurrencyRateInfo,
|
11
11
|
RateLimiter,
|
12
12
|
create_database_loader,
|
13
|
-
load_currencies_to_database_format
|
13
|
+
load_currencies_to_database_format,
|
14
14
|
)
|
15
15
|
|
16
16
|
__all__ = [
|
17
17
|
'CurrencyDatabaseLoader',
|
18
|
-
'DatabaseLoaderConfig',
|
18
|
+
'DatabaseLoaderConfig',
|
19
19
|
'CoinPaprikaCoinInfo',
|
20
20
|
'HybridCurrencyInfo',
|
21
21
|
'CurrencyRateInfo',
|
@@ -4,15 +4,11 @@ Database loader for populating currency data using Yahoo Finance + CoinPaprika.
|
|
4
4
|
|
5
5
|
import logging
|
6
6
|
import time
|
7
|
-
from datetime import datetime
|
8
|
-
from typing import
|
9
|
-
from dataclasses import dataclass
|
7
|
+
from datetime import datetime
|
8
|
+
from typing import Dict, List, Optional
|
10
9
|
|
11
|
-
from pydantic import BaseModel, Field, validator
|
12
10
|
from cachetools import TTLCache
|
13
|
-
|
14
|
-
# Our new clients
|
15
|
-
from ..clients import HybridCurrencyClient, CoinPaprikaClient
|
11
|
+
from pydantic import BaseModel, Field
|
16
12
|
|
17
13
|
logger = logging.getLogger(__name__)
|
18
14
|
|
@@ -49,31 +45,31 @@ class CurrencyRateInfo(BaseModel):
|
|
49
45
|
|
50
46
|
class RateLimiter:
|
51
47
|
"""Simple rate limiter for API calls."""
|
52
|
-
|
48
|
+
|
53
49
|
def __init__(self, max_requests_per_minute: int = 30):
|
54
50
|
self.max_requests = max_requests_per_minute
|
55
51
|
self.request_times = []
|
56
|
-
|
52
|
+
|
57
53
|
def __call__(self):
|
58
54
|
"""Wait if necessary to respect rate limits."""
|
59
55
|
now = time.time()
|
60
|
-
|
56
|
+
|
61
57
|
# Remove requests older than 1 minute
|
62
58
|
self.request_times = [t for t in self.request_times if now - t < 60]
|
63
|
-
|
59
|
+
|
64
60
|
# If we're at the limit, wait
|
65
61
|
if len(self.request_times) >= self.max_requests:
|
66
62
|
sleep_time = 60 - (now - self.request_times[0]) + 1
|
67
63
|
if sleep_time > 0:
|
68
64
|
logger.debug(f"Rate limiting: sleeping for {sleep_time:.1f}s")
|
69
65
|
time.sleep(sleep_time)
|
70
|
-
|
66
|
+
|
71
67
|
self.request_times.append(now)
|
72
68
|
|
73
69
|
|
74
70
|
class DatabaseLoaderConfig(BaseModel):
|
75
71
|
"""Configuration for database loader."""
|
76
|
-
|
72
|
+
|
77
73
|
yahoo_delay: float = Field(default=1.0, description="Delay between Yahoo requests")
|
78
74
|
coinpaprika_delay: float = Field(default=0.5, description="Delay between CoinPaprika requests")
|
79
75
|
max_requests_per_minute: int = Field(default=30, description="Max requests per minute")
|
@@ -88,26 +84,29 @@ class CurrencyDatabaseLoader:
|
|
88
84
|
"""
|
89
85
|
Database loader for populating currency data from Yahoo Finance and CoinPaprika.
|
90
86
|
"""
|
91
|
-
|
87
|
+
|
92
88
|
def __init__(self, config: DatabaseLoaderConfig = None):
|
93
89
|
"""Initialize the database loader."""
|
90
|
+
# Lazy import to avoid circular dependency
|
91
|
+
from ..clients import CoinPaprikaClient, HybridCurrencyClient
|
92
|
+
|
94
93
|
self.config = config or DatabaseLoaderConfig()
|
95
|
-
|
94
|
+
|
96
95
|
# Initialize clients
|
97
96
|
self.hybrid = HybridCurrencyClient(cache_ttl=self.config.cache_ttl_hours * 3600)
|
98
97
|
self.coinpaprika = CoinPaprikaClient(cache_ttl=self.config.cache_ttl_hours * 3600)
|
99
|
-
|
98
|
+
|
100
99
|
# Rate limiters
|
101
100
|
self.yahoo_limiter = RateLimiter(self.config.max_requests_per_minute)
|
102
101
|
self.coinpaprika_limiter = RateLimiter(self.config.max_requests_per_minute)
|
103
|
-
|
102
|
+
|
104
103
|
# Caches
|
105
104
|
cache_ttl = self.config.cache_ttl_hours * 3600
|
106
105
|
self.crypto_cache = TTLCache(maxsize=1000, ttl=cache_ttl)
|
107
106
|
self.fiat_cache = TTLCache(maxsize=100, ttl=cache_ttl)
|
108
|
-
|
107
|
+
|
109
108
|
logger.info(f"Initialized CurrencyDatabaseLoader with config: {self.config}")
|
110
|
-
|
109
|
+
|
111
110
|
def get_hybrid_currency_list(self) -> List[HybridCurrencyInfo]:
|
112
111
|
"""
|
113
112
|
Get list of supported currencies from hybrid client.
|
@@ -116,19 +115,19 @@ class CurrencyDatabaseLoader:
|
|
116
115
|
List of currency info objects
|
117
116
|
"""
|
118
117
|
cache_key = "hybrid_currencies"
|
119
|
-
|
118
|
+
|
120
119
|
if cache_key in self.fiat_cache:
|
121
120
|
logger.debug("Retrieved hybrid currencies from cache")
|
122
121
|
return self.fiat_cache[cache_key]
|
123
|
-
|
122
|
+
|
124
123
|
# Get supported currencies from Hybrid client
|
125
124
|
supported_currencies = self.hybrid.get_all_supported_currencies()
|
126
|
-
|
125
|
+
|
127
126
|
# Convert to our format
|
128
127
|
hybrid_currencies = []
|
129
128
|
for code, name in supported_currencies.items():
|
130
129
|
# Determine currency type based on code
|
131
|
-
if code in ['BTC', 'ETH', 'BNB', 'XRP', 'ADA', 'SOL', 'DOT', 'MATIC',
|
130
|
+
if code in ['BTC', 'ETH', 'BNB', 'XRP', 'ADA', 'SOL', 'DOT', 'MATIC',
|
132
131
|
'LTC', 'BCH', 'LINK', 'UNI', 'ATOM', 'XLM', 'VET', 'FIL',
|
133
132
|
'TRX', 'ETC', 'THETA', 'AAVE', 'MKR', 'COMP', 'SUSHI',
|
134
133
|
'USDT', 'USDC', 'BUSD', 'DAI', 'TUSD', 'USDP']:
|
@@ -137,7 +136,7 @@ class CurrencyDatabaseLoader:
|
|
137
136
|
currency_type = "metal"
|
138
137
|
else:
|
139
138
|
currency_type = "fiat"
|
140
|
-
|
139
|
+
|
141
140
|
currency_info = HybridCurrencyInfo(
|
142
141
|
code=code,
|
143
142
|
name=name,
|
@@ -145,12 +144,12 @@ class CurrencyDatabaseLoader:
|
|
145
144
|
currency_type=currency_type
|
146
145
|
)
|
147
146
|
hybrid_currencies.append(currency_info)
|
148
|
-
|
147
|
+
|
149
148
|
self.fiat_cache[cache_key] = hybrid_currencies
|
150
149
|
logger.info(f"Loaded {len(hybrid_currencies)} currencies from hybrid client")
|
151
|
-
|
150
|
+
|
152
151
|
return hybrid_currencies
|
153
|
-
|
152
|
+
|
154
153
|
def get_cryptocurrency_list(self) -> List[CoinPaprikaCoinInfo]:
|
155
154
|
"""
|
156
155
|
Get list of supported cryptocurrencies from CoinPaprika.
|
@@ -159,45 +158,45 @@ class CurrencyDatabaseLoader:
|
|
159
158
|
List of cryptocurrency info objects
|
160
159
|
"""
|
161
160
|
cache_key = "crypto_currencies"
|
162
|
-
|
161
|
+
|
163
162
|
if cache_key in self.crypto_cache:
|
164
163
|
logger.debug("Retrieved cryptocurrencies from cache")
|
165
164
|
return self.crypto_cache[cache_key]
|
166
|
-
|
165
|
+
|
167
166
|
try:
|
168
167
|
# Get all tickers from CoinPaprika
|
169
168
|
all_tickers = self.coinpaprika._fetch_all_tickers()
|
170
|
-
|
169
|
+
|
171
170
|
crypto_currencies = []
|
172
171
|
for symbol, data in all_tickers.items():
|
173
172
|
# Skip if no price data
|
174
173
|
if data.get('price_usd') is None:
|
175
174
|
continue
|
176
|
-
|
175
|
+
|
177
176
|
# Apply market cap filter if needed
|
178
177
|
# Note: CoinPaprika doesn't provide market cap in tickers endpoint
|
179
178
|
# We'd need to use a different endpoint for that
|
180
|
-
|
179
|
+
|
181
180
|
coin_info = CoinPaprikaCoinInfo(
|
182
181
|
id=data['id'],
|
183
182
|
symbol=symbol,
|
184
183
|
name=data['name']
|
185
184
|
)
|
186
185
|
crypto_currencies.append(coin_info)
|
187
|
-
|
186
|
+
|
188
187
|
# Limit count
|
189
188
|
if len(crypto_currencies) >= self.config.max_cryptocurrencies:
|
190
189
|
break
|
191
|
-
|
190
|
+
|
192
191
|
self.crypto_cache[cache_key] = crypto_currencies
|
193
192
|
logger.info(f"Loaded {len(crypto_currencies)} cryptocurrencies")
|
194
|
-
|
193
|
+
|
195
194
|
return crypto_currencies
|
196
|
-
|
195
|
+
|
197
196
|
except Exception as e:
|
198
197
|
logger.error(f"Failed to get cryptocurrency list: {e}")
|
199
198
|
return []
|
200
|
-
|
199
|
+
|
201
200
|
def get_currency_rates(self, currency_ids: List[str], quote: str = 'usd') -> Dict[str, float]:
|
202
201
|
"""
|
203
202
|
Get current rates for multiple cryptocurrencies.
|
@@ -210,24 +209,24 @@ class CurrencyDatabaseLoader:
|
|
210
209
|
Dict mapping currency ID to rate
|
211
210
|
"""
|
212
211
|
self.coinpaprika_limiter()
|
213
|
-
|
212
|
+
|
214
213
|
try:
|
215
214
|
rates = {}
|
216
215
|
all_tickers = self.coinpaprika._fetch_all_tickers()
|
217
|
-
|
216
|
+
|
218
217
|
for currency_id in currency_ids:
|
219
218
|
if currency_id.upper() in all_tickers:
|
220
219
|
price = all_tickers[currency_id.upper()].get('price_usd')
|
221
220
|
if price is not None:
|
222
221
|
rates[currency_id] = price
|
223
|
-
|
222
|
+
|
224
223
|
logger.debug(f"Retrieved rates for {len(rates)} currencies")
|
225
224
|
return rates
|
226
|
-
|
225
|
+
|
227
226
|
except Exception as e:
|
228
227
|
logger.error(f"Failed to get currency rates: {e}")
|
229
228
|
return {}
|
230
|
-
|
229
|
+
|
231
230
|
def get_fiat_rate(self, base: str, quote: str) -> Optional[float]:
|
232
231
|
"""
|
233
232
|
Get exchange rate for fiat currency pair.
|
@@ -242,16 +241,16 @@ class CurrencyDatabaseLoader:
|
|
242
241
|
# Handle same currency
|
243
242
|
if base.upper() == quote.upper():
|
244
243
|
return 1.0
|
245
|
-
|
244
|
+
|
246
245
|
self.yahoo_limiter()
|
247
|
-
|
246
|
+
|
248
247
|
try:
|
249
248
|
rate_obj = self.hybrid.fetch_rate(base, quote)
|
250
249
|
return rate_obj.rate
|
251
250
|
except Exception as e:
|
252
251
|
logger.debug(f"Failed to get fiat rate {base}/{quote}: {e}")
|
253
252
|
return None
|
254
|
-
|
253
|
+
|
255
254
|
def build_currency_database_data(self) -> List[CurrencyRateInfo]:
|
256
255
|
"""
|
257
256
|
Build complete currency database data using hybrid client.
|
@@ -260,11 +259,11 @@ class CurrencyDatabaseLoader:
|
|
260
259
|
List of currency rate info objects
|
261
260
|
"""
|
262
261
|
currencies = []
|
263
|
-
|
262
|
+
|
264
263
|
# Get currencies from hybrid client
|
265
264
|
logger.info("Loading currencies from hybrid client...")
|
266
265
|
hybrid_currencies = self.get_hybrid_currency_list()
|
267
|
-
|
266
|
+
|
268
267
|
for currency in hybrid_currencies:
|
269
268
|
# Get USD rate
|
270
269
|
if currency.code == 'USD':
|
@@ -274,7 +273,7 @@ class CurrencyDatabaseLoader:
|
|
274
273
|
if usd_rate is None:
|
275
274
|
logger.warning(f"Could not get USD rate for {currency.code}")
|
276
275
|
continue
|
277
|
-
|
276
|
+
|
278
277
|
# Set decimal places based on currency type and value
|
279
278
|
if currency.currency_type == "fiat":
|
280
279
|
decimal_places = 2
|
@@ -290,7 +289,7 @@ class CurrencyDatabaseLoader:
|
|
290
289
|
else: # metal
|
291
290
|
decimal_places = 4
|
292
291
|
min_payment = 0.001
|
293
|
-
|
292
|
+
|
294
293
|
currency_info = CurrencyRateInfo(
|
295
294
|
code=currency.code,
|
296
295
|
name=currency.name,
|
@@ -301,28 +300,28 @@ class CurrencyDatabaseLoader:
|
|
301
300
|
min_payment_amount=min_payment
|
302
301
|
)
|
303
302
|
currencies.append(currency_info)
|
304
|
-
|
303
|
+
|
305
304
|
# Get additional cryptocurrencies from CoinPaprika (for extended crypto coverage)
|
306
305
|
logger.info("Loading additional cryptocurrencies from CoinPaprika...")
|
307
306
|
crypto_currencies = self.get_cryptocurrency_list()
|
308
|
-
|
307
|
+
|
309
308
|
# Filter out cryptos that are already in hybrid client
|
310
309
|
hybrid_crypto_codes = {c.code for c in hybrid_currencies if c.currency_type == "crypto"}
|
311
|
-
|
310
|
+
|
312
311
|
if crypto_currencies:
|
313
312
|
# Get rates for all cryptos
|
314
|
-
crypto_symbols = [crypto.symbol for crypto in crypto_currencies
|
313
|
+
crypto_symbols = [crypto.symbol for crypto in crypto_currencies
|
315
314
|
if crypto.symbol not in hybrid_crypto_codes]
|
316
315
|
rates = self.get_currency_rates(crypto_symbols, 'usd')
|
317
|
-
|
316
|
+
|
318
317
|
for crypto in crypto_currencies:
|
319
318
|
# Skip if already covered by hybrid client
|
320
319
|
if crypto.symbol in hybrid_crypto_codes:
|
321
320
|
continue
|
322
|
-
|
321
|
+
|
323
322
|
if crypto.symbol in rates:
|
324
323
|
usd_rate = rates[crypto.symbol]
|
325
|
-
|
324
|
+
|
326
325
|
# Calculate appropriate decimal places based on USD value
|
327
326
|
if usd_rate >= 1:
|
328
327
|
decimal_places = 2
|
@@ -330,10 +329,10 @@ class CurrencyDatabaseLoader:
|
|
330
329
|
decimal_places = 4
|
331
330
|
else:
|
332
331
|
decimal_places = 8
|
333
|
-
|
332
|
+
|
334
333
|
# Calculate minimum payment amount (roughly $1 worth)
|
335
334
|
min_payment = max(1.0 / usd_rate, 0.000001)
|
336
|
-
|
335
|
+
|
337
336
|
currency_info = CurrencyRateInfo(
|
338
337
|
code=crypto.symbol,
|
339
338
|
name=crypto.name,
|
@@ -344,26 +343,26 @@ class CurrencyDatabaseLoader:
|
|
344
343
|
min_payment_amount=min_payment
|
345
344
|
)
|
346
345
|
currencies.append(currency_info)
|
347
|
-
|
346
|
+
|
348
347
|
logger.info(f"Built database data for {len(currencies)} currencies")
|
349
348
|
return currencies
|
350
|
-
|
349
|
+
|
351
350
|
def get_statistics(self) -> Dict[str, int]:
|
352
351
|
"""Get loader statistics."""
|
353
352
|
hybrid_currencies = self.get_hybrid_currency_list()
|
354
353
|
coinpaprika_cryptos = self.get_cryptocurrency_list()
|
355
|
-
|
354
|
+
|
356
355
|
# Count by type from hybrid client
|
357
356
|
fiat_count = len([c for c in hybrid_currencies if c.currency_type == "fiat"])
|
358
357
|
hybrid_crypto_count = len([c for c in hybrid_currencies if c.currency_type == "crypto"])
|
359
358
|
metal_count = len([c for c in hybrid_currencies if c.currency_type == "metal"])
|
360
|
-
|
359
|
+
|
361
360
|
# Additional cryptos from CoinPaprika (excluding duplicates)
|
362
361
|
hybrid_crypto_codes = {c.code for c in hybrid_currencies if c.currency_type == "crypto"}
|
363
362
|
additional_crypto_count = len([c for c in coinpaprika_cryptos if c.symbol not in hybrid_crypto_codes])
|
364
|
-
|
363
|
+
|
365
364
|
total_crypto_count = hybrid_crypto_count + additional_crypto_count
|
366
|
-
|
365
|
+
|
367
366
|
return {
|
368
367
|
'total_fiat_currencies': fiat_count,
|
369
368
|
'total_cryptocurrencies': total_crypto_count,
|
@@ -420,7 +419,7 @@ def load_currencies_to_database_format() -> List[Dict]:
|
|
420
419
|
"""
|
421
420
|
loader = create_database_loader()
|
422
421
|
currencies = loader.build_currency_database_data()
|
423
|
-
|
422
|
+
|
424
423
|
# Convert to dict format
|
425
424
|
result = []
|
426
425
|
for currency in currencies:
|
@@ -435,5 +434,5 @@ def load_currencies_to_database_format() -> List[Dict]:
|
|
435
434
|
'rate_updated_at': datetime.now()
|
436
435
|
}
|
437
436
|
result.append(currency_dict)
|
438
|
-
|
437
|
+
|
439
438
|
return result
|
@@ -3,11 +3,12 @@ Example usage of the database loader for populating currency data.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
+
|
6
7
|
from .database_loader import (
|
7
|
-
CurrencyDatabaseLoader,
|
8
|
+
CurrencyDatabaseLoader,
|
8
9
|
DatabaseLoaderConfig,
|
9
10
|
create_database_loader,
|
10
|
-
load_currencies_to_database_format
|
11
|
+
load_currencies_to_database_format,
|
11
12
|
)
|
12
13
|
|
13
14
|
# Configure logging
|
@@ -17,7 +18,7 @@ logging.basicConfig(level=logging.INFO, format='%(name)s:%(levelname)s: %(messag
|
|
17
18
|
def example_basic_usage():
|
18
19
|
"""Basic example of using the database loader."""
|
19
20
|
print("๐ Creating database loader...")
|
20
|
-
|
21
|
+
|
21
22
|
# Create loader with default settings
|
22
23
|
loader = create_database_loader(
|
23
24
|
max_cryptocurrencies=100, # Limit to top 100 cryptos
|
@@ -25,38 +26,38 @@ def example_basic_usage():
|
|
25
26
|
min_market_cap_usd=10_000_000, # 10M USD minimum
|
26
27
|
coingecko_delay=2.0 # 2 second delay between requests
|
27
28
|
)
|
28
|
-
|
29
|
+
|
29
30
|
# Get statistics
|
30
31
|
print("๐ Statistics:")
|
31
32
|
stats = loader.get_statistics()
|
32
33
|
for key, value in stats.items():
|
33
34
|
print(f" {key}: {value}")
|
34
|
-
|
35
|
+
|
35
36
|
print("\n๐ช Building currency database data...")
|
36
|
-
|
37
|
+
|
37
38
|
# Build complete currency data
|
38
39
|
currencies = loader.build_currency_database_data()
|
39
|
-
|
40
|
+
|
40
41
|
print(f"\nโ
Successfully loaded {len(currencies)} currencies")
|
41
|
-
|
42
|
+
|
42
43
|
# Show sample data
|
43
44
|
print("\n๐ Sample currencies:")
|
44
45
|
for i, currency in enumerate(currencies[:10]):
|
45
46
|
print(f" {i+1}. {currency.code} ({currency.currency_type}): "
|
46
47
|
f"{currency.name} = ${currency.usd_rate:.6f}")
|
47
|
-
|
48
|
+
|
48
49
|
return currencies
|
49
50
|
|
50
51
|
|
51
52
|
def example_django_integration():
|
52
53
|
"""Example of how to integrate with Django ORM."""
|
53
54
|
print("๐ Loading currencies in Django format...")
|
54
|
-
|
55
|
+
|
55
56
|
# Get currencies in Django-ready format
|
56
57
|
currency_dicts = load_currencies_to_database_format()
|
57
|
-
|
58
|
+
|
58
59
|
print(f"โ
Ready to insert {len(currency_dicts)} currencies into Django ORM")
|
59
|
-
|
60
|
+
|
60
61
|
# This is how you would use it in Django:
|
61
62
|
print("\n๐ก Django integration example:")
|
62
63
|
print("""
|
@@ -77,67 +78,67 @@ def example_django_integration():
|
|
77
78
|
Currency.objects.bulk_create(currencies_to_create, ignore_conflicts=True)
|
78
79
|
print(f"Inserted {len(currencies_to_create)} currencies")
|
79
80
|
""")
|
80
|
-
|
81
|
+
|
81
82
|
return currency_dicts
|
82
83
|
|
83
84
|
|
84
85
|
def example_advanced_config():
|
85
86
|
"""Example with advanced configuration."""
|
86
87
|
print("๐ง Advanced configuration example...")
|
87
|
-
|
88
|
+
|
88
89
|
# Custom configuration
|
89
90
|
config = DatabaseLoaderConfig(
|
90
91
|
# Rate limiting
|
91
92
|
coingecko_delay=3.0, # Slower requests for stability
|
92
93
|
yfinance_delay=1.0,
|
93
94
|
max_requests_per_minute=20, # Conservative rate limit
|
94
|
-
|
95
|
+
|
95
96
|
# Limits
|
96
97
|
max_cryptocurrencies=50, # Smaller set
|
97
98
|
max_fiat_currencies=20,
|
98
|
-
|
99
|
+
|
99
100
|
# Filtering
|
100
101
|
min_market_cap_usd=50_000_000, # Higher threshold - 50M USD
|
101
102
|
exclude_stablecoins=True, # Skip stablecoins
|
102
|
-
|
103
|
+
|
103
104
|
# Cache
|
104
105
|
cache_ttl_hours=12 # Cache for 12 hours
|
105
106
|
)
|
106
|
-
|
107
|
+
|
107
108
|
loader = CurrencyDatabaseLoader(config)
|
108
|
-
|
109
|
-
print(
|
109
|
+
|
110
|
+
print("๐ Configuration:")
|
110
111
|
print(f" Max cryptocurrencies: {config.max_cryptocurrencies}")
|
111
112
|
print(f" Min market cap: ${config.min_market_cap_usd:,.0f}")
|
112
113
|
print(f" Exclude stablecoins: {config.exclude_stablecoins}")
|
113
114
|
print(f" CoinGecko delay: {config.coingecko_delay}s")
|
114
|
-
|
115
|
+
|
115
116
|
return loader
|
116
117
|
|
117
118
|
|
118
119
|
if __name__ == "__main__":
|
119
120
|
print("๐งช CURRENCY DATABASE LOADER EXAMPLES")
|
120
121
|
print("=" * 50)
|
121
|
-
|
122
|
+
|
122
123
|
try:
|
123
124
|
# Basic usage
|
124
125
|
print("\n1๏ธโฃ BASIC USAGE:")
|
125
126
|
currencies = example_basic_usage()
|
126
|
-
|
127
|
+
|
127
128
|
print("\n" + "=" * 50)
|
128
|
-
|
129
|
+
|
129
130
|
# Django integration
|
130
131
|
print("\n2๏ธโฃ DJANGO INTEGRATION:")
|
131
132
|
django_data = example_django_integration()
|
132
|
-
|
133
|
+
|
133
134
|
print("\n" + "=" * 50)
|
134
|
-
|
135
|
+
|
135
136
|
# Advanced config
|
136
137
|
print("\n3๏ธโฃ ADVANCED CONFIGURATION:")
|
137
138
|
advanced_loader = example_advanced_config()
|
138
|
-
|
139
|
+
|
139
140
|
print("\n๐ All examples completed successfully!")
|
140
|
-
|
141
|
+
|
141
142
|
except Exception as e:
|
142
143
|
print(f"โ Error: {e}")
|
143
144
|
import traceback
|
@@ -3,19 +3,18 @@ Simple cache manager for currency rates.
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import logging
|
6
|
-
from
|
7
|
-
|
6
|
+
from typing import Any, Dict, Optional
|
7
|
+
|
8
8
|
from cachetools import TTLCache
|
9
9
|
|
10
10
|
from ..core.models import Rate
|
11
|
-
from ..core.exceptions import CacheError
|
12
11
|
|
13
12
|
logger = logging.getLogger(__name__)
|
14
13
|
|
15
14
|
|
16
15
|
class CacheManager:
|
17
16
|
"""Simple TTL cache for currency rates."""
|
18
|
-
|
17
|
+
|
19
18
|
def __init__(self, ttl: int = 300, maxsize: int = 1000):
|
20
19
|
"""
|
21
20
|
Initialize cache manager.
|
@@ -26,7 +25,7 @@ class CacheManager:
|
|
26
25
|
"""
|
27
26
|
self.cache = TTLCache(maxsize=maxsize, ttl=ttl)
|
28
27
|
self.ttl = ttl
|
29
|
-
|
28
|
+
|
30
29
|
def get_rate(self, base: str, quote: str, source: str) -> Optional[Rate]:
|
31
30
|
"""
|
32
31
|
Get cached rate.
|
@@ -40,7 +39,7 @@ class CacheManager:
|
|
40
39
|
Cached Rate or None
|
41
40
|
"""
|
42
41
|
key = self._make_key(base, quote, source)
|
43
|
-
|
42
|
+
|
44
43
|
try:
|
45
44
|
cached_rate = self.cache.get(key)
|
46
45
|
if cached_rate:
|
@@ -52,7 +51,7 @@ class CacheManager:
|
|
52
51
|
except Exception as e:
|
53
52
|
logger.error(f"Cache get error: {e}")
|
54
53
|
return None
|
55
|
-
|
54
|
+
|
56
55
|
def set_rate(self, rate: Rate) -> bool:
|
57
56
|
"""
|
58
57
|
Cache rate.
|
@@ -64,7 +63,7 @@ class CacheManager:
|
|
64
63
|
True if cached successfully
|
65
64
|
"""
|
66
65
|
key = self._make_key(rate.base_currency, rate.quote_currency, rate.source)
|
67
|
-
|
66
|
+
|
68
67
|
try:
|
69
68
|
self.cache[key] = rate
|
70
69
|
logger.debug(f"Cached rate for {key}")
|
@@ -72,16 +71,16 @@ class CacheManager:
|
|
72
71
|
except Exception as e:
|
73
72
|
logger.error(f"Cache set error: {e}")
|
74
73
|
return False
|
75
|
-
|
74
|
+
|
76
75
|
def _make_key(self, base: str, quote: str, source: str) -> str:
|
77
76
|
"""Make cache key."""
|
78
77
|
return f"{source}:{base}:{quote}".upper()
|
79
|
-
|
78
|
+
|
80
79
|
def clear(self) -> None:
|
81
80
|
"""Clear all cached rates."""
|
82
81
|
self.cache.clear()
|
83
82
|
logger.info("Cache cleared")
|
84
|
-
|
83
|
+
|
85
84
|
def get_stats(self) -> Dict[str, Any]:
|
86
85
|
"""Get cache statistics."""
|
87
86
|
return {
|