django-cfg 1.2.23__py3-none-any.whl → 1.2.27__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/knowbase/tasks/archive_tasks.py +6 -6
- django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
- django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
- django_cfg/apps/payments/config/__init__.py +15 -37
- django_cfg/apps/payments/config/module.py +30 -122
- django_cfg/apps/payments/config/providers.py +28 -16
- django_cfg/apps/payments/config/settings.py +53 -93
- django_cfg/apps/payments/config/utils.py +10 -156
- django_cfg/apps/payments/management/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/README.md +178 -0
- django_cfg/apps/payments/management/commands/__init__.py +3 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
- django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
- django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
- django_cfg/apps/payments/managers/currency_manager.py +65 -14
- django_cfg/apps/payments/middleware/api_access.py +33 -0
- django_cfg/apps/payments/migrations/0001_initial.py +94 -1
- django_cfg/apps/payments/models/payments.py +110 -0
- django_cfg/apps/payments/services/__init__.py +7 -1
- django_cfg/apps/payments/services/core/balance_service.py +14 -16
- django_cfg/apps/payments/services/core/fallback_service.py +432 -0
- django_cfg/apps/payments/services/core/payment_service.py +212 -29
- django_cfg/apps/payments/services/core/subscription_service.py +15 -17
- django_cfg/apps/payments/services/internal_types.py +31 -0
- django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
- django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
- django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
- django_cfg/apps/payments/services/providers/__init__.py +3 -0
- django_cfg/apps/payments/services/providers/cryptapi.py +14 -3
- django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
- django_cfg/apps/payments/services/providers/registry.py +4 -0
- django_cfg/apps/payments/services/security/__init__.py +34 -0
- django_cfg/apps/payments/services/security/error_handler.py +637 -0
- django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
- django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
- django_cfg/apps/payments/signals/api_key_signals.py +10 -0
- django_cfg/apps/payments/signals/payment_signals.py +3 -2
- django_cfg/apps/payments/tasks/__init__.py +12 -0
- django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
- django_cfg/apps/payments/utils/__init__.py +7 -4
- django_cfg/apps/payments/utils/billing_utils.py +342 -0
- django_cfg/apps/payments/utils/config_utils.py +2 -0
- django_cfg/apps/payments/views/payment_views.py +40 -2
- django_cfg/apps/payments/views/webhook_views.py +266 -0
- django_cfg/apps/payments/viewsets.py +65 -0
- django_cfg/cli/README.md +2 -2
- django_cfg/cli/commands/create_project.py +1 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/main.py +1 -1
- django_cfg/cli/utils.py +5 -5
- django_cfg/core/config.py +18 -4
- django_cfg/models/payments.py +547 -0
- django_cfg/models/tasks.py +51 -2
- django_cfg/modules/base.py +11 -5
- django_cfg/modules/django_currency/README.md +104 -269
- django_cfg/modules/django_currency/__init__.py +99 -41
- django_cfg/modules/django_currency/clients/__init__.py +11 -0
- django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
- django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
- django_cfg/modules/django_currency/core/__init__.py +42 -0
- django_cfg/modules/django_currency/core/converter.py +169 -0
- django_cfg/modules/django_currency/core/exceptions.py +28 -0
- django_cfg/modules/django_currency/core/models.py +54 -0
- django_cfg/modules/django_currency/database/__init__.py +25 -0
- django_cfg/modules/django_currency/database/database_loader.py +507 -0
- django_cfg/modules/django_currency/utils/__init__.py +9 -0
- django_cfg/modules/django_currency/utils/cache.py +92 -0
- django_cfg/registry/core.py +10 -0
- django_cfg/template_archive/__init__.py +0 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/METADATA +10 -6
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/RECORD +77 -51
- django_cfg/apps/agents/examples/__init__.py +0 -3
- django_cfg/apps/agents/examples/simple_example.py +0 -161
- django_cfg/apps/knowbase/examples/__init__.py +0 -3
- django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
- django_cfg/modules/django_currency/cache.py +0 -430
- django_cfg/modules/django_currency/converter.py +0 -324
- django_cfg/modules/django_currency/service.py +0 -277
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.23.dist-info → django_cfg-1.2.27.dist-info}/licenses/LICENSE +0 -0
@@ -4,12 +4,12 @@ Configuration utility functions.
|
|
4
4
|
Helper functions for working with payment configurations.
|
5
5
|
"""
|
6
6
|
|
7
|
-
from typing import Optional
|
7
|
+
from typing import Optional
|
8
8
|
import logging
|
9
9
|
|
10
10
|
from .module import PaymentsCfgModule
|
11
11
|
from .settings import PaymentsSettings
|
12
|
-
from .
|
12
|
+
from django_cfg.models.payments import PaymentProviderConfig
|
13
13
|
|
14
14
|
logger = logging.getLogger(__name__)
|
15
15
|
|
@@ -28,171 +28,25 @@ def get_provider_config(provider_name: str) -> Optional[PaymentProviderConfig]:
|
|
28
28
|
return config.providers.get(provider_name)
|
29
29
|
|
30
30
|
|
31
|
-
def get_nowpayments_config() -> Optional[NowPaymentsConfig]:
|
32
|
-
"""Get NowPayments configuration."""
|
33
|
-
provider_config = get_provider_config('nowpayments')
|
34
|
-
if isinstance(provider_config, NowPaymentsConfig):
|
35
|
-
return provider_config
|
36
|
-
return None
|
37
|
-
|
38
|
-
|
39
|
-
def get_stripe_config() -> Optional[StripeConfig]:
|
40
|
-
"""Get Stripe configuration."""
|
41
|
-
provider_config = get_provider_config('stripe')
|
42
|
-
if isinstance(provider_config, StripeConfig):
|
43
|
-
return provider_config
|
44
|
-
return None
|
45
|
-
|
46
|
-
|
47
|
-
def get_cryptapi_config() -> Optional[CryptAPIConfig]:
|
48
|
-
"""Get CryptAPI configuration."""
|
49
|
-
provider_config = get_provider_config('cryptapi')
|
50
|
-
if isinstance(provider_config, CryptAPIConfig):
|
51
|
-
return provider_config
|
52
|
-
return None
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
31
|
def is_payments_enabled() -> bool:
|
58
32
|
"""Check if payments module is enabled."""
|
59
33
|
try:
|
60
34
|
config = get_payments_config()
|
61
35
|
return config.enabled
|
62
36
|
except Exception as e:
|
63
|
-
logger.warning(f"
|
64
|
-
return False
|
65
|
-
|
66
|
-
|
67
|
-
def is_feature_enabled(feature_name: str) -> bool:
|
68
|
-
"""Check if specific payment feature is enabled."""
|
69
|
-
try:
|
70
|
-
config = get_payments_config()
|
71
|
-
feature_map = {
|
72
|
-
'crypto_payments': config.enable_crypto_payments,
|
73
|
-
'fiat_payments': config.enable_fiat_payments,
|
74
|
-
'subscriptions': config.enable_subscription_system,
|
75
|
-
'balance': config.enable_balance_system,
|
76
|
-
'api_keys': config.enable_api_key_system,
|
77
|
-
'webhooks': config.enable_webhook_processing,
|
78
|
-
}
|
79
|
-
return feature_map.get(feature_name, False)
|
80
|
-
except Exception as e:
|
81
|
-
logger.warning(f"Error checking feature {feature_name}: {e}")
|
37
|
+
logger.warning(f"Failed to check payments status: {e}")
|
82
38
|
return False
|
83
39
|
|
84
40
|
|
85
|
-
def get_enabled_providers() -> List[str]:
|
86
|
-
"""Get list of enabled payment providers."""
|
87
|
-
try:
|
88
|
-
config = get_payments_config()
|
89
|
-
return [name for name, provider_config in config.providers.items() if provider_config.enabled]
|
90
|
-
except Exception as e:
|
91
|
-
logger.warning(f"Error getting enabled providers: {e}")
|
92
|
-
return []
|
93
|
-
|
94
|
-
|
95
|
-
def get_provider_settings(provider_name: str) -> Dict[str, Any]:
|
96
|
-
"""Get provider settings as dictionary for service initialization."""
|
97
|
-
try:
|
98
|
-
provider_config = get_provider_config(provider_name)
|
99
|
-
if provider_config:
|
100
|
-
return provider_config.get_config_dict()
|
101
|
-
return {}
|
102
|
-
except Exception as e:
|
103
|
-
logger.error(f"Error getting settings for provider {provider_name}: {e}")
|
104
|
-
return {}
|
105
|
-
|
106
|
-
|
107
|
-
def validate_provider_config(provider_name: str) -> bool:
|
108
|
-
"""Validate provider configuration."""
|
109
|
-
try:
|
110
|
-
provider_config = get_provider_config(provider_name)
|
111
|
-
if not provider_config:
|
112
|
-
return False
|
113
|
-
|
114
|
-
# Basic validation - check if API key exists
|
115
|
-
config_dict = provider_config.get_config_dict()
|
116
|
-
return bool(config_dict.get('api_key'))
|
117
|
-
|
118
|
-
except Exception as e:
|
119
|
-
logger.error(f"Error validating provider {provider_name}: {e}")
|
120
|
-
return False
|
121
|
-
|
122
|
-
|
123
|
-
def get_rate_limit_settings() -> Dict[str, int]:
|
124
|
-
"""Get rate limiting settings."""
|
125
|
-
try:
|
126
|
-
config = get_payments_config()
|
127
|
-
return {
|
128
|
-
'hourly_limit': config.rate_limits.default_rate_limit_per_hour,
|
129
|
-
'daily_limit': config.rate_limits.default_rate_limit_per_day,
|
130
|
-
'burst_multiplier': config.rate_limits.burst_limit_multiplier,
|
131
|
-
'window_size': config.rate_limits.sliding_window_size,
|
132
|
-
}
|
133
|
-
except Exception as e:
|
134
|
-
logger.warning(f"Error getting rate limit settings: {e}")
|
135
|
-
return {
|
136
|
-
'hourly_limit': 1000,
|
137
|
-
'daily_limit': 10000,
|
138
|
-
'burst_multiplier': 2.0,
|
139
|
-
'window_size': 3600,
|
140
|
-
}
|
141
|
-
|
142
|
-
|
143
|
-
def get_cache_settings() -> Dict[str, int]:
|
144
|
-
"""Get cache timeout settings."""
|
145
|
-
try:
|
146
|
-
config = get_payments_config()
|
147
|
-
return {
|
148
|
-
'access_check': config.cache.cache_timeout_access_check,
|
149
|
-
'user_balance': config.cache.cache_timeout_user_balance,
|
150
|
-
'subscriptions': config.cache.cache_timeout_subscriptions,
|
151
|
-
'provider_status': config.cache.cache_timeout_provider_status,
|
152
|
-
'currency_rates': config.cache.cache_timeout_currency_rates,
|
153
|
-
}
|
154
|
-
except Exception as e:
|
155
|
-
logger.warning(f"Error getting cache settings: {e}")
|
156
|
-
return {
|
157
|
-
'access_check': 60,
|
158
|
-
'user_balance': 300,
|
159
|
-
'subscriptions': 600,
|
160
|
-
'provider_status': 1800,
|
161
|
-
'currency_rates': 3600,
|
162
|
-
}
|
163
|
-
|
164
|
-
|
165
|
-
def get_billing_settings() -> Dict[str, Any]:
|
166
|
-
"""Get billing settings."""
|
167
|
-
try:
|
168
|
-
config = get_payments_config()
|
169
|
-
return {
|
170
|
-
'auto_bill': config.billing.auto_bill_subscriptions,
|
171
|
-
'grace_period_hours': config.billing.billing_grace_period_hours,
|
172
|
-
'retry_failed': config.billing.retry_failed_payments,
|
173
|
-
'max_retries': config.billing.max_payment_retries,
|
174
|
-
'min_amount_usd': config.billing.min_payment_amount_usd,
|
175
|
-
'max_amount_usd': config.billing.max_payment_amount_usd,
|
176
|
-
}
|
177
|
-
except Exception as e:
|
178
|
-
logger.warning(f"Error getting billing settings: {e}")
|
179
|
-
return {
|
180
|
-
'auto_bill': True,
|
181
|
-
'grace_period_hours': 24,
|
182
|
-
'retry_failed': True,
|
183
|
-
'max_retries': 3,
|
184
|
-
'min_amount_usd': 1.0,
|
185
|
-
'max_amount_usd': 50000.0,
|
186
|
-
}
|
187
|
-
|
188
|
-
|
189
41
|
def reset_config_cache():
|
190
|
-
"""Reset configuration cache
|
42
|
+
"""Reset configuration cache."""
|
191
43
|
global _payments_config
|
192
44
|
_payments_config.reset_cache()
|
193
45
|
|
194
46
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
47
|
+
__all__ = [
|
48
|
+
'get_payments_config',
|
49
|
+
'get_provider_config',
|
50
|
+
'is_payments_enabled',
|
51
|
+
'reset_config_cache'
|
52
|
+
]
|
@@ -0,0 +1,178 @@
|
|
1
|
+
# Currency Management Commands
|
2
|
+
|
3
|
+
Management команды для работы с валютами в Universal Payments System.
|
4
|
+
|
5
|
+
## Команды
|
6
|
+
|
7
|
+
### 🪙 `populate_currencies` - Первоначальное заполнение
|
8
|
+
|
9
|
+
Заполняет пустую базу данных валютами из внешних API (CoinGecko, YFinance).
|
10
|
+
|
11
|
+
```bash
|
12
|
+
# Быстрое заполнение (50 криптовалют + 20 фиатных)
|
13
|
+
python manage.py populate_currencies --quick
|
14
|
+
|
15
|
+
# Стандартное заполнение (200 криптовалют + 30 фиатных)
|
16
|
+
python manage.py populate_currencies
|
17
|
+
|
18
|
+
# Только криптовалюты
|
19
|
+
python manage.py populate_currencies --crypto-only
|
20
|
+
|
21
|
+
# Только фиатные валюты
|
22
|
+
python manage.py populate_currencies --fiat-only
|
23
|
+
|
24
|
+
# Пропустить существующие валюты
|
25
|
+
python manage.py populate_currencies --skip-existing
|
26
|
+
```
|
27
|
+
|
28
|
+
### 🔄 `update_currencies` - Обновление курсов
|
29
|
+
|
30
|
+
Обновляет курсы валют с внешних API.
|
31
|
+
|
32
|
+
```bash
|
33
|
+
# Обновить устаревшие курсы (старше 6 часов)
|
34
|
+
python manage.py update_currencies
|
35
|
+
|
36
|
+
# Принудительно обновить все валюты
|
37
|
+
python manage.py update_currencies --force-update
|
38
|
+
|
39
|
+
# Сухой прогон (показать что будет обновлено)
|
40
|
+
python manage.py update_currencies --dry-run
|
41
|
+
|
42
|
+
# Кастомные лимиты
|
43
|
+
python manage.py update_currencies --max-crypto 100 --max-fiat 30
|
44
|
+
|
45
|
+
# Исключить стейблкоины
|
46
|
+
python manage.py update_currencies --exclude-stablecoins
|
47
|
+
|
48
|
+
# Подробный вывод
|
49
|
+
python manage.py update_currencies --verbose
|
50
|
+
```
|
51
|
+
|
52
|
+
### 📊 `currency_stats` - Статистика валют
|
53
|
+
|
54
|
+
Показывает статистику базы данных валют.
|
55
|
+
|
56
|
+
```bash
|
57
|
+
# Базовая статистика
|
58
|
+
python manage.py currency_stats
|
59
|
+
|
60
|
+
# Детальная статистика
|
61
|
+
python manage.py currency_stats --detailed
|
62
|
+
|
63
|
+
# Показать топ-10 валют
|
64
|
+
python manage.py currency_stats --top 10
|
65
|
+
|
66
|
+
# Проверить устаревшие курсы
|
67
|
+
python manage.py currency_stats --check-rates
|
68
|
+
|
69
|
+
# Экспортировать в CSV
|
70
|
+
python manage.py currency_stats --export-csv currencies.csv
|
71
|
+
```
|
72
|
+
|
73
|
+
## Автоматизация
|
74
|
+
|
75
|
+
### Cron для регулярного обновления
|
76
|
+
|
77
|
+
```bash
|
78
|
+
# Обновлять курсы каждые 6 часов
|
79
|
+
0 */6 * * * cd /path/to/project && poetry run python manage.py update_currencies
|
80
|
+
|
81
|
+
# Ежедневная проверка статистики
|
82
|
+
0 9 * * * cd /path/to/project && poetry run python manage.py currency_stats --check-rates
|
83
|
+
```
|
84
|
+
|
85
|
+
### Docker
|
86
|
+
|
87
|
+
```bash
|
88
|
+
# В Docker контейнере
|
89
|
+
docker exec -it container_name poetry run python manage.py populate_currencies --quick
|
90
|
+
docker exec -it container_name poetry run python manage.py update_currencies
|
91
|
+
```
|
92
|
+
|
93
|
+
## Примеры использования
|
94
|
+
|
95
|
+
### Первоначальная настройка
|
96
|
+
|
97
|
+
```bash
|
98
|
+
# 1. Заполнить базу данных валютами
|
99
|
+
python manage.py populate_currencies --quick
|
100
|
+
|
101
|
+
# 2. Проверить результат
|
102
|
+
python manage.py currency_stats
|
103
|
+
```
|
104
|
+
|
105
|
+
### Регулярное обслуживание
|
106
|
+
|
107
|
+
```bash
|
108
|
+
# 1. Обновить курсы
|
109
|
+
python manage.py update_currencies --verbose
|
110
|
+
|
111
|
+
# 2. Проверить устаревшие курсы
|
112
|
+
python manage.py currency_stats --check-rates
|
113
|
+
|
114
|
+
# 3. При необходимости - принудительное обновление
|
115
|
+
python manage.py update_currencies --force-update
|
116
|
+
```
|
117
|
+
|
118
|
+
### Production обслуживание
|
119
|
+
|
120
|
+
```bash
|
121
|
+
# Обновление с минимальными API запросами
|
122
|
+
python manage.py update_currencies --max-crypto 50 --max-fiat 20
|
123
|
+
|
124
|
+
# Мониторинг состояния
|
125
|
+
python manage.py currency_stats --detailed --export-csv daily_report.csv
|
126
|
+
```
|
127
|
+
|
128
|
+
## Интеграция с django_currency
|
129
|
+
|
130
|
+
Команды используют модуль `django_currency.database.database_loader` для:
|
131
|
+
|
132
|
+
- ✅ Получения списка валют с CoinGecko
|
133
|
+
- ✅ Загрузки курсов фиатных валют с YFinance
|
134
|
+
- ✅ Rate limiting для защиты от API throttling
|
135
|
+
- ✅ Кэширования для оптимизации производительности
|
136
|
+
- ✅ Pydantic валидации для типобезопасности
|
137
|
+
|
138
|
+
## Конфигурация
|
139
|
+
|
140
|
+
Настройки в `DatabaseLoaderConfig`:
|
141
|
+
|
142
|
+
```python
|
143
|
+
config = DatabaseLoaderConfig(
|
144
|
+
max_cryptocurrencies=500, # Максимум криптовалют
|
145
|
+
max_fiat_currencies=50, # Максимум фиатных валют
|
146
|
+
min_market_cap_usd=1_000_000, # Минимальная капитализация
|
147
|
+
coingecko_delay=1.5, # Задержка между запросами
|
148
|
+
yfinance_delay=0.5, # Задержка для YFinance
|
149
|
+
exclude_stablecoins=False, # Исключить стейблкоины
|
150
|
+
cache_ttl_hours=24 # TTL кэша в часах
|
151
|
+
)
|
152
|
+
```
|
153
|
+
|
154
|
+
## Мониторинг
|
155
|
+
|
156
|
+
### Логи
|
157
|
+
|
158
|
+
Команды логируют в `django_cfg.apps.payments.management.commands`:
|
159
|
+
|
160
|
+
```python
|
161
|
+
import logging
|
162
|
+
logger = logging.getLogger('django_cfg.apps.payments.management.commands')
|
163
|
+
```
|
164
|
+
|
165
|
+
### Метрики
|
166
|
+
|
167
|
+
- Количество созданных/обновленных валют
|
168
|
+
- Время выполнения API запросов
|
169
|
+
- Ошибки валидации и API
|
170
|
+
- Статистика курсов валют
|
171
|
+
|
172
|
+
## Безопасность
|
173
|
+
|
174
|
+
- ✅ Rate limiting для API запросов
|
175
|
+
- ✅ Atomic транзакции для консистентности
|
176
|
+
- ✅ Graceful handling ошибок API
|
177
|
+
- ✅ Валидация данных с Pydantic
|
178
|
+
- ✅ Rollback при критических ошибках
|