django-cfg 1.2.22__py3-none-any.whl → 1.2.25__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 (125) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/knowbase/tasks/archive_tasks.py +6 -6
  3. django_cfg/apps/knowbase/tasks/document_processing.py +3 -3
  4. django_cfg/apps/knowbase/tasks/external_data_tasks.py +2 -2
  5. django_cfg/apps/knowbase/tasks/maintenance.py +3 -3
  6. django_cfg/apps/payments/admin/__init__.py +23 -0
  7. django_cfg/apps/payments/admin/api_keys_admin.py +347 -0
  8. django_cfg/apps/payments/admin/balance_admin.py +434 -0
  9. django_cfg/apps/payments/admin/currencies_admin.py +186 -0
  10. django_cfg/apps/payments/admin/filters.py +259 -0
  11. django_cfg/apps/payments/admin/payments_admin.py +142 -0
  12. django_cfg/apps/payments/admin/subscriptions_admin.py +227 -0
  13. django_cfg/apps/payments/admin/tariffs_admin.py +199 -0
  14. django_cfg/apps/payments/config/__init__.py +65 -0
  15. django_cfg/apps/payments/config/module.py +70 -0
  16. django_cfg/apps/payments/config/providers.py +115 -0
  17. django_cfg/apps/payments/config/settings.py +96 -0
  18. django_cfg/apps/payments/config/utils.py +52 -0
  19. django_cfg/apps/payments/decorators.py +291 -0
  20. django_cfg/apps/payments/management/__init__.py +3 -0
  21. django_cfg/apps/payments/management/commands/README.md +178 -0
  22. django_cfg/apps/payments/management/commands/__init__.py +3 -0
  23. django_cfg/apps/payments/management/commands/currency_stats.py +323 -0
  24. django_cfg/apps/payments/management/commands/populate_currencies.py +246 -0
  25. django_cfg/apps/payments/management/commands/update_currencies.py +336 -0
  26. django_cfg/apps/payments/managers/currency_manager.py +65 -14
  27. django_cfg/apps/payments/middleware/api_access.py +294 -0
  28. django_cfg/apps/payments/middleware/rate_limiting.py +216 -0
  29. django_cfg/apps/payments/middleware/usage_tracking.py +296 -0
  30. django_cfg/apps/payments/migrations/0001_initial.py +125 -11
  31. django_cfg/apps/payments/models/__init__.py +18 -0
  32. django_cfg/apps/payments/models/api_keys.py +2 -2
  33. django_cfg/apps/payments/models/balance.py +2 -2
  34. django_cfg/apps/payments/models/base.py +16 -0
  35. django_cfg/apps/payments/models/events.py +2 -2
  36. django_cfg/apps/payments/models/payments.py +112 -2
  37. django_cfg/apps/payments/models/subscriptions.py +2 -2
  38. django_cfg/apps/payments/services/__init__.py +64 -7
  39. django_cfg/apps/payments/services/billing/__init__.py +8 -0
  40. django_cfg/apps/payments/services/cache/__init__.py +15 -0
  41. django_cfg/apps/payments/services/cache/base.py +30 -0
  42. django_cfg/apps/payments/services/cache/simple_cache.py +135 -0
  43. django_cfg/apps/payments/services/core/__init__.py +17 -0
  44. django_cfg/apps/payments/services/core/balance_service.py +447 -0
  45. django_cfg/apps/payments/services/core/fallback_service.py +432 -0
  46. django_cfg/apps/payments/services/core/payment_service.py +576 -0
  47. django_cfg/apps/payments/services/core/subscription_service.py +614 -0
  48. django_cfg/apps/payments/services/internal_types.py +297 -0
  49. django_cfg/apps/payments/services/middleware/__init__.py +8 -0
  50. django_cfg/apps/payments/services/monitoring/__init__.py +22 -0
  51. django_cfg/apps/payments/services/monitoring/api_schemas.py +222 -0
  52. django_cfg/apps/payments/services/monitoring/provider_health.py +372 -0
  53. django_cfg/apps/payments/services/providers/__init__.py +22 -0
  54. django_cfg/apps/payments/services/providers/base.py +137 -0
  55. django_cfg/apps/payments/services/providers/cryptapi.py +273 -0
  56. django_cfg/apps/payments/services/providers/cryptomus.py +310 -0
  57. django_cfg/apps/payments/services/providers/nowpayments.py +293 -0
  58. django_cfg/apps/payments/services/providers/registry.py +103 -0
  59. django_cfg/apps/payments/services/security/__init__.py +34 -0
  60. django_cfg/apps/payments/services/security/error_handler.py +637 -0
  61. django_cfg/apps/payments/services/security/payment_notifications.py +342 -0
  62. django_cfg/apps/payments/services/security/webhook_validator.py +475 -0
  63. django_cfg/apps/payments/services/validators/__init__.py +8 -0
  64. django_cfg/apps/payments/signals/__init__.py +13 -0
  65. django_cfg/apps/payments/signals/api_key_signals.py +160 -0
  66. django_cfg/apps/payments/signals/payment_signals.py +128 -0
  67. django_cfg/apps/payments/signals/subscription_signals.py +196 -0
  68. django_cfg/apps/payments/tasks/__init__.py +12 -0
  69. django_cfg/apps/payments/tasks/webhook_processing.py +177 -0
  70. django_cfg/apps/payments/urls.py +5 -5
  71. django_cfg/apps/payments/utils/__init__.py +45 -0
  72. django_cfg/apps/payments/utils/billing_utils.py +342 -0
  73. django_cfg/apps/payments/utils/config_utils.py +245 -0
  74. django_cfg/apps/payments/utils/middleware_utils.py +228 -0
  75. django_cfg/apps/payments/utils/validation_utils.py +94 -0
  76. django_cfg/apps/payments/views/payment_views.py +40 -2
  77. django_cfg/apps/payments/views/webhook_views.py +266 -0
  78. django_cfg/apps/payments/viewsets.py +65 -0
  79. django_cfg/apps/support/signals.py +16 -4
  80. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  81. django_cfg/cli/README.md +2 -2
  82. django_cfg/cli/commands/create_project.py +1 -1
  83. django_cfg/cli/commands/info.py +1 -1
  84. django_cfg/cli/main.py +1 -1
  85. django_cfg/cli/utils.py +5 -5
  86. django_cfg/core/config.py +18 -4
  87. django_cfg/models/payments.py +546 -0
  88. django_cfg/models/revolution.py +1 -1
  89. django_cfg/models/tasks.py +51 -2
  90. django_cfg/modules/base.py +12 -6
  91. django_cfg/modules/django_currency/README.md +104 -269
  92. django_cfg/modules/django_currency/__init__.py +99 -41
  93. django_cfg/modules/django_currency/clients/__init__.py +11 -0
  94. django_cfg/modules/django_currency/clients/coingecko_client.py +257 -0
  95. django_cfg/modules/django_currency/clients/yfinance_client.py +246 -0
  96. django_cfg/modules/django_currency/core/__init__.py +42 -0
  97. django_cfg/modules/django_currency/core/converter.py +169 -0
  98. django_cfg/modules/django_currency/core/exceptions.py +28 -0
  99. django_cfg/modules/django_currency/core/models.py +54 -0
  100. django_cfg/modules/django_currency/database/__init__.py +25 -0
  101. django_cfg/modules/django_currency/database/database_loader.py +507 -0
  102. django_cfg/modules/django_currency/utils/__init__.py +9 -0
  103. django_cfg/modules/django_currency/utils/cache.py +92 -0
  104. django_cfg/modules/django_email.py +42 -4
  105. django_cfg/modules/django_unfold/dashboard.py +20 -0
  106. django_cfg/registry/core.py +10 -0
  107. django_cfg/template_archive/__init__.py +0 -0
  108. django_cfg/template_archive/django_sample.zip +0 -0
  109. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/METADATA +11 -6
  110. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/RECORD +113 -50
  111. django_cfg/apps/agents/examples/__init__.py +0 -3
  112. django_cfg/apps/agents/examples/simple_example.py +0 -161
  113. django_cfg/apps/knowbase/examples/__init__.py +0 -3
  114. django_cfg/apps/knowbase/examples/external_data_usage.py +0 -191
  115. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +0 -199
  116. django_cfg/apps/payments/services/base.py +0 -68
  117. django_cfg/apps/payments/services/nowpayments.py +0 -78
  118. django_cfg/apps/payments/services/providers.py +0 -77
  119. django_cfg/apps/payments/services/redis_service.py +0 -215
  120. django_cfg/modules/django_currency/cache.py +0 -430
  121. django_cfg/modules/django_currency/converter.py +0 -324
  122. django_cfg/modules/django_currency/service.py +0 -277
  123. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/WHEEL +0 -0
  124. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/entry_points.txt +0 -0
  125. {django_cfg-1.2.22.dist-info → django_cfg-1.2.25.dist-info}/licenses/LICENSE +0 -0
