django-cfg 1.3.1__py3-none-any.whl → 1.3.3__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/management/commands/cleanup_expired_data.py +419 -0
- django_cfg/apps/payments/management/commands/currency_stats.py +376 -0
- django_cfg/apps/payments/management/commands/process_pending_payments.py +357 -0
- django_cfg/apps/payments/management/commands/test_providers.py +434 -0
- django_cfg/apps/payments/models/balance.py +5 -2
- django_cfg/apps/payments/models/managers/api_key_managers.py +2 -2
- django_cfg/apps/payments/models/managers/balance_managers.py +3 -3
- django_cfg/apps/payments/models/managers/subscription_managers.py +3 -3
- django_cfg/apps/payments/services/cache_service/__init__.py +143 -0
- django_cfg/apps/payments/services/cache_service/api_key_cache.py +37 -0
- django_cfg/apps/payments/services/cache_service/interfaces.py +32 -0
- django_cfg/apps/payments/services/cache_service/keys.py +49 -0
- django_cfg/apps/payments/services/cache_service/rate_limit_cache.py +47 -0
- django_cfg/apps/payments/services/cache_service/simple_cache.py +101 -0
- django_cfg/apps/payments/services/core/payment_service.py +49 -22
- django_cfg/apps/payments/signals/api_key_signals.py +2 -2
- django_cfg/apps/payments/signals/balance_signals.py +1 -1
- django_cfg/utils/smart_defaults.py +10 -4
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.3.dist-info}/METADATA +1 -1
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.3.dist-info}/RECORD +24 -15
- django_cfg/apps/payments/services/cache/cache_service.py +0 -235
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.3.dist-info}/WHEEL +0 -0
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.3.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.3.1.dist-info → django_cfg-1.3.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
"""
|
2
|
+
API Key cache implementation for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Specialized caching for API key operations and validation.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Optional
|
8
|
+
from .simple_cache import SimpleCache
|
9
|
+
|
10
|
+
|
11
|
+
class ApiKeyCache:
|
12
|
+
"""Specialized cache for API key operations."""
|
13
|
+
|
14
|
+
def __init__(self):
|
15
|
+
self.cache = SimpleCache("api_keys")
|
16
|
+
self.default_timeout = self._get_cache_timeout('api_key')
|
17
|
+
|
18
|
+
def _get_cache_timeout(self, cache_type: str) -> int:
|
19
|
+
"""Get cache timeout from PaymentsConfig."""
|
20
|
+
try:
|
21
|
+
from django_cfg.models.payments import PaymentsConfig
|
22
|
+
config = PaymentsConfig.get_current_config()
|
23
|
+
return config.cache_timeouts.get(cache_type, 300)
|
24
|
+
except Exception:
|
25
|
+
return 300 # 5 minutes default
|
26
|
+
|
27
|
+
def get_api_key_data(self, api_key: str) -> Optional[dict]:
|
28
|
+
"""Get cached API key data."""
|
29
|
+
return self.cache.get(f"key:{api_key}")
|
30
|
+
|
31
|
+
def cache_api_key_data(self, api_key: str, data: dict) -> bool:
|
32
|
+
"""Cache API key data."""
|
33
|
+
return self.cache.set(f"key:{api_key}", data, self.default_timeout)
|
34
|
+
|
35
|
+
def invalidate_api_key(self, api_key: str) -> bool:
|
36
|
+
"""Invalidate cached API key."""
|
37
|
+
return self.cache.delete(f"key:{api_key}")
|
@@ -0,0 +1,32 @@
|
|
1
|
+
"""
|
2
|
+
Cache interfaces for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Abstract interfaces for cache implementations.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from abc import ABC, abstractmethod
|
8
|
+
from typing import Optional, Any
|
9
|
+
|
10
|
+
|
11
|
+
class CacheInterface(ABC):
|
12
|
+
"""Abstract cache interface."""
|
13
|
+
|
14
|
+
@abstractmethod
|
15
|
+
def get(self, key: str) -> Optional[Any]:
|
16
|
+
"""Get value from cache."""
|
17
|
+
pass
|
18
|
+
|
19
|
+
@abstractmethod
|
20
|
+
def set(self, key: str, value: Any, timeout: Optional[int] = None) -> bool:
|
21
|
+
"""Set value in cache."""
|
22
|
+
pass
|
23
|
+
|
24
|
+
@abstractmethod
|
25
|
+
def delete(self, key: str) -> bool:
|
26
|
+
"""Delete value from cache."""
|
27
|
+
pass
|
28
|
+
|
29
|
+
@abstractmethod
|
30
|
+
def exists(self, key: str) -> bool:
|
31
|
+
"""Check if key exists in cache."""
|
32
|
+
pass
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"""
|
2
|
+
Cache key generation utilities for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Centralized cache key generation for consistency and testing.
|
5
|
+
"""
|
6
|
+
|
7
|
+
|
8
|
+
class CacheKeys:
|
9
|
+
"""Cache key generation utilities."""
|
10
|
+
|
11
|
+
@staticmethod
|
12
|
+
def user_balance(user_id: int) -> str:
|
13
|
+
"""Generate cache key for user balance."""
|
14
|
+
return f"payments:user_balance:{user_id}"
|
15
|
+
|
16
|
+
@staticmethod
|
17
|
+
def payment(payment_id: str) -> str:
|
18
|
+
"""Generate cache key for payment data."""
|
19
|
+
return f"payments:payment:{payment_id}"
|
20
|
+
|
21
|
+
@staticmethod
|
22
|
+
def payment_status(payment_id: str) -> str:
|
23
|
+
"""Generate cache key for payment status."""
|
24
|
+
return f"payments:payment_status:{payment_id}"
|
25
|
+
|
26
|
+
@staticmethod
|
27
|
+
def currency_rates(from_currency: str, to_currency: str) -> str:
|
28
|
+
"""Generate cache key for currency exchange rates."""
|
29
|
+
return f"payments:currency_rates:{from_currency}:{to_currency}"
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def provider_currencies(provider: str) -> str:
|
33
|
+
"""Generate cache key for provider supported currencies."""
|
34
|
+
return f"payments:provider_currencies:{provider}"
|
35
|
+
|
36
|
+
@staticmethod
|
37
|
+
def api_key_validation(api_key: str) -> str:
|
38
|
+
"""Generate cache key for API key validation data."""
|
39
|
+
return f"payments:api_key_validation:{api_key}"
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def user_subscription(user_id: int) -> str:
|
43
|
+
"""Generate cache key for user subscription data."""
|
44
|
+
return f"payments:user_subscription:{user_id}"
|
45
|
+
|
46
|
+
@staticmethod
|
47
|
+
def rate_limit(user_id: int, action: str) -> str:
|
48
|
+
"""Generate cache key for rate limiting."""
|
49
|
+
return f"payments:rate_limit:{user_id}:{action}"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
"""
|
2
|
+
Rate limiting cache implementation for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Specialized caching for API rate limiting and usage tracking.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Optional
|
8
|
+
from .simple_cache import SimpleCache
|
9
|
+
|
10
|
+
|
11
|
+
class RateLimitCache:
|
12
|
+
"""Specialized cache for rate limiting."""
|
13
|
+
|
14
|
+
def __init__(self):
|
15
|
+
self.cache = SimpleCache("rate_limit")
|
16
|
+
|
17
|
+
def get_usage_count(self, user_id: int, endpoint_group: str, window: str = "hour") -> int:
|
18
|
+
"""Get current usage count for rate limiting."""
|
19
|
+
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
20
|
+
count = self.cache.get(key)
|
21
|
+
return count if count is not None else 0
|
22
|
+
|
23
|
+
def increment_usage(self, user_id: int, endpoint_group: str, window: str = "hour", ttl: Optional[int] = None) -> int:
|
24
|
+
"""Increment usage count and return new count."""
|
25
|
+
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
26
|
+
|
27
|
+
# Get current count
|
28
|
+
current = self.get_usage_count(user_id, endpoint_group, window)
|
29
|
+
new_count = current + 1
|
30
|
+
|
31
|
+
# Get TTL from config or use defaults
|
32
|
+
if ttl is None:
|
33
|
+
try:
|
34
|
+
from django_cfg.models.payments import PaymentsConfig
|
35
|
+
config = PaymentsConfig.get_current_config()
|
36
|
+
ttl = config.cache_timeouts.get('rate_limit', 3600)
|
37
|
+
except Exception:
|
38
|
+
ttl = 3600 if window == "hour" else 86400 # 1 hour or 1 day
|
39
|
+
|
40
|
+
# Set new count with TTL
|
41
|
+
self.cache.set(key, new_count, ttl)
|
42
|
+
return new_count
|
43
|
+
|
44
|
+
def reset_usage(self, user_id: int, endpoint_group: str, window: str = "hour") -> bool:
|
45
|
+
"""Reset usage count."""
|
46
|
+
key = f"usage:{user_id}:{endpoint_group}:{window}"
|
47
|
+
return self.cache.delete(key)
|
@@ -0,0 +1,101 @@
|
|
1
|
+
"""
|
2
|
+
Simple cache implementation for the Universal Payment System v2.0.
|
3
|
+
|
4
|
+
Basic cache functionality with graceful fallback.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Optional, Any
|
8
|
+
from django.core.cache import cache
|
9
|
+
from django_cfg.modules.django_logger import get_logger
|
10
|
+
|
11
|
+
from .interfaces import CacheInterface
|
12
|
+
|
13
|
+
logger = get_logger(__name__)
|
14
|
+
|
15
|
+
|
16
|
+
class SimpleCache(CacheInterface):
|
17
|
+
"""
|
18
|
+
Simple cache implementation using Django's cache framework.
|
19
|
+
|
20
|
+
Falls back gracefully when cache is unavailable.
|
21
|
+
Based on proven solution from payments_old.
|
22
|
+
"""
|
23
|
+
|
24
|
+
def __init__(self, prefix: str = "payments"):
|
25
|
+
self.prefix = prefix
|
26
|
+
self.enabled = self._is_cache_enabled()
|
27
|
+
|
28
|
+
def _is_cache_enabled(self) -> bool:
|
29
|
+
"""Check if cache is enabled via PaymentsConfig."""
|
30
|
+
from django.conf import settings
|
31
|
+
import sys
|
32
|
+
|
33
|
+
# For tests, always enable cache (detect test environment)
|
34
|
+
if 'test' in sys.argv or hasattr(settings, 'TESTING'):
|
35
|
+
return True
|
36
|
+
|
37
|
+
# For development, enable by default
|
38
|
+
if settings.DEBUG:
|
39
|
+
return True
|
40
|
+
|
41
|
+
try:
|
42
|
+
from django_cfg.models.payments import PaymentsConfig
|
43
|
+
config = PaymentsConfig.get_current_config()
|
44
|
+
return config.enabled # Cache enabled if payments enabled
|
45
|
+
except Exception as e:
|
46
|
+
logger.debug(f"PaymentsConfig not available, enabling cache by default: {e}")
|
47
|
+
return True # Default to enabled with graceful fallback
|
48
|
+
|
49
|
+
def _make_key(self, key: str) -> str:
|
50
|
+
"""Create prefixed cache key."""
|
51
|
+
return f"{self.prefix}:{key}"
|
52
|
+
|
53
|
+
def get(self, key: str) -> Optional[Any]:
|
54
|
+
"""Get value from cache."""
|
55
|
+
if not self.enabled:
|
56
|
+
return None
|
57
|
+
|
58
|
+
try:
|
59
|
+
cache_key = self._make_key(key)
|
60
|
+
return cache.get(cache_key)
|
61
|
+
except Exception as e:
|
62
|
+
logger.warning(f"Cache get failed for key {key}: {e}")
|
63
|
+
return None
|
64
|
+
|
65
|
+
def set(self, key: str, value: Any, timeout: Optional[int] = None) -> bool:
|
66
|
+
"""Set value in cache."""
|
67
|
+
if not self.enabled:
|
68
|
+
return False
|
69
|
+
|
70
|
+
try:
|
71
|
+
cache_key = self._make_key(key)
|
72
|
+
cache.set(cache_key, value, timeout)
|
73
|
+
return True
|
74
|
+
except Exception as e:
|
75
|
+
logger.warning(f"Cache set failed for key {key}: {e}")
|
76
|
+
return False
|
77
|
+
|
78
|
+
def delete(self, key: str) -> bool:
|
79
|
+
"""Delete value from cache."""
|
80
|
+
if not self.enabled:
|
81
|
+
return False
|
82
|
+
|
83
|
+
try:
|
84
|
+
cache_key = self._make_key(key)
|
85
|
+
cache.delete(cache_key)
|
86
|
+
return True
|
87
|
+
except Exception as e:
|
88
|
+
logger.warning(f"Cache delete failed for key {key}: {e}")
|
89
|
+
return False
|
90
|
+
|
91
|
+
def exists(self, key: str) -> bool:
|
92
|
+
"""Check if key exists in cache."""
|
93
|
+
if not self.enabled:
|
94
|
+
return False
|
95
|
+
|
96
|
+
try:
|
97
|
+
cache_key = self._make_key(key)
|
98
|
+
return cache.get(cache_key) is not None
|
99
|
+
except Exception as e:
|
100
|
+
logger.warning(f"Cache exists check failed for key {key}: {e}")
|
101
|
+
return False
|
@@ -6,19 +6,20 @@ Handles payment creation, status checking, and lifecycle management.
|
|
6
6
|
|
7
7
|
from typing import Optional, Dict, Any
|
8
8
|
from decimal import Decimal
|
9
|
-
from django.contrib.auth
|
9
|
+
from django.contrib.auth import get_user_model
|
10
|
+
from django.db import models
|
10
11
|
from django.utils import timezone
|
11
12
|
|
13
|
+
from django_cfg.modules.django_currency import convert_currency, get_exchange_rate
|
12
14
|
from .base import BaseService
|
13
15
|
from ..types import (
|
14
16
|
PaymentCreateRequest, PaymentStatusRequest, PaymentResult,
|
15
17
|
PaymentData, ServiceOperationResult
|
16
18
|
)
|
17
19
|
from ...models import UniversalPayment, Currency, ProviderCurrency
|
18
|
-
from django_cfg.modules.django_currency import convert_currency, get_exchange_rate
|
19
|
-
# ConfigService removed - using direct Constance access
|
20
20
|
from ..providers import ProviderRegistry, get_provider_registry
|
21
21
|
|
22
|
+
User = get_user_model()
|
22
23
|
|
23
24
|
class PaymentService(BaseService):
|
24
25
|
"""
|
@@ -85,16 +86,17 @@ class PaymentService(BaseService):
|
|
85
86
|
|
86
87
|
# Create payment in database first
|
87
88
|
def create_payment_transaction():
|
89
|
+
currency = currency_result.data['currency']
|
88
90
|
payment = UniversalPayment.objects.create(
|
89
91
|
user=user,
|
90
92
|
amount_usd=request.amount_usd,
|
91
|
-
|
93
|
+
currency=currency,
|
94
|
+
network=currency.native_networks.first(), # Use first native network
|
92
95
|
provider=request.provider,
|
93
96
|
status=UniversalPayment.PaymentStatus.PENDING,
|
94
97
|
callback_url=request.callback_url,
|
95
98
|
cancel_url=request.cancel_url,
|
96
99
|
description=request.description,
|
97
|
-
metadata=request.metadata,
|
98
100
|
expires_at=timezone.now() + timezone.timedelta(hours=1) # 1 hour expiry
|
99
101
|
)
|
100
102
|
return payment
|
@@ -137,8 +139,8 @@ class PaymentService(BaseService):
|
|
137
139
|
error_code="provider_creation_failed"
|
138
140
|
)
|
139
141
|
|
140
|
-
# Convert to PaymentData
|
141
|
-
payment_data =
|
142
|
+
# Convert to PaymentData using our helper method
|
143
|
+
payment_data = self._convert_payment_to_data(payment)
|
142
144
|
|
143
145
|
self._log_operation(
|
144
146
|
"create_payment",
|
@@ -154,8 +156,9 @@ class PaymentService(BaseService):
|
|
154
156
|
payment_id=str(payment.id),
|
155
157
|
status=payment.status,
|
156
158
|
amount_usd=payment.amount_usd,
|
157
|
-
crypto_amount=payment.
|
158
|
-
currency_code=payment.
|
159
|
+
crypto_amount=payment.pay_amount,
|
160
|
+
currency_code=payment.currency.code,
|
161
|
+
payment_url=payment.payment_url,
|
159
162
|
expires_at=payment.expires_at,
|
160
163
|
data={'payment': payment_data.model_dump()}
|
161
164
|
)
|
@@ -211,8 +214,8 @@ class PaymentService(BaseService):
|
|
211
214
|
# Reload payment if status was updated
|
212
215
|
payment.refresh_from_db()
|
213
216
|
|
214
|
-
# Convert to PaymentData
|
215
|
-
payment_data =
|
217
|
+
# Convert to PaymentData using from_attributes
|
218
|
+
payment_data = self._convert_payment_to_data(payment)
|
216
219
|
|
217
220
|
return PaymentResult(
|
218
221
|
success=True,
|
@@ -220,12 +223,12 @@ class PaymentService(BaseService):
|
|
220
223
|
payment_id=str(payment.id),
|
221
224
|
status=payment.status,
|
222
225
|
amount_usd=payment.amount_usd,
|
223
|
-
crypto_amount=payment.
|
224
|
-
currency_code=payment.
|
226
|
+
crypto_amount=payment.pay_amount,
|
227
|
+
currency_code=payment.currency.code,
|
225
228
|
provider_payment_id=payment.provider_payment_id,
|
226
229
|
payment_url=payment.payment_url,
|
227
|
-
qr_code_url=payment
|
228
|
-
wallet_address=payment.
|
230
|
+
qr_code_url=getattr(payment, 'qr_code_url', None),
|
231
|
+
wallet_address=payment.pay_address,
|
229
232
|
expires_at=payment.expires_at,
|
230
233
|
data={'payment': payment_data.model_dump()}
|
231
234
|
)
|
@@ -279,7 +282,7 @@ class PaymentService(BaseService):
|
|
279
282
|
|
280
283
|
if success:
|
281
284
|
payment.refresh_from_db()
|
282
|
-
payment_data =
|
285
|
+
payment_data = self._convert_payment_to_data(payment)
|
283
286
|
|
284
287
|
self._log_operation(
|
285
288
|
"cancel_payment",
|
@@ -311,7 +314,7 @@ class PaymentService(BaseService):
|
|
311
314
|
def _validate_currency(self, currency_code: str) -> ServiceOperationResult:
|
312
315
|
"""Validate currency is supported."""
|
313
316
|
try:
|
314
|
-
currency = Currency.objects.get(code=currency_code,
|
317
|
+
currency = Currency.objects.get(code=currency_code, is_active=True)
|
315
318
|
|
316
319
|
# Check if currency is supported by any provider
|
317
320
|
provider_currency = ProviderCurrency.objects.filter(
|
@@ -327,7 +330,7 @@ class PaymentService(BaseService):
|
|
327
330
|
|
328
331
|
return self._create_success_result(
|
329
332
|
"Currency is valid",
|
330
|
-
{'currency':
|
333
|
+
{'currency': currency} # Wrap in dict for Pydantic
|
331
334
|
)
|
332
335
|
|
333
336
|
except Currency.DoesNotExist:
|
@@ -391,10 +394,10 @@ class PaymentService(BaseService):
|
|
391
394
|
total_count = queryset.count()
|
392
395
|
payments = queryset.order_by('-created_at')[offset:offset + limit]
|
393
396
|
|
394
|
-
payment_data = [
|
395
|
-
|
396
|
-
|
397
|
-
|
397
|
+
payment_data = []
|
398
|
+
for payment in payments:
|
399
|
+
payment_obj = self._convert_payment_to_data(payment)
|
400
|
+
payment_data.append(payment_obj.model_dump())
|
398
401
|
|
399
402
|
return self._create_success_result(
|
400
403
|
f"Retrieved {len(payment_data)} payments",
|
@@ -413,6 +416,30 @@ class PaymentService(BaseService):
|
|
413
416
|
user_id=user_id
|
414
417
|
)
|
415
418
|
|
419
|
+
def _convert_payment_to_data(self, payment: UniversalPayment) -> PaymentData:
|
420
|
+
"""Convert Django UniversalPayment to PaymentData."""
|
421
|
+
return PaymentData(
|
422
|
+
id=str(payment.id),
|
423
|
+
user_id=payment.user_id,
|
424
|
+
amount_usd=float(payment.amount_usd),
|
425
|
+
crypto_amount=payment.pay_amount,
|
426
|
+
currency_code=payment.currency.code,
|
427
|
+
provider=payment.provider,
|
428
|
+
status=payment.status,
|
429
|
+
provider_payment_id=payment.provider_payment_id,
|
430
|
+
payment_url=payment.payment_url,
|
431
|
+
qr_code_url=getattr(payment, 'qr_code_url', None),
|
432
|
+
wallet_address=payment.pay_address,
|
433
|
+
callback_url=payment.callback_url,
|
434
|
+
cancel_url=payment.cancel_url,
|
435
|
+
description=payment.description,
|
436
|
+
metadata={},
|
437
|
+
created_at=payment.created_at,
|
438
|
+
updated_at=payment.updated_at,
|
439
|
+
expires_at=payment.expires_at,
|
440
|
+
completed_at=getattr(payment, 'completed_at', None)
|
441
|
+
)
|
442
|
+
|
416
443
|
def get_payment_stats(self, days: int = 30) -> ServiceOperationResult:
|
417
444
|
"""Get payment statistics."""
|
418
445
|
try:
|
@@ -43,7 +43,7 @@ def handle_api_key_changes(sender, instance: APIKey, created: bool, **kwargs):
|
|
43
43
|
logger.info(f"New API key created", extra={
|
44
44
|
'api_key_id': str(instance.id),
|
45
45
|
'user_id': instance.user.id,
|
46
|
-
'
|
46
|
+
'key_name': instance.name,
|
47
47
|
'expires_at': instance.expires_at.isoformat() if instance.expires_at else None
|
48
48
|
})
|
49
49
|
|
@@ -52,7 +52,7 @@ def handle_api_key_changes(sender, instance: APIKey, created: bool, **kwargs):
|
|
52
52
|
f"api_key_created:{instance.user.id}:{instance.id}",
|
53
53
|
{
|
54
54
|
'api_key_id': str(instance.id),
|
55
|
-
'
|
55
|
+
'key_name': instance.name,
|
56
56
|
'timestamp': timezone.now().isoformat()
|
57
57
|
},
|
58
58
|
timeout=86400 # 24 hours
|
@@ -81,7 +81,7 @@ def handle_transaction_creation(sender, instance: Transaction, created: bool, **
|
|
81
81
|
'transaction_id': str(instance.id),
|
82
82
|
'user_id': instance.user.id,
|
83
83
|
'transaction_type': instance.transaction_type,
|
84
|
-
'amount': instance.
|
84
|
+
'amount': instance.amount_usd,
|
85
85
|
'payment_id': str(instance.payment_id) if instance.payment_id else None
|
86
86
|
})
|
87
87
|
|
@@ -50,15 +50,21 @@ class SmartDefaults:
|
|
50
50
|
@staticmethod
|
51
51
|
def get_database_defaults(environment: str = "development", debug: bool = False, engine: str = "sqlite3") -> Dict[str, Any]:
|
52
52
|
"""Get database configuration defaults."""
|
53
|
-
|
53
|
+
defaults = {
|
54
54
|
'ENGINE': 'django.db.backends.sqlite3',
|
55
55
|
'NAME': Path('db') / 'db.sqlite3',
|
56
56
|
'ATOMIC_REQUESTS': True,
|
57
57
|
'CONN_MAX_AGE': 60,
|
58
|
-
'OPTIONS': {
|
59
|
-
'timeout': 20,
|
60
|
-
}
|
58
|
+
'OPTIONS': {}
|
61
59
|
}
|
60
|
+
|
61
|
+
# Add engine-specific options
|
62
|
+
if engine == "django.db.backends.postgresql":
|
63
|
+
defaults['OPTIONS']['connect_timeout'] = 20
|
64
|
+
elif engine == "django.db.backends.sqlite3":
|
65
|
+
defaults['OPTIONS']['timeout'] = 20 # SQLite uses 'timeout'
|
66
|
+
|
67
|
+
return defaults
|
62
68
|
|
63
69
|
@staticmethod
|
64
70
|
def get_cache_defaults() -> Dict[str, Any]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.3
|
4
4
|
Summary: 🚀 Next-gen Django configuration: type-safety, AI features, blazing-fast setup, and automated best practices — all in one.
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
6
6
|
Project-URL: Documentation, https://docs.djangocfg.com
|
@@ -1,5 +1,5 @@
|
|
1
1
|
django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
django_cfg/__init__.py,sha256=
|
2
|
+
django_cfg/__init__.py,sha256=tA-lxGDQpDFg-AcpBhuyA2sNdleuJjI4TbNJwxuQTWk,1630
|
3
3
|
django_cfg/apps.py,sha256=k84brkeXJI7EgKZLEpTkM9YFZofKI4PzhFOn1cl9Msc,1656
|
4
4
|
django_cfg/config.py,sha256=cbrtZxfXbI5p-qfdK5eR86OGxIbm4827zYdGIr6LmNg,1399
|
5
5
|
django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
|
@@ -297,8 +297,12 @@ django_cfg/apps/payments/config/constance/fields.py,sha256=v45-3ulrrxUesj9r3WEuX
|
|
297
297
|
django_cfg/apps/payments/config/constance/settings.py,sha256=PTzAPwbTV9FX8LwYY0OYkuvbWcIVU47XEeDqTbbbwv0,6854
|
298
298
|
django_cfg/apps/payments/management/__init__.py,sha256=1qi5wv2KVLIKoGVzItrB78D8xrbf3ruwO3_kGZ7bLh4,30
|
299
299
|
django_cfg/apps/payments/management/commands/__init__.py,sha256=1pri3qN5PLFIRSwxLkZJ7Bc4W4UyiKBZCcJjqy1IUr0,22
|
300
|
+
django_cfg/apps/payments/management/commands/cleanup_expired_data.py,sha256=fKvpSlCwaCiJorlN2vhnid-iUHAwsM3fHJfVB9uKKag,15168
|
301
|
+
django_cfg/apps/payments/management/commands/currency_stats.py,sha256=yftYm7edz1oxbP1xYR6CO0lR61YUSliOpJlw7tGMi7g,14974
|
300
302
|
django_cfg/apps/payments/management/commands/manage_currencies.py,sha256=yQjOl25wT3UUmA8uLKI-p4PE0adpxMAhy81TVid7ZDs,15339
|
301
303
|
django_cfg/apps/payments/management/commands/manage_providers.py,sha256=ojSvGOtjSLnZ8M0-WziC6qNd-sDrXnIzgm7YId7OnuU,15745
|
304
|
+
django_cfg/apps/payments/management/commands/process_pending_payments.py,sha256=yfmO9sRulGfZQi-tIdf2qWniCU1HhqtGxBY-j_N4UkM,13308
|
305
|
+
django_cfg/apps/payments/management/commands/test_providers.py,sha256=qpXTiKoErZBIXz2KtiWqa4IwWbK8c5WuABE2tDR_eGY,18475
|
302
306
|
django_cfg/apps/payments/middleware/__init__.py,sha256=eL5TmlCKmpW53Ift5rtwS8ss1wUqp4j2gzjGhcAQUQY,380
|
303
307
|
django_cfg/apps/payments/middleware/api_access.py,sha256=0UEHUNKjNKsewBNDMMNtOdywrj0w84fh0wbw-jjrvn4,15312
|
304
308
|
django_cfg/apps/payments/middleware/rate_limiting.py,sha256=U6mEyonU3JAK0LZjZqp-q4KgHnXdWpUJT4LJ1jCeQRQ,14813
|
@@ -307,26 +311,31 @@ django_cfg/apps/payments/migrations/0001_initial.py,sha256=DYi5gAC-4U7Mijrj_wKGu
|
|
307
311
|
django_cfg/apps/payments/migrations/__init__.py,sha256=OHlzxEGDJYKZz82orZXnh77xy-Okv6FcG3EKMfg9LzU,21
|
308
312
|
django_cfg/apps/payments/models/__init__.py,sha256=7x38zrZjYxH3tV079SthGZeIjuyNB5hbqirT03-ZxuE,1443
|
309
313
|
django_cfg/apps/payments/models/api_keys.py,sha256=dAS9XSOwAOBK40qnjrElz04Up9sqNGNg_0k13pnUjbs,5344
|
310
|
-
django_cfg/apps/payments/models/balance.py,sha256=
|
314
|
+
django_cfg/apps/payments/models/balance.py,sha256=esjkt-VIdWBu09eqxTwP5WmcGdI4aCbXSfjoTHwYZec,8084
|
311
315
|
django_cfg/apps/payments/models/base.py,sha256=XXMxqHe7OYmzVBW7g8nXgE41wJMigkRtgkPYGTx53oA,2212
|
312
316
|
django_cfg/apps/payments/models/currencies.py,sha256=6ONWpBoZUOFVIHGzj_j1LZsI0yRRhk1x9sNn6kINAA8,8458
|
313
317
|
django_cfg/apps/payments/models/payments.py,sha256=qvSBAl5YSqttZCAgaYCIyP23KiCJafzt0HZEJoAkNpg,11321
|
314
318
|
django_cfg/apps/payments/models/subscriptions.py,sha256=w2zUrybgsKGfQ2QO0QbWHPp5ZZshVrf013CyfKoxdVA,11037
|
315
319
|
django_cfg/apps/payments/models/tariffs.py,sha256=b2iDC7hBdZR8TX8aEskM5nTEa5_f0H6-j6wZdcbHdyk,6471
|
316
320
|
django_cfg/apps/payments/models/managers/__init__.py,sha256=56kdXtRJOLHhtnY4arYi15fEAmWWrWJP0F8kn8okpzU,1090
|
317
|
-
django_cfg/apps/payments/models/managers/api_key_managers.py,sha256=
|
318
|
-
django_cfg/apps/payments/models/managers/balance_managers.py,sha256=
|
321
|
+
django_cfg/apps/payments/models/managers/api_key_managers.py,sha256=LuSugGdivQ_3Cb_6feJKa2AHTKdH-vFD68mWKM3Kgb8,10428
|
322
|
+
django_cfg/apps/payments/models/managers/balance_managers.py,sha256=84iV5cfSWiETyfLXoSK_s6A1lRv_dsOxu_n6V57gbEY,20298
|
319
323
|
django_cfg/apps/payments/models/managers/currency_managers.py,sha256=ybLPx24rdnXo8jhCybq_3p5_si9BAhOSwIYib3tey-g,13061
|
320
324
|
django_cfg/apps/payments/models/managers/payment_managers.py,sha256=Hrkpk6N2bm8uxqNKFy7MTXg8W6-GVw5KMVNj4WYJ-9k,17547
|
321
|
-
django_cfg/apps/payments/models/managers/subscription_managers.py,sha256=
|
325
|
+
django_cfg/apps/payments/models/managers/subscription_managers.py,sha256=_hDmneMMTtvo2htNDDZOxuoYyxNKP46JC0MrXLwv5f8,21688
|
322
326
|
django_cfg/apps/payments/services/__init__.py,sha256=QUFVfTwliUvQWtaw0JqDss_LDamgNZwaej8fzL6Qzco,6147
|
323
327
|
django_cfg/apps/payments/services/cache/__init__.py,sha256=xIeDSSelNoS2eiWlIn-qsK9tYDizPJtVmBH1Ghc7wxk,353
|
324
|
-
django_cfg/apps/payments/services/
|
328
|
+
django_cfg/apps/payments/services/cache_service/__init__.py,sha256=Lp29sQUzuW7tKfrT6JBQYZgQ_ko4hqm2XozQ0XkC5Gc,4291
|
329
|
+
django_cfg/apps/payments/services/cache_service/api_key_cache.py,sha256=kVLUC5WbRpxXNGiKfcgnR7j4kBH861KpMTuGZJo8ADY,1292
|
330
|
+
django_cfg/apps/payments/services/cache_service/interfaces.py,sha256=7sqTRBSX4BPZ_Oxw6RJTyoLLHTLB5__adyNFZeAzjBI,758
|
331
|
+
django_cfg/apps/payments/services/cache_service/keys.py,sha256=U37Dwkboxn0E_B5MpfcY0RobIzhC5SQklE-jfkBMcOg,1700
|
332
|
+
django_cfg/apps/payments/services/cache_service/rate_limit_cache.py,sha256=MjFn5q23WjupNI2wZ9KpUJZR5TxX1zkYp6Cu1okZIfQ,1785
|
333
|
+
django_cfg/apps/payments/services/cache_service/simple_cache.py,sha256=aoAVHLfDUpAF0DP7UQYywGKjg8KzPjzu5xxMqRmN8zU,3258
|
325
334
|
django_cfg/apps/payments/services/core/__init__.py,sha256=CY2M4ID3rqcdpbokQSdO_fxtdCfHjsGgBsTznyGPw3k,526
|
326
335
|
django_cfg/apps/payments/services/core/balance_service.py,sha256=vNYJfRS_nsAzxq8aGmwp96Tj5UUgXBoNlMRwP45n9Jc,18212
|
327
336
|
django_cfg/apps/payments/services/core/base.py,sha256=BBOUWPx3dS7u7Ix7KaAyuacCTfXM9jympUuaRSGP4-M,5448
|
328
337
|
django_cfg/apps/payments/services/core/currency_service.py,sha256=1E6uX9rhJyycfktxunkHPD3nhCLWLchXZoVXiwjGiOM,18174
|
329
|
-
django_cfg/apps/payments/services/core/payment_service.py,sha256=
|
338
|
+
django_cfg/apps/payments/services/core/payment_service.py,sha256=X8-yXpBFnvfSVEidMrj42RRvQRZFSKu0cTTrRTtCU0s,18727
|
330
339
|
django_cfg/apps/payments/services/core/subscription_service.py,sha256=1kfxaW-BybIwQkbEpizxNJG_Egz6aF1qCVF2mX4v7Q4,21125
|
331
340
|
django_cfg/apps/payments/services/core/webhook_service.py,sha256=5Ly44QDUQJYm7V5xkOoKaPzobwf5MkLjFI6uamrpTY0,16222
|
332
341
|
django_cfg/apps/payments/services/integrations/__init__.py,sha256=sD48dDem1rqR8jALgrShBfm0-VMhvbK32q4_ufGElq8,663
|
@@ -342,8 +351,8 @@ django_cfg/apps/payments/services/types/requests.py,sha256=0s-5kPdtInnXJE_0lVUlI
|
|
342
351
|
django_cfg/apps/payments/services/types/responses.py,sha256=3FdyNOGQEoI8uZNjBPhhw1XtXqs-2lo02qZ5TQg-CqY,7947
|
343
352
|
django_cfg/apps/payments/services/types/webhooks.py,sha256=y7R1CoAZBRn71y9Mc8k6VVj5rjpbQ1ZHJkNHD1ZyK3M,10095
|
344
353
|
django_cfg/apps/payments/signals/__init__.py,sha256=rSso5kyUszEtlbYiw6A72XU2mK1gmB7O9n2lQb2GPWQ,933
|
345
|
-
django_cfg/apps/payments/signals/api_key_signals.py,sha256=
|
346
|
-
django_cfg/apps/payments/signals/balance_signals.py,sha256=
|
354
|
+
django_cfg/apps/payments/signals/api_key_signals.py,sha256=fR61t2mOAORD-ugWl4u6ZSP5nuykahnyIqh1uWjRnbY,8587
|
355
|
+
django_cfg/apps/payments/signals/balance_signals.py,sha256=ByPFzeMpNwo1vGmkeTg0bzLyAhaRPqVdgEvGayUN43Q,6002
|
347
356
|
django_cfg/apps/payments/signals/payment_signals.py,sha256=uV5v1HlHKxP4A_bpIC1TkTHkj28nEsP3gbRJx3ca0iI,5449
|
348
357
|
django_cfg/apps/payments/signals/subscription_signals.py,sha256=erzd3UczXGKamUecq2r2DeLm-0ycpFANy0nO948qmwg,9061
|
349
358
|
django_cfg/apps/payments/static/payments/css/components.css,sha256=CE9HL-pqlq1gvmluNIXh5-GvRvHLSYHRm-MVxURZO-I,8395
|
@@ -619,11 +628,11 @@ django_cfg/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
619
628
|
django_cfg/templatetags/django_cfg.py,sha256=11_3YX0jAVuOd_fVcDixAxyDMG4V7A98SPqv8Lbfpxc,1308
|
620
629
|
django_cfg/utils/__init__.py,sha256=64wwXJuXytvwt8Ze_erSR2HmV07nGWJ6DV5wloRBvYE,435
|
621
630
|
django_cfg/utils/path_resolution.py,sha256=C9As6p4Q9l3VeoVkFDRPQWGrzAWf8O8UxLVkaI3ToVM,13899
|
622
|
-
django_cfg/utils/smart_defaults.py,sha256=
|
631
|
+
django_cfg/utils/smart_defaults.py,sha256=Otmho1DGvuC8eaYgY3X6VA0okf8srYRyW6OQBonpEjE,9214
|
623
632
|
django_cfg/utils/toolkit.py,sha256=MfnjfGl2_VZo2o5aWIJaOYz2w45HQfOjO6X6nm5BJ8k,25312
|
624
633
|
django_cfg/utils/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaNpucs,4800
|
625
|
-
django_cfg-1.3.
|
626
|
-
django_cfg-1.3.
|
627
|
-
django_cfg-1.3.
|
628
|
-
django_cfg-1.3.
|
629
|
-
django_cfg-1.3.
|
634
|
+
django_cfg-1.3.3.dist-info/METADATA,sha256=ItziNnmUhaCQo35YUTrSoZ9nSJDk6MN9ZsehpFqbhNs,38740
|
635
|
+
django_cfg-1.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
636
|
+
django_cfg-1.3.3.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
637
|
+
django_cfg-1.3.3.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
638
|
+
django_cfg-1.3.3.dist-info/RECORD,,
|