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.
Files changed (138) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/__init__.py +3 -2
  3. django_cfg/apps/payments/admin/balance_admin.py +18 -18
  4. django_cfg/apps/payments/admin/currencies_admin.py +319 -131
  5. django_cfg/apps/payments/admin/payments_admin.py +15 -4
  6. django_cfg/apps/payments/config/module.py +2 -2
  7. django_cfg/apps/payments/config/utils.py +2 -2
  8. django_cfg/apps/payments/decorators.py +2 -2
  9. django_cfg/apps/payments/management/commands/README.md +95 -127
  10. django_cfg/apps/payments/management/commands/currency_stats.py +5 -24
  11. django_cfg/apps/payments/management/commands/manage_currencies.py +229 -0
  12. django_cfg/apps/payments/management/commands/manage_providers.py +235 -0
  13. django_cfg/apps/payments/managers/__init__.py +3 -2
  14. django_cfg/apps/payments/managers/balance_manager.py +2 -2
  15. django_cfg/apps/payments/managers/currency_manager.py +272 -49
  16. django_cfg/apps/payments/managers/payment_manager.py +161 -13
  17. django_cfg/apps/payments/middleware/api_access.py +2 -2
  18. django_cfg/apps/payments/middleware/rate_limiting.py +8 -18
  19. django_cfg/apps/payments/middleware/usage_tracking.py +20 -17
  20. django_cfg/apps/payments/migrations/0002_network_providercurrency_and_more.py +241 -0
  21. django_cfg/apps/payments/migrations/0003_add_usd_rate_cache.py +30 -0
  22. django_cfg/apps/payments/models/__init__.py +3 -2
  23. django_cfg/apps/payments/models/currencies.py +187 -71
  24. django_cfg/apps/payments/models/payments.py +3 -2
  25. django_cfg/apps/payments/serializers/__init__.py +3 -2
  26. django_cfg/apps/payments/serializers/currencies.py +20 -12
  27. django_cfg/apps/payments/services/cache/simple_cache.py +2 -2
  28. django_cfg/apps/payments/services/core/balance_service.py +2 -2
  29. django_cfg/apps/payments/services/core/fallback_service.py +2 -2
  30. django_cfg/apps/payments/services/core/payment_service.py +3 -6
  31. django_cfg/apps/payments/services/core/subscription_service.py +4 -7
  32. django_cfg/apps/payments/services/internal_types.py +171 -7
  33. django_cfg/apps/payments/services/monitoring/api_schemas.py +58 -204
  34. django_cfg/apps/payments/services/monitoring/provider_health.py +2 -2
  35. django_cfg/apps/payments/services/providers/base.py +144 -43
  36. django_cfg/apps/payments/services/providers/cryptapi/__init__.py +4 -0
  37. django_cfg/apps/payments/services/providers/cryptapi/config.py +8 -0
  38. django_cfg/apps/payments/services/providers/cryptapi/models.py +192 -0
  39. django_cfg/apps/payments/services/providers/cryptapi/provider.py +439 -0
  40. django_cfg/apps/payments/services/providers/cryptomus/__init__.py +4 -0
  41. django_cfg/apps/payments/services/providers/cryptomus/models.py +176 -0
  42. django_cfg/apps/payments/services/providers/cryptomus/provider.py +429 -0
  43. django_cfg/apps/payments/services/providers/cryptomus/provider_v2.py +564 -0
  44. django_cfg/apps/payments/services/providers/models/__init__.py +34 -0
  45. django_cfg/apps/payments/services/providers/models/currencies.py +190 -0
  46. django_cfg/apps/payments/services/providers/nowpayments/__init__.py +4 -0
  47. django_cfg/apps/payments/services/providers/nowpayments/models.py +196 -0
  48. django_cfg/apps/payments/services/providers/nowpayments/provider.py +380 -0
  49. django_cfg/apps/payments/services/providers/registry.py +294 -11
  50. django_cfg/apps/payments/services/providers/stripe/__init__.py +4 -0
  51. django_cfg/apps/payments/services/providers/stripe/models.py +184 -0
  52. django_cfg/apps/payments/services/providers/stripe/provider.py +109 -0
  53. django_cfg/apps/payments/services/security/error_handler.py +6 -8
  54. django_cfg/apps/payments/services/security/payment_notifications.py +2 -2
  55. django_cfg/apps/payments/services/security/webhook_validator.py +3 -4
  56. django_cfg/apps/payments/signals/api_key_signals.py +2 -2
  57. django_cfg/apps/payments/signals/payment_signals.py +11 -5
  58. django_cfg/apps/payments/signals/subscription_signals.py +2 -2
  59. django_cfg/apps/payments/static/payments/css/payments.css +340 -0
  60. django_cfg/apps/payments/static/payments/js/notifications.js +202 -0
  61. django_cfg/apps/payments/static/payments/js/payment-utils.js +318 -0
  62. django_cfg/apps/payments/static/payments/js/theme.js +86 -0
  63. django_cfg/apps/payments/tasks/webhook_processing.py +2 -2
  64. django_cfg/apps/payments/templates/admin/payments/currency/change_list.html +50 -0
  65. django_cfg/apps/payments/templates/payments/base.html +182 -0
  66. django_cfg/apps/payments/templates/payments/components/payment_card.html +201 -0
  67. django_cfg/apps/payments/templates/payments/components/payment_qr_code.html +109 -0
  68. django_cfg/apps/payments/templates/payments/components/progress_bar.html +43 -0
  69. django_cfg/apps/payments/templates/payments/components/provider_stats.html +40 -0
  70. django_cfg/apps/payments/templates/payments/components/status_badge.html +34 -0
  71. django_cfg/apps/payments/templates/payments/components/status_overview.html +148 -0
  72. django_cfg/apps/payments/templates/payments/dashboard.html +258 -0
  73. django_cfg/apps/payments/templates/payments/dashboard_simple_test.html +35 -0
  74. django_cfg/apps/payments/templates/payments/payment_create.html +579 -0
  75. django_cfg/apps/payments/templates/payments/payment_detail.html +373 -0
  76. django_cfg/apps/payments/templates/payments/payment_list.html +354 -0
  77. django_cfg/apps/payments/templates/payments/stats.html +261 -0
  78. django_cfg/apps/payments/templates/payments/test.html +213 -0
  79. django_cfg/apps/payments/templatetags/__init__.py +1 -0
  80. django_cfg/apps/payments/templatetags/payments_tags.py +315 -0
  81. django_cfg/apps/payments/urls.py +3 -1
  82. django_cfg/apps/payments/urls_admin.py +58 -0
  83. django_cfg/apps/payments/utils/__init__.py +1 -3
  84. django_cfg/apps/payments/utils/billing_utils.py +2 -2
  85. django_cfg/apps/payments/utils/config_utils.py +2 -8
  86. django_cfg/apps/payments/utils/validation_utils.py +2 -2
  87. django_cfg/apps/payments/views/__init__.py +3 -2
  88. django_cfg/apps/payments/views/currency_views.py +31 -20
  89. django_cfg/apps/payments/views/payment_views.py +2 -2
  90. django_cfg/apps/payments/views/templates/__init__.py +25 -0
  91. django_cfg/apps/payments/views/templates/ajax.py +451 -0
  92. django_cfg/apps/payments/views/templates/base.py +212 -0
  93. django_cfg/apps/payments/views/templates/dashboard.py +60 -0
  94. django_cfg/apps/payments/views/templates/payment_detail.py +102 -0
  95. django_cfg/apps/payments/views/templates/payment_management.py +158 -0
  96. django_cfg/apps/payments/views/templates/qr_code.py +174 -0
  97. django_cfg/apps/payments/views/templates/stats.py +244 -0
  98. django_cfg/apps/payments/views/templates/utils.py +181 -0
  99. django_cfg/apps/payments/views/webhook_views.py +2 -2
  100. django_cfg/apps/payments/viewsets.py +3 -2
  101. django_cfg/apps/tasks/urls.py +0 -2
  102. django_cfg/apps/tasks/urls_admin.py +14 -0
  103. django_cfg/apps/urls.py +6 -3
  104. django_cfg/core/config.py +35 -0
  105. django_cfg/models/payments.py +2 -8
  106. django_cfg/modules/django_currency/__init__.py +16 -11
  107. django_cfg/modules/django_currency/clients/__init__.py +4 -4
  108. django_cfg/modules/django_currency/clients/coinpaprika_client.py +289 -0
  109. django_cfg/modules/django_currency/clients/yahoo_client.py +157 -0
  110. django_cfg/modules/django_currency/core/__init__.py +1 -7
  111. django_cfg/modules/django_currency/core/converter.py +18 -23
  112. django_cfg/modules/django_currency/core/models.py +122 -11
  113. django_cfg/modules/django_currency/database/__init__.py +4 -4
  114. django_cfg/modules/django_currency/database/database_loader.py +190 -309
  115. django_cfg/modules/django_unfold/dashboard.py +7 -2
  116. django_cfg/registry/core.py +1 -0
  117. django_cfg/template_archive/.gitignore +1 -0
  118. django_cfg/template_archive/django_sample.zip +0 -0
  119. django_cfg/templates/admin/components/action_grid.html +9 -9
  120. django_cfg/templates/admin/components/metric_card.html +5 -5
  121. django_cfg/templates/admin/components/status_badge.html +2 -2
  122. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +152 -24
  123. django_cfg/templates/admin/snippets/components/quick_actions.html +3 -3
  124. django_cfg/templates/admin/snippets/components/system_health.html +1 -1
  125. django_cfg/templates/admin/snippets/tabs/overview_tab.html +49 -52
  126. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/METADATA +13 -18
  127. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/RECORD +130 -83
  128. django_cfg/apps/payments/management/commands/populate_currencies.py +0 -246
  129. django_cfg/apps/payments/management/commands/update_currencies.py +0 -336
  130. django_cfg/apps/payments/services/providers/cryptapi.py +0 -273
  131. django_cfg/apps/payments/services/providers/cryptomus.py +0 -310
  132. django_cfg/apps/payments/services/providers/nowpayments.py +0 -293
  133. django_cfg/apps/payments/services/validators/__init__.py +0 -8
  134. django_cfg/modules/django_currency/clients/coingecko_client.py +0 -257
  135. django_cfg/modules/django_currency/clients/yfinance_client.py +0 -246
  136. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/WHEEL +0 -0
  137. {django_cfg-1.2.27.dist-info → django_cfg-1.2.31.dist-info}/entry_points.txt +0 -0
  138. {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, SupportedCurrencies, YFinanceCurrencies, CoinGeckoCurrencies
8
+ from .models import Rate, ConversionRequest, ConversionResult
9
9
  from .exceptions import ConversionError, CurrencyNotFoundError
10
- from ..clients import YFinanceClient, CoinGeckoClient
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.yfinance = YFinanceClient()
27
- self.coingecko = CoinGeckoClient()
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 ["yfinance", "coingecko"]:
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 YFinance first (good for fiat and major crypto)
104
- if self.yfinance.supports_pair(base, quote):
103
+ # Try CoinPaprika first (excellent for crypto, no rate limits)
104
+ if self.coinpaprika.supports_pair(base, quote):
105
105
  try:
106
- rate = self.yfinance.fetch_rate(base, quote)
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"YFinance failed for {base}/{quote}: {e}")
110
+ logger.warning(f"CoinPaprika failed for {base}/{quote}: {e}")
111
111
 