@@ -1,334 +1,169 @@
1
1
  # Django Currency Module
2
2
 
3
- 🚀 **Auto-configuring currency conversion service for django-cfg**
3
+ 🚀 **Universal currency converter with decomposed provider logic**
4
4
 
5
- A comprehensive currency conversion module that integrates seamlessly with DjangoConfig, featuring multiple data sources, intelligent caching, and beautiful YAML export functionality.
5
+ A simple, KISS-principle currency conversion module that provides seamless bidirectional conversion between fiat and cryptocurrency rates.
6
6
 
7
7
  ## ✨ Features
8
8
 
9
- - **🔄 Multi-Source Conversion**: CBR API, ECB API, and fallback currency converter
10
- - **📁 YAML Caching**: Beautiful, human-readable cache files with comments
11
- - **⚡ TTL Memory Cache**: Fast in-memory caching with automatic expiration
12
- - **🌍 170+ Currencies**: Support for major world currencies
13
- - **🔧 Auto-Configuration**: Seamless integration with DjangoConfig
14
- - **📊 Batch Operations**: Convert multiple currencies in one call
15
- - **🎨 Pretty Export**: Export rates to formatted YAML with descriptions
16
- - **🔔 Telegram Integration**: Send currency alerts via Telegram
9
+ - **🔄 Universal Conversion**: Fiat ⇄ Fiat, Crypto ⇄ Fiat, Crypto Crypto
10
+ - **📡 Dynamic Loading**: All currencies loaded dynamically from APIs (no hardcoded lists)
11
+ - **🎯 Provider Separation**: YFinance for fiat, CoinGecko for crypto
12
+ - **⚡ TTL Caching**: Fast in-memory caching with configurable TTL
13
+ - **🔧 Pydantic Models**: All data structures typed with Pydantic v2
14
+ - **🚫 No API Keys**: Uses only public APIs
15
+ - **🔀 Smart Routing**: Automatic provider selection and indirect conversions
17
16
 
18
- ## 🚀 Quick Start
19
-
20
- ### Basic Usage
21
-
22
- ```python
23
- from django_cfg.modules.django_currency import DjangoCurrency
17
+ ## 🏗️ Architecture
24
18
 
25
- # Initialize service (auto-configured)
26
- currency = DjangoCurrency()
27
-
28
- # Convert currencies
29
- result = currency.convert(100, 'USD', 'RUB')
30
- print(f"100 USD = {result:.2f} RUB")
31
-
32
- # Get exchange rate
33
- rate = currency.get_rate('EUR', 'USD')
34
- print(f"1 EUR = {rate:.4f} USD")
35
19
  ```
20
+ django_currency/
21
+ ├── models.py # Pydantic v2 data models
22
+ ├── exceptions.py # Custom exceptions
23
+ ├── cache.py # TTL cache manager
24
+ ├── converter.py # Main conversion logic
25
+ ├── clients/
26
+ │ ├── yfinance_client.py # Fiat currencies only
27
+ │ └── coingecko_client.py # Cryptocurrencies only
28
+ └── __init__.py # Public API
29
+ ```
30
+
31
+ ## 🚀 Quick Start
36
32
 
37
- ### Convenience Functions
33
+ ### Simple API
38
34
 
39
35
  ```python
