-
Notifications
You must be signed in to change notification settings - Fork 663
Description
Description
The SymbolFilters oneOf model fails to populate the actual_instance field during deserialization in all versions >= 2.1.0 and loses all the information. This makes it impossible to access individual filter data (PriceFilter, LotSizeFilter, etc.) through the model's standard interface.
While ExchangeFilters was not the cleanest model however workable with in versions <= 2.0.0 SymbolFilters is not usable anymore.
Impact
Applications cannot access exchange filter data (filter type/instance, tick size, step size, min/max values, etc.)
Steps to Reproduce
import os
import logging
from binance_sdk_spot.spot import Spot, ConfigurationRestAPI, SPOT_REST_API_PROD_URL
# Configure logging
logging.basicConfig(level=logging.INFO)
# Create configuration for the REST API
configuration_rest_api = ConfigurationRestAPI(
api_key=os.getenv("API_KEY", ""),
api_secret=os.getenv("API_SECRET", ""),
base_path=os.getenv("BASE_PATH", SPOT_REST_API_PROD_URL),
)
# Initialize Spot client
client = Spot(config_rest_api=configuration_rest_api)
def exchange_info():
try:
response = client.rest_api.exchange_info()
rate_limits = response.rate_limits
logging.info(f"exchange_info() rate limits: {rate_limits}")
data = response.data()
logging.info(f"exchange_info() response: {data}")
# Try to access filter data
symbol_filter = exchange_info.symbols[0].filters[0]
print(f"actual_instance: {symbol_filter.actual_instance}")
# Expected: <PriceFilter object>
# Actual: None
# All validator fields are also None
print(f"oneof_schema_1_validator: {symbol_filter.oneof_schema_1_validator}")
# Expected: <PriceFilter object> or None (if not matching)
# Actual: None (always)
except Exception as e:
logging.error(f"exchange_info() error: {e}")
if __name__ == "__main__":
exchange_info()Expected Behavior
The SymbolFilters.actual_instance field should contain the parsed filter object (e.g., PriceFilter, LotSizeFilter, etc.) based on the filterType field in the JSON.
Example to possible expected outcome:
# For a PRICE_FILTER in the JSON
{
"filterType": "PRICE_FILTER",
"minPrice": "0.00001000",
"maxPrice": "922327.00000000",
"tickSize": "0.00001000"
}
# Should result in or something similar to:
filter_obj.actual_instance # <PriceFilter instance>
filter_obj.actual_instance.tick_size # "0.00001000"Actual Behavior
filter_obj.actual_instance # None
filter_obj.to_dict() # None
filter_obj.model_dump() # All validators are None
# Output:
{
'oneof_schema_1_validator': None,
'oneof_schema_2_validator': None,
# ... all 16 validators are None
'actual_instance': None
}Possible Root Cause
The SymbolFilters.from_dict() method attempts to deserialize into each possible filter type but fails to populate actual_instance when a match is found. The method increments match counter but doesn't store the successfully parsed instance.
Environment
- SDK Version: 2.1.0 through 6.0.0
- Python Version: 3.12.0
- OS: Windows 11 (but affects all platforms)
- binance-common Version: Tested with 2.0.0 and 3.3.0