2025-12-29 03:06:49 +08:00
|
|
|
"""
|
2026-04-06 16:47:36 +07:00
|
|
|
Database and cache configuration
|
2025-12-29 03:06:49 +08:00
|
|
|
"""
|
2026-04-09 14:30:51 +07:00
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
import os
|
|
|
|
|
|
2026-04-09 14:30:51 +07:00
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
class MetaRedisConfig(type):
|
2026-04-09 14:30:51 +07:00
|
|
|
"""Redis configuration"""
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def HOST(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return os.getenv("REDIS_HOST", "localhost")
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def PORT(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("REDIS_PORT", 6379))
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def PASSWORD(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return os.getenv("REDIS_PASSWORD", None)
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def DB(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("REDIS_DB", 0))
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def CONNECT_TIMEOUT(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("REDIS_CONNECT_TIMEOUT", 5))
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def SOCKET_TIMEOUT(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("REDIS_SOCKET_TIMEOUT", 5))
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@property
|
|
|
|
|
def MAX_CONNECTIONS(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("REDIS_MAX_CONNECTIONS", 10))
|
2025-12-29 03:06:49 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class RedisConfig(metaclass=MetaRedisConfig):
|
2026-04-06 16:47:36 +07:00
|
|
|
"""Redis cache configuration."""
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
@classmethod
|
|
|
|
|
def get_url(cls) -> str:
|
2026-04-06 16:47:36 +07:00
|
|
|
"""Get the Redis connection URL."""
|
2025-12-29 03:06:49 +08:00
|
|
|
if cls.PASSWORD:
|
|
|
|
|
return f"redis://:{cls.PASSWORD}@{cls.HOST}:{cls.PORT}/{cls.DB}"
|
|
|
|
|
return f"redis://{cls.HOST}:{cls.PORT}/{cls.DB}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class MetaCacheConfig(type):
|
2026-04-06 16:47:36 +07:00
|
|
|
"""Cache business configuration."""
|
|
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
def ENABLED(cls):
|
2026-04-06 16:47:36 +07:00
|
|
|
# Forced to be off by default unless explicitly enabled by an environment variable
|
2026-04-09 14:30:51 +07:00
|
|
|
return os.getenv("CACHE_ENABLED", "False").lower() == "true"
|
2025-12-29 03:06:49 +08:00
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def DEFAULT_EXPIRE(cls):
|
2026-04-09 14:30:51 +07:00
|
|
|
return int(os.getenv("CACHE_EXPIRE", 300))
|
2025-12-29 03:06:49 +08:00
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def KLINE_CACHE_TTL(cls):
|
|
|
|
|
return {
|
2026-04-09 14:30:51 +07:00
|
|
|
"1m": 5, # K-line cache for 1 minute and 5 seconds
|
|
|
|
|
"3m": 30, # 3 minutes K-line cache 30 seconds
|
|
|
|
|
"5m": 60, # 5 minutes K-line cache 1 minute
|
|
|
|
|
"15m": 300, # 15 minutes K-line cache 5 minutes
|
|
|
|
|
"30m": 300, # 30 minutes K-line cache 5 minutes
|
|
|
|
|
"1H": 300, # 1 hour K-line cache for 5 minutes
|
|
|
|
|
"4H": 300, # 4 hours K-line cache for 5 minutes
|
|
|
|
|
"1D": 300, # Daily K-line cache for 5 minutes
|
2026-04-06 16:47:36 +07:00
|
|
|
# Compatible with lowercase
|
2026-04-09 14:30:51 +07:00
|
|
|
"1h": 300,
|
|
|
|
|
"4h": 300,
|
|
|
|
|
"1d": 300,
|
2025-12-29 03:06:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def ANALYSIS_CACHE_TTL(cls):
|
|
|
|
|
return 3600
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def PRICE_CACHE_TTL(cls):
|
|
|
|
|
return 10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CacheConfig(metaclass=MetaCacheConfig):
|
2026-04-06 16:47:36 +07:00
|
|
|
"""Cache configuration."""
|
2026-04-09 14:30:51 +07:00
|
|
|
|
2025-12-29 03:06:49 +08:00
|
|
|
pass
|