-
Notifications
You must be signed in to change notification settings - Fork 656
Description
I am using the binance_sdk_derivatives_trading_usds_futures package. When consuming the User Data Stream, the SDK's websocket client returns a raw dict for UserDataStreamEventsResponse (as intended for oneOf types). However, when attempting to convert this dictionary into a Pydantic model using UserDataStreamEventsResponse.from_dict(), the operation fails with a ValueError: Multiple matches found.
Steps to Reproduce
- Subscribe to the User Data Stream via
DerivativesTradingUsdsFuturesWebSocketStreams. - Receive a standard event payload (e.g.,
ORDER_TRADE_UPDATE) in the callback. - Note: The callback receives a
dictbecause the SDK skips auto-deserialization foroneOfmodels inwebsocket.py. - Attempt to deserialize the payload manually:
import asyncio
from binance_sdk_derivatives_trading_usds_futures.derivatives_trading_usds_futures import DerivativesTradingUsdsFutures
from binance_sdk_derivatives_trading_usds_futures.websocket_streams.models.user_data_stream_events_response import UserDataStreamEventsResponse
client = DerivativesTradingUsdsFutures(...)
async def start_stream():
try:
connection = client.websocket_streams.create_connection()
user_stream = connection.user_data(listen_key)
user_stream.on("message", _on_ws_user_data_message)
except Exception as e:
logging.error(f"start_stream() error: {e}")
finally:
if connection:
await connection.close_connection(close_session=True)
def _on_ws_user_data_message(message: dict):
response = UserDataStreamEventsResponse.from_dict(message)
"""
# Error Msg
File "D:\test_project\.venv\lib\site-packages\binance_sdk_derivatives_trading_usds_futures\websocket_streams\models\user_data_stream_events_response.py", line 300, in from_json
raise ValueError(
ValueError: Multiple matches found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: AccountConfigUpdate, AccountUpdate, AlgoUpdate, ConditionalOrderTriggerReject, GridUpdate, Listenkeyexpired, MarginCall, OrderTradeUpdate, StrategyUpdate, TradeLite. Details: 1 validation error for Listenkeyexpired
E
Input should be a valid string [type=string_type, input_value=1766981401938, input_type=int]
"""
if __name__ == "__main__":
asyncio.run(start_stream())- The code raises a
ValueError
Observed Error
ValueError: Multiple matches found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: AccountConfigUpdate, AccountUpdate, AlgoUpdate...
Root Cause Analysis The issue lies in the generated from_json / from_dict logic within UserDataStreamEventsResponse combined with overly permissive schema definitions in this specific SDK (binance_sdk_derivatives_trading_usds_futures).
-
Brute-Force Matching: The
from_jsonmethod iterates through alloneOfcandidate models, attempting to validate the input against each one. -
Ambiguous Schemas (The "Wildcard" Problem): Several generated models in this package, such as
AccountConfigUpdateandStrategyUpdate, define all their fields asOptionaland includeadditional_properties.
Impact Users cannot strictly type-check or deserialize User Data Stream events using the provided SDK models. We are forced to implement manual discriminators (checking payload['e']) to bypass the SDK's broken deserialization logic.
Suggested Fix The UserDataStreamEventsResponse deserialization logic should use a discriminator (the e field in the JSON payload) to determine the correct target model, rather than relying on a brute-force trial that is prone to ambiguity.
Environment
- Package: binance_sdk_derivatives_trading_usds_futures=5.0.0
- Python Version: 3.10.11