22from typing import Dict , Any , Optional , Type , List , Union , Tuple , get_origin , get_args , Literal
33from datetime import datetime
44import typing_inspect
5+ from dataclasses import fields , is_dataclass
56
67from ..configs import *
78from ..utils .validate_fields import validate_field_string , build_id_field_string
@@ -213,6 +214,7 @@ def process_model(model: Type, data: Dict[str, Any]) -> Tuple[Dict[str, Any], Di
213214 errors = {}
214215
215216 for field_name , field_type in model .__annotations__ .items ():
217+ print (field_name , field_type )
216218 # Use the provided field name for validation; apply mappings after validation
217219 original_field_name = field_name
218220 mapped_field_name = MAPPINGS .get (field_name , field_name )
@@ -330,22 +332,50 @@ def _call_endpoint(self, metadata: dict, **kwargs):
330332 field_model = metadata .get ("field_model" )
331333 method = metadata ["method" ].upper ()
332334
335+ use_field_model_for_fields = True # default
336+
337+ # If request_body_model exists, check if it has a field named 'fields'
338+ if request_body_model and "fields" in kwargs :
339+ for f in fields (request_body_model ):
340+ # Check top-level
341+ if f .name == "fields" :
342+ use_field_model_for_fields = False
343+ break
344+
345+ # Check nested dataclass
346+ if is_dataclass (f .type ):
347+ nested_names = [sub_f .name for sub_f in fields (f .type )]
348+ if "fields" in nested_names :
349+ use_field_model_for_fields = False
350+ break
351+
352+ print ("Use field model for 'fields'? ->" , use_field_model_for_fields )
353+
333354 path = self ._format_path (path , kwargs )
334355
335356 query_params = {}
336357 validation_errors = {"query" : {}, "data" : {}}
337358
338- if field_model and "fields" in kwargs . keys () :
359+ if field_model and "fields" in kwargs and use_field_model_for_fields :
339360 field_string = kwargs ["fields" ]
340361 if field_string == "all_ids" :
341362 kwargs ["fields" ] = build_id_field_string (field_model )
342363 else :
343364 response = validate_field_string (field_model , field_string )
344365 kwargs ["fields" ] = response .get ("valid_string" )
345366
367+ # Validate 'response_fields' if provided, but only if we are NOT using the field model
368+ if "response_fields" in kwargs and not use_field_model_for_fields :
369+ field_string = kwargs ["response_fields" ]
370+ response = validate_field_string (field_model , field_string )
371+ kwargs ["response_fields" ] = response .get ("valid_string" )
372+
346373 # Validate query parameters
347374 if query_model :
348375 for field , field_type in query_model .__annotations__ .items ():
376+ if field == "fields" and not use_field_model_for_fields :
377+ continue
378+
349379 mapped_field = MAPPINGS .get (field , field )
350380
351381 value = kwargs .pop (mapped_field , kwargs .pop (field , None ))
@@ -369,7 +399,12 @@ def _call_endpoint(self, metadata: dict, **kwargs):
369399 payload = payload_result .get ("payload" )
370400 if payload_result .get ("errors" ):
371401 validation_errors ["data" ].update (payload_result ["errors" ])
372-
402+
403+ # Reinject response_fields into query_params if present as "fields"
404+ response_fields = kwargs .get ("response_fields" )
405+ if response_fields :
406+ query_params ["fields" ] = response_fields
407+
373408 # If there are validation errors, return them
374409 if validation_errors ["query" ] or validation_errors ["data" ]:
375410 return {
@@ -380,8 +415,9 @@ def _call_endpoint(self, metadata: dict, **kwargs):
380415 "errors" : validation_errors ,
381416 }
382417
383- url = BaseRequest .format_url (BaseRequest (self .base_url , self .base_path ), path , query_params )
384- return self .request_handler (url , method , query_params , payload , ** kwargs )
418+ api_url = BaseRequest .format_url (BaseRequest (self .base_url , self .base_path ), path , query_params )
419+
420+ return self .request_handler (api_url , method , query_params , payload , ** kwargs )
385421
386422 def __getattr__ (self , method_type : str ):
387423 """
0 commit comments