django-cfg 1.2.27__py3-none-any.whl → 1.2.31__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/payments/admin/__init__.py +3 -2
- django_cfg/apps/payments/admin/balance_admin.py +18 -18
- django_cfg/apps/payments/admin/currencies_admin.py +319 -131
- django_cfg/apps/payments/admin/payments_admin.py +15 -4
- django_cfg/apps/payments/config/module.py +2 -2
- django_cfg/apps/payments/config/utils.py +2 -2
- django_cfg/apps/payments/decorators.py +2 -2
- django_cfg/apps/payments/management/commands/README.md +95 -127
- django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
- django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
- django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
- django_cfg/apps/payments/managers/__init__.py +3 -2
- django_cfg/apps/payments/managers/balance_manager.py +2 -2
- django_cfg/apps/payments/managers/currency_manager.py +272 -49
- django_cfg/apps/payments/managers/payment_manager.py +161 -13
- django_cfg/apps/payments/middleware/api_access.py +2 -2
- django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
- django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
- django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
- django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
- django_cfg/apps/payments/models/__init__.py +3 -2
- django_cfg/apps/payments/models/currencies.py +187 -71
- django_cfg/apps/payments/models/payments.py +3 -2
- django_cfg/apps/payments/serializers/__init__.py +3 -2
- django_cfg/apps/payments/serializers/currencies.py +20 -12
- django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
- django_cfg/apps/payments/services/core/balance_service.py +2 -2
- django_cfg/apps/payments/services/core/fallback_service.py +2 -2
- django_cfg/apps/payments/services/core/payment_service.py +3 -6
- django_cfg/apps/payments/services/core/subscription_service.py +4 -7
- django_cfg/apps/payments/services/internal_types.py +171 -7
- django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
- django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
- django_cfg/apps/payments/services/providers/base.py +144 -43
- django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
- django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
- django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
- django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
- django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
- django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
- django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
- django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
- django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
- django_cfg/apps/payments/services/providers/registry.py +294 -11
- django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
- django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
- django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
- django_cfg/apps/payments/services/security/error_handler.py +6 -8
- django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
- django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
- django_cfg/apps/payments/signals/api_key_signals.py +2 -2
- django_cfg/apps/payments/signals/payment_signals.py +11 -5
- django_cfg/apps/payments/signals/subscription_signals.py +2 -2
- django_cfg/apps/payments/static/payments/css/payments.css +340 -0
- django_cfg/apps/payments/static/payments/js/notifications.js +202 -0
- django_cfg/apps/payments/static/payments/js/payment-utils.js +318 -0
- django_cfg/apps/payments/static/payments/js/theme.js +86 -0
- django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
- django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
- django_cfg/apps/payments/templates/payments/base.html +182 -0
- django_cfg/apps/payments/templates/payments/components/payment_card.html +201 -0
- django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +109 -0
- django_cfg/apps/payments/templates/payments/components/progress_bar.html +43 -0
- django_cfg/apps/payments/templates/payments/components/provider_stats.html +40 -0
- django_cfg/apps/payments/templates/payments/components/status_badge.html +34 -0
- django_cfg/apps/payments/templates/payments/components/status_overview.html +148 -0
- django_cfg/apps/payments/templates/payments/dashboard.html +258 -0
- django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
- django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
- django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
- django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
- django_cfg/apps/payments/templates/payments/stats.html +261 -0
- django_cfg/apps/payments/templates/payments/test.html +213 -0
- django_cfg/apps/payments/templatetags/__init__.py +1 -0
- django_cfg/apps/payments/templatetags/payments_tags.py +315 -0
- django_cfg/apps/payments/urls.py +3 -1
- django_cfg/apps/payments/urls_admin.py +58 -0
- django_cfg/apps/payments/utils/__init__.py +1 -3
- django_cfg/apps/payments/utils/billing_utils.py +2 -2
- django_cfg/apps/payments/utils/config_utils.py +2 -8
- django_cfg/apps/payments/utils/validation_utils.py +2 -2
- django_cfg/apps/payments/views/__init__.py +3 -2
- django_cfg/apps/payments/views/currency_views.py +31 -20
- django_cfg/apps/payments/views/payment_views.py +2 -2
- django_cfg/apps/payments/views/templates/__init__.py +25 -0
- django_cfg/apps/payments/views/templates/ajax.py +451 -0
- django_cfg/apps/payments/views/templates/base.py +212 -0
- django_cfg/apps/payments/views/templates/dashboard.py +60 -0
- django_cfg/apps/payments/views/templates/payment_detail.py +102 -0
- django_cfg/apps/payments/views/templates/payment_management.py +158 -0
- django_cfg/apps/payments/views/templates/qr_code.py +174 -0
- django_cfg/apps/payments/views/templates/stats.py +244 -0
- django_cfg/apps/payments/views/templates/utils.py +181 -0
- django_cfg/apps/payments/views/webhook_views.py +2 -2
- django_cfg/apps/payments/viewsets.py +3 -2
- django_cfg/apps/tasks/urls.py +0 -2
- django_cfg/apps/tasks/urls_admin.py +14 -0
- django_cfg/apps/urls.py +6 -3
- django_cfg/core/config.py +35 -0
- django_cfg/models/payments.py +2 -8
- django_cfg/modules/django_currency/__init__.py +16 -11
- django_cfg/modules/django_currency/clients/__init__.py +4 -4
- django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
- django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
- django_cfg/modules/django_currency/core/__init__.py +1 -7
- django_cfg/modules/django_currency/core/converter.py +18 -23
- django_cfg/modules/django_currency/core/models.py +122 -11
- django_cfg/modules/django_currency/database/__init__.py +4 -4
- django_cfg/modules/django_currency/database/database_loader.py +190 -309
- django_cfg/modules/django_unfold/dashboard.py +7 -2
- django_cfg/registry/core.py +1 -0
- django_cfg/template_archive/.gitignore +1 -0
- django_cfg/template_archive/django_sample.zip +0 -0
- django_cfg/templates/admin/components/action_grid.html +9 -9
- django_cfg/templates/admin/components/metric_card.html +5 -5
- django_cfg/templates/admin/components/status_badge.html +2 -2
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
- django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
- django_cfg/templates/admin/snippets/components/system_health.html +1 -1
- django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/METADATA +13 -18
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/RECORD +130 -83
- django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
- django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
- django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
- django_cfg/apps/payments/services/providers/cryptomus.py +0 -310
- django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
- django_cfg/apps/payments/services/validators/__init__.py +0 -8
- django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
- django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/licenses/LICENSE +0 -0
@@ -5,9 +5,9 @@ Main currency converter with intelligent routing.
|
|
5
5
|
import logging
|
6
6
|
from typing import Optional
|
7
7
|
|
8
|
-
from .models import Rate, ConversionRequest, ConversionResult
|
8
|
+
from .models import Rate, ConversionRequest, ConversionResult
|
9
9
|
from .exceptions import ConversionError, CurrencyNotFoundError
|
10
|
-
from ..clients import
|
10
|
+
from ..clients import YahooFinanceClient, CoinPaprikaClient
|
11
11
|
from ..utils.cache import CacheManager
|
12
12
|
|
13
13
|
logger = logging.getLogger(__name__)
|
@@ -23,8 +23,8 @@ class CurrencyConverter:
|
|
23
23
|
Args:
|
24
24
|
cache_ttl: Cache TTL in seconds
|
25
25
|
"""
|
26
|
-
self.
|
27
|
-
self.
|
26
|
+
self.yahoo = YahooFinanceClient(cache_ttl=cache_ttl)
|
27
|
+
self.coinpaprika = CoinPaprikaClient(cache_ttl=cache_ttl)
|
28
28
|
self.cache = CacheManager(ttl=cache_ttl)
|
29
29
|
|
30
30
|
def convert(self, amount: float, from_currency: str, to_currency: str) -> ConversionResult:
|
@@ -95,28 +95,28 @@ class CurrencyConverter:
|
|
95
95
|
CurrencyNotFoundError: If no provider supports the pair
|
96
96
|
"""
|
97
97
|
# Try cache first
|
98
|
-
for source in ["
|
98
|
+
for source in ["yahoo", "coinpaprika"]:
|
99
99
|
cached_rate = self.cache.get_rate(base, quote, source)
|
100
100
|
if cached_rate:
|
101
101
|
return cached_rate
|
102
102
|
|
103
|
-
# Try
|
104
|
-
if self.
|
103
|
+
# Try CoinPaprika first (excellent for crypto, no rate limits)
|
104
|
+
if self.coinpaprika.supports_pair(base, quote):
|
105
105
|
try:
|
106
|
-
rate = self.
|
106
|
+
rate = self.coinpaprika.fetch_rate(base, quote)
|
107
107
|
self.cache.set_rate(rate)
|
108
108
|
return rate
|
109
109
|
except Exception as e:
|
110
|
-
logger.warning(f"
|
110
|
+
logger.warning(f"CoinPaprika failed for {base}/{quote}: {e}")
|
111
111
|
|
112
|
-
# Try
|
113
|
-
if self.
|
112
|
+
# Try Yahoo Finance next (good for fiat and major forex pairs)
|
113
|
+
if self.yahoo.supports_pair(base, quote):
|
114
114
|
try:
|
115
|
-
rate = self.
|
115
|
+
rate = self.yahoo.fetch_rate(base, quote)
|
116
116
|
self.cache.set_rate(rate)
|
117
117
|
return rate
|
118
118
|
except Exception as e:
|
119
|
-
logger.warning(f"
|
119
|
+
logger.warning(f"Yahoo Finance failed for {base}/{quote}: {e}")
|
120
120
|
|
121
121
|
# Try indirect conversion via USD
|
122
122
|
if base != "USD" and quote != "USD":
|
@@ -156,14 +156,9 @@ class CurrencyConverter:
|
|
156
156
|
rate=combined_rate
|
157
157
|
)
|
158
158
|
|
159
|
-
def get_supported_currencies(self) ->
|
159
|
+
def get_supported_currencies(self) -> dict:
|
160
160
|
"""Get list of supported currencies by provider."""
|
161
|
-
return
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
coingecko=CoinGeckoCurrencies(
|
166
|
-
crypto=list(self.coingecko.get_crypto_ids().keys()),
|
167
|
-
vs_currencies=list(self.coingecko.get_vs_currencies())
|
168
|
-
)
|
169
|
-
)
|
161
|
+
return {
|
162
|
+
"yahoo": self.yahoo.get_all_supported_currencies(),
|
163
|
+
"coinpaprika": self.coinpaprika.get_all_supported_currencies()
|
164
|
+
}
|
@@ -1,16 +1,16 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Data models for currency conversion and API responses.
|
3
3
|
"""
|
4
4
|
|
5
5
|
from datetime import datetime
|
6
|
-
from typing import Optional, List, Set
|
7
|
-
from pydantic import BaseModel, Field
|
6
|
+
from typing import Optional, List, Set, Dict, Any
|
7
|
+
from pydantic import BaseModel, Field, RootModel
|
8
8
|
|
9
9
|
|
10
10
|
class Rate(BaseModel):
|
11
11
|
"""Currency exchange rate model."""
|
12
12
|
|
13
|
-
source: str = Field(description="Data source (
|
13
|
+
source: str = Field(description="Data source (yahoo, coinpaprika)")
|
14
14
|
base_currency: str = Field(description="Base currency code")
|
15
15
|
quote_currency: str = Field(description="Quote currency code")
|
16
16
|
rate: float = Field(description="Exchange rate")
|
@@ -34,21 +34,132 @@ class ConversionResult(BaseModel):
|
|
34
34
|
path: Optional[str] = Field(default=None, description="Conversion path if indirect")
|
35
35
|
|
36
36
|
|
37
|
-
class
|
38
|
-
"""
|
37
|
+
class YahooFinanceCurrencies(BaseModel):
|
38
|
+
"""Yahoo Finance supported currencies model."""
|
39
39
|
|
40
40
|
fiat: List[str] = Field(description="Supported fiat currencies")
|
41
41
|
|
42
42
|
|
43
|
-
class
|
44
|
-
"""
|
43
|
+
class CoinPaprikaCurrencies(BaseModel):
|
44
|
+
"""CoinPaprika supported currencies model."""
|
45
45
|
|
46
46
|
crypto: List[str] = Field(description="Supported cryptocurrencies")
|
47
|
-
vs_currencies: List[str] = Field(description="Supported quote currencies")
|
48
47
|
|
49
48
|
|
50
49
|
class SupportedCurrencies(BaseModel):
|
51
50
|
"""All supported currencies model."""
|
52
51
|
|
53
|
-
|
54
|
-
|
52
|
+
yahoo: YahooFinanceCurrencies = Field(description="Yahoo Finance currencies")
|
53
|
+
coinpaprika: CoinPaprikaCurrencies = Field(description="CoinPaprika currencies")
|
54
|
+
|
55
|
+
|
56
|
+
# ============================================================================
|
57
|
+
# API RESPONSE MODELS
|
58
|
+
# ============================================================================
|
59
|
+
|
60
|
+
class YahooFinanceTradingPeriod(BaseModel):
|
61
|
+
"""Yahoo Finance trading period."""
|
62
|
+
start: int
|
63
|
+
end: int
|
64
|
+
timezone: str
|
65
|
+
gmtoffset: int
|
66
|
+
|
67
|
+
|
68
|
+
class YahooFinanceCurrentTradingPeriod(BaseModel):
|
69
|
+
"""Yahoo Finance current trading period."""
|
70
|
+
pre: YahooFinanceTradingPeriod
|
71
|
+
regular: YahooFinanceTradingPeriod
|
72
|
+
post: YahooFinanceTradingPeriod
|
73
|
+
|
74
|
+
|
75
|
+
class YahooFinanceMeta(BaseModel):
|
76
|
+
"""Yahoo Finance chart meta data."""
|
77
|
+
currency: str
|
78
|
+
symbol: str
|
79
|
+
exchangeName: str
|
80
|
+
fullExchangeName: str
|
81
|
+
instrumentType: str
|
82
|
+
firstTradeDate: int
|
83
|
+
regularMarketTime: int
|
84
|
+
hasPrePostMarketData: bool
|
85
|
+
gmtoffset: int
|
86
|
+
timezone: str
|
87
|
+
exchangeTimezoneName: str
|
88
|
+
regularMarketPrice: float
|
89
|
+
fiftyTwoWeekHigh: Optional[float] = None
|
90
|
+
fiftyTwoWeekLow: Optional[float] = None
|
91
|
+
regularMarketDayHigh: Optional[float] = None
|
92
|
+
regularMarketDayLow: Optional[float] = None
|
93
|
+
regularMarketVolume: Optional[int] = None
|
94
|
+
longName: Optional[str] = None
|
95
|
+
shortName: Optional[str] = None
|
96
|
+
chartPreviousClose: Optional[float] = None
|
97
|
+
previousClose: Optional[float] = None
|
98
|
+
scale: Optional[int] = None
|
99
|
+
priceHint: Optional[int] = None
|
100
|
+
currentTradingPeriod: Optional[YahooFinanceCurrentTradingPeriod] = None
|
101
|
+
tradingPeriods: Optional[List[List[YahooFinanceTradingPeriod]]] = None
|
102
|
+
dataGranularity: Optional[str] = None
|
103
|
+
range: Optional[str] = None
|
104
|
+
validRanges: Optional[List[str]] = None
|
105
|
+
|
106
|
+
|
107
|
+
class YahooFinanceResult(BaseModel):
|
108
|
+
"""Yahoo Finance chart result."""
|
109
|
+
meta: YahooFinanceMeta
|
110
|
+
|
111
|
+
|
112
|
+
class YahooFinanceChart(BaseModel):
|
113
|
+
"""Yahoo Finance chart response."""
|
114
|
+
result: List[YahooFinanceResult]
|
115
|
+
error: Optional[str] = None
|
116
|
+
|
117
|
+
|
118
|
+
class YahooFinanceResponse(BaseModel):
|
119
|
+
"""Complete Yahoo Finance API response."""
|
120
|
+
chart: YahooFinanceChart
|
121
|
+
|
122
|
+
|
123
|
+
class CoinPaprikaQuoteUSD(BaseModel):
|
124
|
+
"""CoinPaprika USD quote data."""
|
125
|
+
price: float
|
126
|
+
volume_24h: Optional[float] = None
|
127
|
+
volume_24h_change_24h: Optional[float] = None
|
128
|
+
market_cap: Optional[float] = None
|
129
|
+
market_cap_change_24h: Optional[float] = None
|
130
|
+
percent_change_15m: Optional[float] = None
|
131
|
+
percent_change_30m: Optional[float] = None
|
132
|
+
percent_change_1h: Optional[float] = None
|
133
|
+
percent_change_6h: Optional[float] = None
|
134
|
+
percent_change_12h: Optional[float] = None
|
135
|
+
percent_change_24h: Optional[float] = None
|
136
|
+
percent_change_7d: Optional[float] = None
|
137
|
+
percent_change_30d: Optional[float] = None
|
138
|
+
percent_change_1y: Optional[float] = None
|
139
|
+
ath_price: Optional[float] = None
|
140
|
+
ath_date: Optional[str] = None
|
141
|
+
percent_from_price_ath: Optional[float] = None
|
142
|
+
|
143
|
+
|
144
|
+
class CoinPaprikaQuotes(BaseModel):
|
145
|
+
"""CoinPaprika quotes container."""
|
146
|
+
USD: CoinPaprikaQuoteUSD
|
147
|
+
|
148
|
+
|
149
|
+
class CoinPaprikaTicker(BaseModel):
|
150
|
+
"""CoinPaprika ticker data."""
|
151
|
+
id: str
|
152
|
+
name: str
|
153
|
+
symbol: str
|
154
|
+
rank: int
|
155
|
+
total_supply: Optional[float] = None
|
156
|
+
max_supply: Optional[float] = None
|
157
|
+
beta_value: Optional[float] = None
|
158
|
+
first_data_at: Optional[str] = None
|
159
|
+
last_updated: str
|
160
|
+
quotes: CoinPaprikaQuotes
|
161
|
+
|
162
|
+
|
163
|
+
class CoinPaprikaTickersResponse(RootModel):
|
164
|
+
"""CoinPaprika tickers response (list of tickers)."""
|
165
|
+
root: List[CoinPaprikaTicker]
|
@@ -5,8 +5,8 @@ Database utilities for currency management.
|
|
5
5
|
from .database_loader import (
|
6
6
|
CurrencyDatabaseLoader,
|
7
7
|
DatabaseLoaderConfig,
|
8
|
-
|
9
|
-
|
8
|
+
CoinPaprikaCoinInfo,
|
9
|
+
YahooFinanceCurrencyInfo,
|
10
10
|
CurrencyRateInfo,
|
11
11
|
RateLimiter,
|
12
12
|
create_database_loader,
|
@@ -16,8 +16,8 @@ from .database_loader import (
|
|
16
16
|
__all__ = [
|
17
17
|
'CurrencyDatabaseLoader',
|
18
18
|
'DatabaseLoaderConfig',
|
19
|
-
'
|
20
|
-
'
|
19
|
+
'CoinPaprikaCoinInfo',
|
20
|
+
'YahooFinanceCurrencyInfo',
|
21
21
|
'CurrencyRateInfo',
|
22
22
|
'RateLimiter',
|
23
23
|
'create_database_loader',
|