112
- # Try CoinGecko (good for crypto)
113
- if self.coingecko.supports_pair(base, quote):
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.coingecko.fetch_rate(base, quote)
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"CoinGecko failed for {base}/{quote}: {e}")
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) -> SupportedCurrencies:
159
+ def get_supported_currencies(self) -> dict:
160
160
  """Get list of supported currencies by provider."""
161
- return SupportedCurrencies(
162
- yfinance=YFinanceCurrencies(
163
- fiat=list(self.yfinance.get_fiat_currencies())
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
- Simple data models for currency conversion.
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 (yfinance, coingecko)")
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 YFinanceCurrencies(BaseModel):
38
- """YFinance supported currencies model."""
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 CoinGeckoCurrencies(BaseModel):
44
- """CoinGecko supported currencies model."""
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
- yfinance: YFinanceCurrencies = Field(description="YFinance currencies")
54
- coingecko: CoinGeckoCurrencies = Field(description="CoinGecko currencies")
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
- CoinGeckoCoinInfo,
9
- YFinanceCurrencyInfo,
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
- 'CoinGeckoCoinInfo',
20
- 'YFinanceCurrencyInfo',
19
+ 'CoinPaprikaCoinInfo',
20
+ 'YahooFinanceCurrencyInfo',
21
21
  'CurrencyRateInfo',
22
22
  'RateLimiter',
23
23
  'create_database_loader',