11import urllib3
22urllib3 .disable_warnings (urllib3 .exceptions .InsecureRequestWarning )
3- from typing import Type , TypeVar
3+ from typing import Type , TypeVar , get_args , get_origin
44import certifi
55from pydantic import BaseModel
66import requests
@@ -61,6 +61,63 @@ def _request(self, method: str, endpoint: str, **kwargs) -> requests.Response:
6161
6262 return response
6363
64+ # def _process_response(self, response: requests.Response, response_model: Type[T]) -> ApiResponse[T]:
65+ # status_code = response.status_code
66+ # raw_content = response.text
67+
68+ # try:
69+ # response_data = response.json()
70+ # except ValueError:
71+ # return ApiResponse[T](
72+ # succeeded=False,
73+ # http_status_code=status_code,
74+ # message="Error processing server response",
75+ # details=raw_content,
76+ # data=None
77+ # )
78+
79+ # if 200 <= status_code < 300:
80+
81+ # if issubclass(response_model, BaseModel) and isinstance(response_data["data"], dict):
82+ # response_data["data"] = response_model.model_validate(response_data["data"])
83+
84+ # return ApiResponse[T].model_validate(response_data)
85+
86+ # try:
87+ # generic_error = ApiResponse[object].model_validate(response_data)
88+ # except Exception:
89+ # return ApiResponse[T](
90+ # succeeded=False,
91+ # http_status_code=status_code,
92+ # message="Error processing server error response",
93+ # details=raw_content,
94+ # data=None
95+ # )
96+
97+ # if status_code == 400 and isinstance(response_data.get("data"), list):
98+ # try:
99+ # failures = [ValidationFailure.model_validate(item) for item in response_data["data"]]
100+ # if failures:
101+ # details_str = "; ".join(f"{f.propertyName}: {f.errorMessage}" for f in failures)
102+ # return ApiResponse[T](
103+ # succeeded=False,
104+ # http_status_code=400,
105+ # message=generic_error.message,
106+ # details=details_str,
107+ # data=None
108+ # )
109+ # except Exception:
110+ # pass
111+
112+ # return ApiResponse[T](
113+ # succeeded=False,
114+ # http_status_code=status_code,
115+ # message=generic_error.message or f"HTTP Error {status_code}",
116+ # details=generic_error.details or raw_content,
117+ # data=None
118+ # )
119+
120+
64121 def _process_response (self , response : requests .Response , response_model : Type [T ]) -> ApiResponse [T ]:
65122 status_code = response .status_code
66123 raw_content = response .text
@@ -77,12 +134,30 @@ def _process_response(self, response: requests.Response, response_model: Type[T]
77134 )
78135
79136 if 200 <= status_code < 300 :
80-
81- if issubclass (response_model , BaseModel ) and isinstance (response_data ["data" ], dict ):
82- response_data ["data" ] = response_model .model_validate (response_data ["data" ])
83-
137+ # -- Manejo de data con modelos pydantic o lista de modelos pydantic
138+ origin = get_origin (response_model )
139+ if origin == list :
140+ # Significa que es algo como list[TaxFile]
141+ (model_type ,) = get_args (response_model )
142+ # Validar cada elemento de la lista si data es una lista
143+ if issubclass (model_type , BaseModel ) and isinstance (response_data ["data" ], list ):
144+ response_data ["data" ] = [
145+ model_type .model_validate (item )
146+ for item in response_data ["data" ]
147+ ]
148+ else :
149+ # Manejo de caso donde response_model es un modelo Pydantic "simple"
150+ if (
151+ isinstance (response_model , type )
152+ and issubclass (response_model , BaseModel )
153+ and isinstance (response_data ["data" ], dict )
154+ ):
155+ response_data ["data" ] = response_model .model_validate (response_data ["data" ])
156+
157+ # Finalmente se parsea la respuesta como ApiResponse[T]
84158 return ApiResponse [T ].model_validate (response_data )
85159
160+ # -- Manejo de respuestas de error --
86161 try :
87162 generic_error = ApiResponse [object ].model_validate (response_data )
88163 except Exception :
@@ -116,12 +191,16 @@ def _process_response(self, response: requests.Response, response_model: Type[T]
116191 details = generic_error .details or raw_content ,
117192 data = None
118193 )
119-
194+
195+
196+
120197 def send_request (self , method : str , endpoint : str , response_model : Type [T ], ** kwargs ) -> ApiResponse [T ]:
121198 payload = kwargs .pop ("payload" , None )
122199 if payload is not None and isinstance (payload , BaseModel ):
123200 # Excluir propiedades con valor None
124201 kwargs ["json" ] = payload .model_dump (mode = "json" , by_alias = True , exclude_none = True )
125202
126203 response = self ._request (method , endpoint , ** kwargs )
127- return self ._process_response (response , response_model )
204+ return self ._process_response (response , response_model )
205+
206+
0 commit comments