model_validate override for models #492
Open
+35
−8
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
This PR addresses deserialization issues #477 #476 #405 with schema models in both REST and WebSocket APIs. The changes ensure that Pydantic's
model_validate()method properly handles discriminated unions by delegating to customfrom_dict()logic.Problem Statement
The codebase uses oneOf schemas extensively for filter types (SymbolFilters, ExchangeFilters, AssetFilters) and user data stream events (ExecutionReport, BalanceUpdate, etc.). These models have custom deserialization logic in their
from_dict()methods that handles discriminator-based type resolution.However, several code paths use
model_validate()instead offrom_dict():Models do not evaluate to a
one_of_modeland takte themodel_validatebranchbinance-connector-python/common/src/binance_common/utils.py
Lines 396 to 408 in 5725647
same as under the Rest Api
binance-connector-python/common/src/binance_common/websocket.py
Lines 846 to 853 in 5725647
binance-connector-python/common/src/binance_common/websocket.py
Lines 245 to 254 in 5725647
parse_user_event()
binance-connector-python/common/src/binance_common/utils.py
Lines 765 to 771 in 5725647
When Pydantic's native
model_validate()is called on models, it bypasses the custom discriminator logic infrom_dict(), resulting inactual_instance=Noneand failed deserialization.Root Cause
Pydantic v2's
model_validate()andfrom_dict()take different routes:from_dict(): Executes custom logic → discriminator resolution → proper type instantiationmodel_validate(): Uses Pydantic's native validation → bypasses custom discriminator logic → fails for oneOf**dataunpacking: Constructs model directly → no validation or custom logicThe issue occurs because the response handling code calls
model_validate(parsed_dict), but the models needfrom_dict(parsed_dict)to work correctly. The Models are not recognised as oneOf models.Solution
1. Override
model_validate()in ModelsAdd a
model_validate()class method that intercepts dictionary inputs and delegates tofrom_dict():Files Modified:
Implementation:
2. Override
model_validate()in Parent Response ModelsSince
ExchangeInfoResponsecontains nested oneOf filter models, it also needs the override to ensure nested deserialization works correctly:Files Modified:
Implementation:
Important: The
from_dict()method must callsuper().model_validate()(notcls.model_validate()) to avoid infinite recursion:Impact
Fixed Code Paths
from_dict()andmodel_validate()callsExecutionReport,BalanceUpdate, etc. now resolve to correct types inreceive_loop()Test Coverage
All test cases now pass:
parse_user_event()Why This Approach?
This solution maintains backward compatibility while fixing the core issue:
from_dict()still works exactly as beforemodel_validate()now "just works" for modelsfrom_dictandmodel_validate) now produce identical resultsmodel_validate()will automatically get correct behaviorAlternative Implementation
The alternative to overwriting the model_validate() for those models could be to ensure that they are recognised by
is_one_of()so that for websocket and rest api it would take thefrom_dict(). However this would not work on the UserDataStream events in parse_user_event() as there is not OneOf Validation