40
36
  from django_cfg.modules.django_currency import convert_currency, get_exchange_rate
41
37
 
42
- # Quick conversion
43
- amount_rub = convert_currency(100, 'USD', 'RUB')
38
+ # Convert currencies
39
+ eur_amount = convert_currency(100, "USD", "EUR")
40
+ btc_price = convert_currency(50000, "USD", "BTC")
44
41
 
45
- # Quick rate lookup
46
- eur_usd_rate = get_exchange_rate('EUR', 'USD')
42
+ # Get exchange rates
43
+ usd_eur_rate = get_exchange_rate("USD", "EUR")
44
+ btc_usd_rate = get_exchange_rate("BTC", "USD")
47
45
  ```
48
46
 
49
- ### Batch Conversions
47
+ ### Advanced Usage
50
48
 
51
49
  ```python
52
- currency = DjangoCurrency()
50
+ from django_cfg.modules.django_currency import CurrencyConverter
53
51
 
54
- amounts = [100, 500, 1000]
55
- from_currencies = ['USD', 'EUR', 'GBP']
56
- to_currencies = ['RUB', 'RUB', 'RUB']
52
+ converter = CurrencyConverter()
57
53
 
58
- results = currency.convert_multiple(amounts, from_currencies, to_currencies)
59
- # Results: [8074.98, 4268.14, 9514.20]
60
- ```
54
+ # Get conversion result with details
55
+ result = converter.convert(100, "USD", "EUR")
56
+ print(f"Amount: {result.result}")
57
+ print(f"Rate: {result.rate.rate}")
58
+ print(f"Source: {result.rate.source}")
61
59
 
62
- ## 📁 YAML Caching
63
-
64
- The module uses beautiful YAML files for caching with automatic comments:
65
-
66
- ```yaml
67
- # Currency Exchange Rates - Django CFG
68
- # Source: CBR API
69
- # Generated: 2024-01-15 14:30:25 UTC
70
- # Total currencies: 43
71
- # Cache TTL: 24 hours
72
-
73
- source: cbr
74
- timestamp: 2024-01-15T14:30:25.123456
75
-
76
- metadata:
77
- count: 43
78
- cache_version: '1.0'
79
- format: 'YAML'
80
- description: 'Currency rates from CBR API'
81
- updated_at: '2024-01-15 14:30:25 UTC'
82
- ttl_hours: 24
83
- next_update: '2024-01-16 14:30:25 UTC'
84
-
85
- # Currency Rates
86
- rates:
87
- USD: 80.749800 # US Dollar
88
- EUR: 93.627400 # Euro
89
- GBP: 108.422800 # British Pound
90
- JPY: 0.551940 # Japanese Yen
91
- CNY: 11.200000 # Chinese Yuan
92
- KRW: 0.063500 # South Korean Won
93
- RUB: 1.000000 # Russian Ruble
94
- # ... more currencies
60
+ # Get all supported currencies
61
+ currencies = converter.get_supported_currencies()
62
+ print(f"Fiat currencies: {len(currencies.yfinance.fiat)}")
63
+ print(f"Cryptocurrencies: {len(currencies.coingecko.crypto)}")
95
64
  ```
96
65
 
97
- ## 🔧 Configuration
66
+ ## 🎯 Provider Logic
98
67
 
99
- ### DjangoConfig Integration
68
+ ### YFinance Client
69
+ - **Purpose**: Fiat currency pairs only
70
+ - **Symbols**: `EURUSD=X`, `GBPJPY=X`, etc.
71
+ - **Dynamic Loading**: Uses `yf.Lookup().get_currency()` to get all available pairs
72
+ - **Coverage**: All major and minor fiat currencies
100
73
 
101
- ```python
102
- from django_cfg import DjangoConfig
103
-
104
- class MyConfig(DjangoConfig):
105
- project_name: str = "My Project"
106
-
107
- # Optional: Custom cache directory (default: src/django_cfg/cache/currency/)
108
- currency_cache_dir: str = "/path/to/cache"
109
-
110
- # Telegram integration (optional)
111
- telegram: TelegramConfig = TelegramConfig(
112
- bot_token="your_bot_token",
113
- chat_id="your_chat_id"
114
- )
115
-
116
- config = MyConfig()
117
- ```
74
+ ### CoinGecko Client
75
+ - **Purpose**: Cryptocurrency pairs only
76
+ - **API**: CoinGecko Public API v3
77
+ - **Dynamic Loading**: Uses `get_coins_list()` and `get_supported_vs_currencies()`
78
+ - **Coverage**: 17,000+ cryptocurrencies
118
79
 
119
- ### Cache Configuration
80
+ ## 🔄 Conversion Routes
120
81
 
121
82
  ```python
