fix: ensure DB credentials are explicitly passed and verified (v1.5.3)

This commit is contained in:
Gemini CLI
2026-03-05 23:26:59 +01:00
parent 58070550a5
commit 8b076106dc

View File

@ -41,37 +41,56 @@ logger = logging.getLogger("PingPongBot")
class DatabaseManager: class DatabaseManager:
"""Minimal Database Manager for the bot""" """Minimal Database Manager for the bot"""
def __init__(self): def __init__(self, host, port, database, user, password):
self.host = os.getenv('DB_HOST', '20.20.20.20') self.host = host
self.port = int(os.getenv('DB_PORT', 5433)) self.port = int(port)
self.database = os.getenv('DB_NAME', 'btc_data') self.database = database
self.user = os.getenv('DB_USER', 'btc_bot') self.user = user
self.password = os.getenv('DB_PASSWORD', '') self.password = password
self.pool = None self.pool = None
async def connect(self): async def connect(self):
self.pool = await asyncpg.create_pool( try:
host=self.host, port=self.port, user=self.user, self.pool = await asyncpg.create_pool(
password=self.password, database=self.database host=self.host, port=self.port, user=self.user,
) password=self.password, database=self.database,
logger.info("Connected to Database") min_size=1, max_size=10
)
# Test connection
async with self.pool.acquire() as conn:
res = await conn.fetchval("SELECT 1")
if res == 1:
logger.info(f"Database connection verified at {self.host}:{self.port}")
else:
raise Exception("Database test query failed")
except Exception as e:
logger.error(f"DATABASE CONNECTION FAILED: {e}")
raise
async def get_candles(self, symbol: str, interval: str, limit: int = 100): async def get_candles(self, symbol: str, interval: str, limit: int = 100):
async with self.pool.acquire() as conn: if not self.pool:
rows = await conn.fetch(''' logger.error("Attempted to query DB before connecting")
SELECT time, open, high, low, close, volume return []
FROM candles try:
WHERE symbol = $1 AND interval = $2 async with self.pool.acquire() as conn:
ORDER BY time DESC LIMIT $3 rows = await conn.fetch('''
''', symbol, interval, limit) SELECT time, open, high, low, close, volume
return [dict(r) for r in rows] FROM candles
WHERE symbol = $1 AND interval = $2
ORDER BY time DESC LIMIT $3
''', symbol, interval, limit)
return [dict(r) for r in rows]
except Exception as e:
logger.error(f"DB Query Error for {symbol} {interval}: {e}")
return []
class PingPongBot: class PingPongBot:
def __init__(self, config_path="config/ping_pong_config.yaml"): def __init__(self, config_path="config/ping_pong_config.yaml"):
self.version = "1.5.2" self.version = "1.5.3"
with open(config_path, 'r') as f: with open(config_path, 'r') as f:
self.config = yaml.safe_load(f) self.config = yaml.safe_load(f)
# Explicitly load from ENV to ensure they are available
self.api_key = os.getenv("BYBIT_API_KEY") or os.getenv("API_KEY") self.api_key = os.getenv("BYBIT_API_KEY") or os.getenv("API_KEY")
self.api_secret = os.getenv("BYBIT_API_SECRET") or os.getenv("API_SECRET") self.api_secret = os.getenv("BYBIT_API_SECRET") or os.getenv("API_SECRET")
@ -85,7 +104,14 @@ class PingPongBot:
timeout=10 timeout=10
) )
self.db = DatabaseManager() # Initialize DB with explicit credentials
self.db = DatabaseManager(
host=os.getenv('DB_HOST', '20.20.20.20'),
port=os.getenv('DB_PORT', 5433),
database=os.getenv('DB_NAME', 'btc_data'),
user=os.getenv('DB_USER', 'btc_bot'),
password=os.getenv('DB_PASSWORD', '')
)
# Base settings # Base settings
self.base_coin = self.config['symbol'].upper().replace("USDT", "").replace("USDC", "") # e.g. BTC self.base_coin = self.config['symbol'].upper().replace("USDT", "").replace("USDC", "") # e.g. BTC
@ -188,11 +214,14 @@ class PingPongBot:
logger.info(f"DIRECTION CHANGE: {self.direction} -> {new_direction} (Price: {current_price:.2f}, MA44: {self.ma_44_val:.2f})") logger.info(f"DIRECTION CHANGE: {self.direction} -> {new_direction} (Price: {current_price:.2f}, MA44: {self.ma_44_val:.2f})")
self.status_msg = f"Switching to {new_direction.upper()}" self.status_msg = f"Switching to {new_direction.upper()}"
# 1. Close all positions (Point III.3)
if self.direction is not None: if self.direction is not None:
await self.close_all_positions() await self.close_all_positions()
# 2. Swap Assets on Spot (Point II)
await self.swap_assets(new_direction) await self.swap_assets(new_direction)
# 3. Update configuration
self.direction = new_direction self.direction = new_direction
if self.direction == "long": if self.direction == "long":
self.category = "inverse" self.category = "inverse"
@ -202,7 +231,7 @@ class PingPongBot:
self.symbol = f"{self.base_coin}USDC" self.symbol = f"{self.base_coin}USDC"
logger.info(f"Bot configured for {self.direction.upper()} | Symbol: {self.symbol} | Category: {self.category}") logger.info(f"Bot configured for {self.direction.upper()} | Symbol: {self.symbol} | Category: {self.category}")
self.last_candle_time = None self.last_candle_time = None # Force indicator recalculation
return True return True
return False return False
@ -265,8 +294,8 @@ class PingPongBot:
if ticker['retCode'] == 0: if ticker['retCode'] == 0:
self.market_price = float(ticker['result']['list'][0]['lastPrice']) self.market_price = float(ticker['result']['list'][0]['lastPrice'])
# settleCoin is only for linear perpetuals # settleCoin is only for USDC linear perpetuals
settle_coin = "USDC" if self.category == "linear" else None settle_coin = "USDC" if (self.category == "linear" and "USDC" in self.symbol) else None
pos = await asyncio.to_thread(self.session.get_positions, category=self.category, symbol=self.symbol, settleCoin=settle_coin) pos = await asyncio.to_thread(self.session.get_positions, category=self.category, symbol=self.symbol, settleCoin=settle_coin)
if pos['retCode'] == 0: if pos['retCode'] == 0:
active = [p for p in pos['result']['list'] if float(p.get('size', 0)) > 0] active = [p for p in pos['result']['list'] if float(p.get('size', 0)) > 0]
@ -376,8 +405,12 @@ class PingPongBot:
self.console.print("="*60 + "\n") self.console.print("="*60 + "\n")
async def run(self): async def run(self):
await self.db.connect() try:
await self.update_direction() await self.db.connect()
await self.update_direction()
except Exception as e:
logger.error(f"Startup Failure: {e}")
return
last_exchange_update = 0 last_exchange_update = 0
while True: while True: