025-11-10 14:13:06 - main - INFO -
Starting continuous risk monitoring
2025-11-10 14:13:07,129 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:07,162 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:10 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:07 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:10 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
2025-11-10 14:13:07,708 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:07,709 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:11 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:08 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:11 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
2025-11-10 14:13:08,963 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:08,964 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:12 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:09 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:12 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
2025-11-10 14:13:11,201 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:11,204 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:15 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:12 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:15 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
2025-11-10 14:13:12,448 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:12,448 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:16 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:13 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:16 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
2025-11-10 14:13:13,598 - WebSocketMarketDataManager - ERROR -
[FIXED] === EVENT: WebSocket error ===
2025-11-10 14:13:13,599 - WebSocketMarketDataManager - ERROR -
[FIXED] Error: Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:17 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None
2025-11-10 14:13:13 - websocket - ERROR - Handshake status 403 Forbidden -±± {‘date’: ‘Mon, 10 Nov 2025 08:43:17 GMT’, ‘transfer-encoding’: ‘chunked’, ‘connection’: ‘keep-alive’} -±± None - goodbye
async def initialize_websocket_connection_fixed(self) → bool:
“”"
FIXED: Correct WebSocket implementation - NO 'Bearer ’ prefix for WebSocket
“”"
try:
self.logger.info(“
[FIXED] === START: WebSocket initialization - NO BEARER PREFIX ===”)
# 🚨 CRITICAL: Use direct token loading as shown in examples
from _01_login import load_access_token
self.logger.info("🔍 [FIXED] Step 1: Loading access token...")
access_token = load_access_token()
self.logger.info(f"🔍 [FIXED] load_access_token() returned: {type(access_token)}")
if not access_token:
self.logger.error("❌ [FIXED] FAIL: Cannot load access token - token is None or empty")
return False
# 🚨🚨🚨 CRITICAL FIX: REMOVE 'Bearer ' prefix for WebSocket
self.logger.info(f"🔍 [FIXED] Original token length: {len(access_token)}")
self.logger.info(f"🔍 [FIXED] Original token starts with 'Bearer ': {access_token.startswith('Bearer ')}")
# 🚨 IMPORTANT: WebSocket requires token WITHOUT 'Bearer ' prefix
if access_token.startswith('Bearer '):
self.logger.warning("⚠️ [FIXED] Token has 'Bearer ' prefix - REMOVING it for WebSocket")
final_token = access_token.replace('Bearer ', '')
self.logger.info("✅ [FIXED] Removed 'Bearer ' prefix from token")
else:
self.logger.info("✅ [FIXED] Token already without 'Bearer ' prefix - using as-is")
final_token = access_token
self.logger.info(f"✅ [FIXED] Final token length: {len(final_token)} characters")
self.logger.info(f"🔍 [FIXED] Final token first 50 chars: '{final_token[:50]}'")
self.logger.info(f"🔍 [FIXED] Final token starts with 'Bearer ': {final_token.startswith('Bearer ')}")
# ✅ CORRECT: Create configuration exactly like SDK examples
self.logger.info("🔍 [FIXED] Step 2: Creating configuration...")
configuration = upstox_client.Configuration()
configuration.access_token = final_token
self.logger.info(f"✅ [FIXED] Configuration access_token set: {bool(configuration.access_token)}")
# ✅ CORRECT: Create API client with configuration
self.logger.info("🔍 [FIXED] Step 3: Creating API client...")
api_client = upstox_client.ApiClient(configuration)
self.logger.info(f"✅ [FIXED] API client created: {api_client is not None}")
# 🔍 Validate instrument keys
self.logger.info("🔍 [FIXED] Step 4: Validating instrument keys...")
valid_instruments = []
for i, instrument in enumerate(self.instrument_keys):
if isinstance(instrument, str) and '|' in instrument:
valid_instruments.append(instrument)
self.logger.info(f"✅ [FIXED] Instrument {i+1} VALID: '{instrument}'")
else:
self.logger.error(f"❌ [FIXED] Instrument {i+1} INVALID: '{instrument}'")
if not valid_instruments:
self.logger.error("❌ [FIXED] No valid instruments found")
return False
self.logger.info(f"🔍 [FIXED] Subscription mode: '{self.subscription_mode}'")
self.logger.info(f"📡 [FIXED] Creating MarketDataStreamerV3 for {len(valid_instruments)} instruments")
try:
# ✅ CORRECT: Initialize streamer with validated parameters
self.streamer_v3 = upstox_client.MarketDataStreamerV3(
api_client,
valid_instruments,
self.subscription_mode
)
self.logger.info("✅ [FIXED] MarketDataStreamerV3 created successfully")
except Exception as e:
self.logger.error(f"❌ [FIXED] FAIL: Failed to create MarketDataStreamerV3: {e}")
return False
# 🚨 CRITICAL: Register handlers BEFORE connecting
self.logger.info("🔍 [FIXED] Step 5: Setting up event handlers...")
connection_established = asyncio.Event()
def on_open():
self.logger.info("✅ [FIXED] === EVENT: WebSocket on_open triggered ===")
self.logger.info("✅ [FIXED] WebSocket connection established!")
self.is_connected = True
connection_established.set()
def on_message(message):
try:
self._message_counter += 1
if self._message_counter <= 5:
self.logger.info(f"📨 [FIXED] Message #{self._message_counter} received")
self._handle_market_data_message(message)
except Exception as e:
self.logger.error(f"❌ [FIXED] Message handling error: {e}")
def on_error(error):
error_str = str(error)
self.logger.error(f"💥 [FIXED] === EVENT: WebSocket error ===")
self.logger.error(f"💥 [FIXED] Error: {error_str}")
# 🚨 ENHANCED ERROR ANALYSIS
if "401" in error_str or "Unauthorized" in error_str:
self.logger.error("🔐 [FIXED] === 401 UNAUTHORIZED ===")
self.logger.error("🔐 [FIXED] Token authentication failed")
self.logger.error(f"🔐 [FIXED] Token length: {len(final_token)}")
self.logger.error(f"🔐 [FIXED] Has 'Bearer ' prefix: {final_token.startswith('Bearer ')}")
self.logger.error("🔐 [FIXED] Try: Refresh token or check WebSocket permissions")
self.is_connected = False
def on_close(code=None, reason=None):
self.logger.info(f"🔴 [FIXED] WebSocket closed: {code} - {reason}")
self.is_connected = False
# Register handlers
try:
self.streamer_v3.on("open", on_open)
self.streamer_v3.on("message", on_message)
self.streamer_v3.on("error", on_error)
self.streamer_v3.on("close", on_close)
self.logger.info("✅ [FIXED] Event handlers registered")
except Exception as e:
self.logger.error(f"❌ [FIXED] Handler registration failed: {e}")
return False
# Connect
self.logger.info("🔗 [FIXED] Step 6: Connecting WebSocket...")
try:
self.streamer_v3.connect()
self.logger.info("✅ [FIXED] connect() called")
# Wait for connection
self.logger.info("⏳ [FIXED] Waiting for connection...")
await connection_established.wait()
self.logger.info("✅ [FIXED] WebSocket connected successfully!")
# Wait for initial messages
await asyncio.sleep(3)
self.logger.info(f"📨 [FIXED] Messages received: {self._message_counter}")
return True
except Exception as e:
self.logger.error(f"❌ [FIXED] Connection failed: {e}")
return False
except Exception as e:
self.logger.error(f"💥 [FIXED] Initialization failed: {e}")
return False