122
- from django_cfg.modules.django_currency import CurrencyCache
123
-
124
- # Custom cache settings
125
- cache = CurrencyCache(
126
- cache_dir=Path("/custom/cache/dir"),
127
- ttl=3600, # 1 hour TTL
128
- max_size=500 # Max 500 items in memory
129
- )
130
- ```
131
-
132
- ## 📊 Data Sources
133
-
134
- ### 1. Central Bank of Russia (CBR)
135
- - **Best for**: RUB-based conversions
136
- - **URL**: `https://www.cbr-xml-daily.ru/daily_json.js`
137
- - **Currencies**: 40+ major currencies
138
- - **Update**: Daily
139
-
140
- ### 2. European Central Bank (ECB)
141
- - **Best for**: EUR-based conversions
142
- - **URL**: `https://api.exchangerate-api.com/v4/latest/EUR`
143
- - **Currencies**: 170+ currencies
144
- - **Update**: Daily
145
-
146
- ### 3. Fallback Converter
147
- - **Library**: `currency_converter`
148
- - **Best for**: Historical rates and exotic pairs
149
- - **Offline**: Works without internet (cached data)
150
-
151
- ## 🎨 Advanced Features
152
-
153
- ### Export to YAML
83
+ # Direct routes
84
+ USD → EUR # YFinance
85
+ BTC USD # CoinGecko
154
86
 
155
- ```python
156
- currency = DjangoCurrency()
157
-
158
- # Export current rates to formatted YAML
159
- yaml_content = currency.cache.export_rates_yaml('cbr')
160
- print(yaml_content)
161
-
162
- # Save to file
163
- from pathlib import Path
164
- output_file = Path('currency_rates.yaml')
165
- currency.cache.export_rates_yaml('cbr', output_file)
87
+ # Indirect routes (via USD bridge)
88
+ EUR BTC # EUR → USD → BTC
89
+ ETH → BTC # ETH → USD → BTC
166
90
  ```
167
91
 
168
- ### Cache Management
92
+ ## 📊 Data Models
169
93
 
170
- ```python
171
- currency = DjangoCurrency()
94
+ All responses use Pydantic v2 models:
172
95
 
173
- # Get cache information
174
- cache_info = currency.get_config_info()
175
- print(f"Cache directory: {cache_info['cache_directory']}")
176
- print(f"Memory cache size: {cache_info['cache_info']['memory_cache']['size']}")
177
-
178
- # Force refresh rates
179
- success = currency.refresh_rates()
180
- print(f"Refresh {'successful' if success else 'failed'}")
96
+ ```python
97
+ class Rate(BaseModel):
98
+ source: str # "yfinance" or "coingecko"
99
+ base_currency: str # "USD"
100
+ quote_currency: str # "EUR"
101
+ rate: float # 0.85
102
+ timestamp: datetime # Auto-generated
181
103
 
182
- # Clear cache
183
- currency.cache.clear_cache('cbr') # Clear specific source
184
- currency.cache.clear_cache() # Clear all
104
+ class ConversionResult(BaseModel):
105
+ request: ConversionRequest
106
+ result: float
107
+ rate: Rate
108
+ path: Optional[str] # "EUR→USD→BTC" for indirect
185
109
  ```
186
110
 
187
- ### Telegram Alerts
188
-
189
- ```python
190
- from django_cfg.modules.django_currency import DjangoCurrency
111
+ ## Caching
191
112
 
192
- # Send currency alert
193
- DjangoCurrency.send_currency_alert(
194
- "USD/RUB rate exceeded 85.00!",
195
- rates={"USD/RUB": 85.25, "EUR/RUB": 92.15}
196
- )
197
- ```
113
+ - **TTL Cache**: Configurable time-to-live (default: 5 minutes)
114
+ - **Per-Source**: Separate cache for each provider
115
+ - **Statistics**: Cache hit/miss monitoring
116
+ - **Memory Efficient**: Uses `cachetools.TTLCache`
198
117
 
199
118
  ## 🧪 Testing
200
119
 
201
- Run the included test script:
202
-
203
120
  ```bash
204
- cd /path/to/django_currency/
121
+ cd django_cfg/modules/django_currency/
205
122
  python test_currency.py
206
123
  ```
207
124
 
208
- Example output:
125
+ ## 🎨 Example Output
126
+
209
127
  ```
210
128
  🧪 Testing Django Currency Module...
211
129
  ==================================================
212
130
 
213
- 💱 Basic Currency Conversion:
214
- ✅ 100 USD = 8074.98 RUB
131
+ 💱 Test 1: Fiat Currency Conversion
132
+ ✅ 100 USD = 85.23 EUR
215
133
 
216
- 🔄 Using Convenience Function:
217
- 100 USD = 93.15 EUR
134
+ 📊 Test 2: Exchange Rate
135
+ 1 USD = 0.8523 EUR
218
136
 
219
- 📊 Exchange Rates:
220
- ✅ 1 USD = 80.7498 RUB
137
+ 🪙 Test 3: Crypto Conversion
138
+ ✅ 1 BTC = 45,230.50 USD
221
139
 
222
- 📋 Available Currencies:
223
- Total currencies: 43
224
- Major currencies available: USD, EUR, GBP, JPY, CNY, KRW, RUB
140
+ 📋 Test 4: Supported Currencies
141
+ YFinance fiat currencies: 168
142
+ CoinGecko cryptocurrencies: 17,247
143
+ ✅ CoinGecko vs_currencies: 61
225
144
 
226
145
  🎉 All tests completed successfully!
227
146
  ```
228
147
 
229
- ## 📦 Dependencies
148
+ ## 🚫 No Fallbacks Policy
230
149
 
231
- - `pyyaml` - YAML parsing and generation
232
- - `requests` - HTTP requests for API calls
233
- - `cachetools` - TTL memory caching
234
- - `currency_converter` - Fallback converter (optional)
150
+ - **Strict Mode**: If API fails, module fails (no backup hardcoded lists)
151
+ - **Dynamic Only**: All currencies loaded from live APIs
152
+ - **Fail Fast**: Clear error messages when providers unavailable
235
153
 
236
- ## 🔍 Error Handling
154
+ ## 📝 Error Handling
237
155
 
238
156
  ```python
239
- currency = DjangoCurrency()
240
-
241
- # Graceful error handling
242
157
  try:
243
- result = currency.convert(100, 'USD', 'INVALID')
244
- except CurrencyConversionError as e:
245
- print(f"Conversion failed: {e}")
246
-
247
- # Silent failures
248
- result = currency.convert(100, 'USD', 'INVALID', fail_silently=True)
249
- # Returns 0.0 on failure
158
+ result = convert_currency(100, "INVALID", "USD")
159
+ except CurrencyNotFoundError:
160
+ print("Currency not supported")
161
+ except RateFetchError:
162
+ print("API temporarily unavailable")
163
+ except ConversionError:
164
+ print("Conversion failed")
250
165
  ```
251
166
 
252
- ## 🎯 Use Cases
253
-
254
- ### E-commerce
255
- ```python
256
- # Convert product prices
257
- product_price_usd = 99.99
258
- price_rub = convert_currency(product_price_usd, 'USD', 'RUB')
259
- ```
260
-
261
- ### Financial Applications
262
- ```python
263
- # Portfolio conversion
264
- currency = DjangoCurrency()
265
- portfolio_values = [1000, 2000, 1500] # USD, EUR, GBP
266
- currencies = ['USD', 'EUR', 'GBP']
267
- target_currency = 'RUB'
268
-
269
- rub_values = currency.convert_multiple(
270
- portfolio_values,
271
- currencies,
272
- [target_currency] * len(currencies)
273
- )
274
- total_rub = sum(rub_values)
275
- ```
276
-
277
- ### Tax Calculations
278
- ```python
279
- # For CarAPIS tax calculator
280
- def calculate_vehicle_tax(vehicle_price_krw: float, target_country: str):
281
- currency = DjangoCurrency()
282
-
283
- # Convert KRW to local currency
284
- if target_country == 'RU':
285
- price_rub = currency.convert(vehicle_price_krw, 'KRW', 'RUB')
286
- return calculate_russian_tax(price_rub)
287
- elif target_country == 'US':
288
- price_usd = currency.convert(vehicle_price_krw, 'KRW', 'USD')
289
- return calculate_us_tax(price_usd)
290
- ```
291
-
292
- ## 🔗 Integration with Django CFG
293
-
294
- The module automatically integrates with other django-cfg services:
295
-
296
- - **📧 Email Service**: Send rate alerts via email
297
- - **📱 Telegram Service**: Send notifications to Telegram
298
- - **📊 Logger Service**: Structured logging with configuration
299
- - **⚙️ Configuration**: Auto-discovery of DjangoConfig settings
300
-
301
- ## 📈 Performance
302
-
303
- - **Memory Cache**: Sub-millisecond lookups for cached rates
304
- - **File Cache**: ~10ms for file-based cache hits
305
- - **API Calls**: ~200-500ms for fresh data from APIs
306
- - **Batch Operations**: Optimized for multiple conversions
307
- - **YAML Export**: ~50ms for 100+ currencies with formatting
308
-
309
- ## 🛠️ Development
310
-
311
- ### Project Structure
312
- ```
313
- django_currency/
314
- ├── __init__.py # Public API exports
315
- ├── service.py # Main DjangoCurrency service
316
- ├── converter.py # Currency conversion logic
317
- ├── cache.py # YAML caching system
318
- ├── test_currency.py # Test suite
319
- └── README.md # This file
320
- ```
321
-
322
- ### Contributing
323
-
324
- 1. Follow django-cfg module patterns
325
- 2. Use YAML for configuration files
326
- 3. Include comprehensive error handling
327
- 4. Add tests for new features
328
- 5. Update documentation
329
-
330
167
  ---
331
168
 
332
- **Made with ❤️ for the Django CFG ecosystem**
333
-
334
- *Beautiful currency conversion with intelligent caching and seamless Django integration.*
169
+ **Built with ❤️ following KISS principles and decomposed architecture**
@@ -1,47 +1,105 @@
1
1
  """
2
- Django Currency Service for django_cfg.
2
+ Django Currency Module - Simple universal currency converter.
3
3
 
4
- Auto-configuring currency conversion service that integrates with DjangoConfig.
4
+ Provides seamless bidirectional conversion between fiat and cryptocurrency rates.
5
+ Uses YFinance for fiat/major crypto pairs and CoinGecko for broad crypto coverage.
5
6
  """
6
7
 
7
- from .service import DjangoCurrency, CurrencyError, CurrencyConfigError
8
- from .converter import CurrencyConverter
9
- from .cache import CurrencyCache
10
-
11
- # Convenience functions
12
- def convert_currency(
13
- amount: float,
14
- from_currency: str,
15
- to_currency: str,
16
- fail_silently: bool = False
17
- ) -> float:
18
- """Convert currency using auto-configured service."""
19
- currency = DjangoCurrency()
20
- return currency.convert(
21
- amount=amount,
22
- from_currency=from_currency,
23
- to_currency=to_currency,
24
- fail_silently=fail_silently
25
- )
26
-
27
- def get_exchange_rate(from_currency: str, to_currency: str) -> float:
28
- """Get exchange rate using auto-configured service."""
29
- currency = DjangoCurrency()
30
- return currency.get_rate(from_currency, to_currency)
31
-
32
- def get_available_currencies() -> set:
33
- """Get available currencies."""
34
- currency = DjangoCurrency()
35
- return currency.get_available_currencies()
36
-
37
- # Export public API
8
+ # Core functionality
9
+ from .core import (
10
+ CurrencyConverter,
11
+ Rate,
12
+ ConversionRequest,
13
+ ConversionResult,
14
+ SupportedCurrencies,
15
+ YFinanceCurrencies,
16
+ CoinGeckoCurrencies,
17
+ CurrencyError,
18
+ CurrencyNotFoundError,
19
+ RateFetchError,
20
+ ConversionError,
21
+ CacheError
22
+ )
23
+
24
+ # Utilities
25
+ from .utils import CacheManager
26
+
27
+ # Clients
28
+ from .clients import YFinanceClient, CoinGeckoClient
29
+
30
+ # Database tools
31
+ from .database import (
32
+ CurrencyDatabaseLoader,
33
+ DatabaseLoaderConfig,
34
+ create_database_loader,
35
+ load_currencies_to_database_format
36
+ )
37
+
38
+ # Simple public API
39
+ def convert_currency(amount: float, from_currency: str, to_currency: str) -> float:
40
+ """
41
+ Convert currency amount.
42
+
43
+ Args:
44
+ amount: Amount to convert
45
+ from_currency: Source currency code
46
+ to_currency: Target currency code
47
+
48
+ Returns:
49
+ Converted amount
50
+ """
51
+ converter = CurrencyConverter()
52
+ result = converter.convert(amount, from_currency, to_currency)
53
+ return result.result
54
+
55
+
56
+ def get_exchange_rate(base: str, quote: str) -> float:
57
+ """
58
+ Get exchange rate between currencies.
59
+
60
+ Args:
61
+ base: Base currency code
62
+ quote: Quote currency code
63
+
64
+ Returns:
65
+ Exchange rate
66
+ """
67
+ converter = CurrencyConverter()
68
+ result = converter.convert(1.0, base, quote)
69
+ return result.rate.rate
70
+
71
+
38
72
  __all__ = [
39
- 'DjangoCurrency',
40
- 'CurrencyConverter',
41
- 'CurrencyCache',
42
- 'CurrencyError',
43
- 'CurrencyConfigError',
44
- 'convert_currency',
45
- 'get_exchange_rate',
46
- 'get_available_currencies'
73
+ # Core converter and models
74
+ "CurrencyConverter",
75
+ "Rate",
76
+ "ConversionRequest",
77
+ "ConversionResult",
78
+ "SupportedCurrencies",
79
+ "YFinanceCurrencies",
80
+ "CoinGeckoCurrencies",
81
+
82
+ # Exceptions
83
+ "CurrencyError",
84
+ "CurrencyNotFoundError",
85
+ "RateFetchError",
86
+ "ConversionError",
87
+ "CacheError",
88
+
89
+ # Utilities
90
+ "CacheManager",
91
+
92
+ # Clients
93
+ "YFinanceClient",
94
+ "CoinGeckoClient",
95
+
96
+ # Database tools
97
+ "CurrencyDatabaseLoader",
98
+ "DatabaseLoaderConfig",
99
+ "create_database_loader",
100
+ "load_currencies_to_database_format",
101
+
102
+ # Public API
103
+ "convert_currency",
104
+ "get_exchange_rate"
47
105
  ]
@@ -0,0 +1,11 @@
1
+ """
2
+ Currency data clients for fetching rates from external APIs.
3
+ """
4
+
5
+ from .yfinance_client import YFinanceClient
6
+ from .coingecko_client import CoinGeckoClient
7
+
8
+ __all__ = [
9
+ 'YFinanceClient',
10
+ 'CoinGeckoClient'
11
+ ]