11from datetime import date
22from decimal import Decimal
33import logging
4- from typing import Any
4+ from typing import Any , Callable , Dict
55
6- from pydantic import BaseModel , model_validator
6+ from pydantic import BaseModel , model_serializer , model_validator
77
88from kfinance .client .models .date_and_period_models import EstimatePeriodType , EstimateType
9- from kfinance .client .models .response_models import RespWithErrors
109
1110
1211logger = logging .getLogger (__name__ )
@@ -29,10 +28,20 @@ class Estimates(BaseModel):
2928 periods : dict [str , EstimatesPeriodData ]
3029
3130
32- class EstimatesResp (RespWithErrors ):
31+ class EstimatesResp (BaseModel ):
3332 """Response model for a single company's estimates."""
3433
3534 result : Estimates | None = None
35+ error : str | None = None
36+
37+ @model_serializer (mode = "wrap" )
38+ def serialize_model (self , handler : Callable ) -> Dict [str , Any ]:
39+ """Make `error` the last response field and only include if there is at least one error."""
40+ data = handler (self )
41+ error = data .pop ("error" )
42+ if error :
43+ data ["error" ] = error
44+ return data
3645
3746 @model_validator (mode = "before" )
3847 @classmethod
@@ -43,7 +52,11 @@ def from_post_response(cls, data: Any) -> Any:
4352 if len (results ) > 1 :
4453 logger .warning ("Expected at most one result, got %d" , len (results ))
4554 result = next (iter (results .values ()), None )
46- return {"result" : result , "errors" : data .get ("errors" , {})}
55+ errors = data .get ("errors" , {})
56+ if len (errors ) > 1 :
57+ logger .warning ("Expected at most one error, got %d" , len (errors ))
58+ error = next (iter (errors .values ()), None )
59+ return {"result" : result , "error" : error }
4760 return data
4861
4962
@@ -58,10 +71,20 @@ class ConsensusTargetPrice(BaseModel):
5871 estimates : list [ConsensusTargetPriceItem ]
5972
6073
61- class ConsensusTargetPriceResp (RespWithErrors ):
74+ class ConsensusTargetPriceResp (BaseModel ):
6275 """Response model for a single company's consensus target price."""
6376
6477 result : ConsensusTargetPrice | None = None
78+ error : str | None = None
79+
80+ @model_serializer (mode = "wrap" )
81+ def serialize_model (self , handler : Callable ) -> Dict [str , Any ]:
82+ """Make `error` the last response field and only include if there is at least one error."""
83+ data = handler (self )
84+ error = data .pop ("error" )
85+ if error :
86+ data ["error" ] = error
87+ return data
6588
6689 @model_validator (mode = "before" )
6790 @classmethod
@@ -72,7 +95,11 @@ def from_post_response(cls, data: Any) -> Any:
7295 if len (results ) > 1 :
7396 logger .warning ("Expected at most one result, got %d" , len (results ))
7497 result = next (iter (results .values ()), None )
75- return {"result" : result , "errors" : data .get ("errors" , {})}
98+ errors = data .get ("errors" , {})
99+ if len (errors ) > 1 :
100+ logger .warning ("Expected at most one error, got %d" , len (errors ))
101+ error = next (iter (errors .values ()), None )
102+ return {"result" : result , "error" : error }
76103 return data
77104
78105
@@ -86,10 +113,20 @@ class AnalystRecommendations(BaseModel):
86113 estimates : list [AnalystRecommendationsItem ]
87114
88115
89- class AnalystRecommendationsResp (RespWithErrors ):
116+ class AnalystRecommendationsResp (BaseModel ):
90117 """Response model for a single company's analyst recommendations."""
91118
92119 result : AnalystRecommendations | None = None
120+ error : str | None = None
121+
122+ @model_serializer (mode = "wrap" )
123+ def serialize_model (self , handler : Callable ) -> Dict [str , Any ]:
124+ """Make `error` the last response field and only include if there is at least one error."""
125+ data = handler (self )
126+ error = data .pop ("error" )
127+ if error :
128+ data ["error" ] = error
129+ return data
93130
94131 @model_validator (mode = "before" )
95132 @classmethod
@@ -100,5 +137,9 @@ def from_post_response(cls, data: Any) -> Any:
100137 if len (results ) > 1 :
101138 logger .warning ("Expected at most one result, got %d" , len (results ))
102139 result = next (iter (results .values ()), None )
103- return {"result" : result , "errors" : data .get ("errors" , {})}
140+ errors = data .get ("errors" , {})
141+ if len (errors ) > 1 :
142+ logger .warning ("Expected at most one error, got %d" , len (errors ))
143+ error = next (iter (errors .values ()), None )
144+ return {"result" : result , "error" : error }
104145 return data
0 commit comments