@@ -88,9 +88,8 @@ async def _execute(
8888 ) -> Any :
8989 """Shared executor for all API endpoint methods.
9090
91- Delegates to _execute_api_request_internal (or
92- _execute_streamed_api_request_internal when _streaming=True) so all
93- API calls share one unified code path.
91+ Delegates to the public execute_api_request / execute_streamed_api_request
92+ so all API calls share one unified code path.
9493 """
9594 if options is None :
9695 options = {}
@@ -118,7 +117,7 @@ async def _execute(
118117 )
119118
120119 if options .get ("_streaming" , False ):
121- return self ._execute_streamed_api_request_internal (
120+ return self .execute_streamed_api_request (
122121 operation_name = operation_name ,
123122 method = method ,
124123 path = path ,
@@ -128,9 +127,10 @@ async def _execute(
128127 options = options ,
129128 response_types_map = response_types_map ,
130129 telemetry_attributes = telemetry_attributes ,
130+ _skip_builder = True ,
131131 )
132132
133- return await self ._execute_api_request_internal (
133+ return await self .execute_api_request (
134134 operation_name = operation_name ,
135135 method = method ,
136136 path = path ,
@@ -151,16 +151,22 @@ async def execute_api_request(
151151 path : str ,
152152 path_params : dict [str , str ] | None = None ,
153153 body : dict [str , Any ] | list [Any ] | str | bytes | None = None ,
154- query_params : dict [str , str | int | list [str | int ]] | None = None ,
154+ query_params : dict [str , str | int | list [str | int ]] | list | None = None ,
155155 headers : dict [str , str ] | None = None ,
156156 options : dict [str , Any ] | None = None ,
157- ) -> RawResponse :
157+ response_types_map : dict | None = None ,
158+ telemetry_attributes : dict | None = None ,
159+ _skip_builder : bool = False ,
160+ ) -> Any :
158161 """
159162 Execute an arbitrary HTTP request to any OpenFGA API endpoint.
160163
161164 Useful for calling endpoints not yet wrapped by the SDK while
162165 still getting authentication, retries, and error handling.
163166
167+ When called directly by users, returns a RawResponse.
168+ When called internally with response_types_map, returns a deserialized typed model.
169+
164170 :param operation_name: Operation name for telemetry (e.g., "CustomCheck")
165171 :param method: HTTP method (GET, POST, PUT, DELETE, PATCH)
166172 :param path: API path, e.g. "/stores/{store_id}/my-endpoint".
@@ -170,92 +176,26 @@ async def execute_api_request(
170176 :param query_params: Query string parameters
171177 :param headers: Custom headers (SDK enforces Content-Type and Accept)
172178 :param options: Extra options e.g. {"retry_params": RetryParams(max_retry=3)}
173- :return: RawResponse with status, headers, and body
179+ :param response_types_map: When provided, merge with common error types and
180+ return a deserialized typed model. When None, return RawResponse.
181+ :param telemetry_attributes: When provided, use as-is for telemetry.
182+ When None, build minimal defaults.
183+ :param _skip_builder: When True, path/headers/query_params are used as-is
184+ (already resolved by _execute). When False (default), run through
185+ ExecuteApiRequestBuilder.
186+ :return: RawResponse (public callers) or deserialized model (internal callers)
174187 """
175- return await self ._execute_api_request_internal (
176- operation_name = operation_name ,
177- method = method ,
178- path = path ,
179- path_params = path_params ,
180- body = body ,
181- query_params = query_params ,
182- headers = headers ,
183- options = options ,
188+ from openfga_sdk .client .execute_api_request_builder import (
189+ ExecuteApiRequestBuilder ,
190+ ResponseParser ,
184191 )
192+ from openfga_sdk .client .models .raw_response import RawResponse
185193
186- async def execute_streamed_api_request (
187- self ,
188- * ,
189- operation_name : str ,
190- method : str ,
191- path : str ,
192- path_params : dict [str , str ] | None = None ,
193- body : dict [str , Any ] | list [Any ] | str | bytes | None = None ,
194- query_params : dict [str , str | int | list [str | int ]] | None = None ,
195- headers : dict [str , str ] | None = None ,
196- options : dict [str , Any ] | None = None ,
197- ) -> AsyncIterator [dict [str , Any ]]:
198- """
199- Execute an arbitrary HTTP request to a streaming OpenFGA API endpoint.
200-
201- Yields parsed JSON objects as they arrive. Use with async for:
202-
203- async for chunk in api.execute_streamed_api_request(...):
204- process(chunk)
205-
206- :param operation_name: Operation name for telemetry (e.g., "StreamedListObjects")
207- :param method: HTTP method (GET, POST, PUT, DELETE, PATCH)
208- :param path: API path, e.g. "/stores/{store_id}/streamed-list-objects".
209- :param path_params: Path parameter substitutions (URL-encoded automatically).
210- All path parameters, including store_id, must be provided explicitly.
211- :param body: Request body for POST/PUT/PATCH
212- :param query_params: Query string parameters
213- :param headers: Custom headers (SDK enforces Content-Type and Accept)
214- :param options: Extra options e.g. {"retry_params": RetryParams(max_retry=3)}
215- """
216- async for chunk in self ._execute_streamed_api_request_internal (
217- operation_name = operation_name ,
218- method = method ,
219- path = path ,
220- path_params = path_params ,
221- body = body ,
222- query_params = query_params ,
223- headers = headers ,
224- options = options ,
225- ):
226- yield chunk
227-
228- async def _execute_streamed_api_request_internal (
229- self ,
230- * ,
231- operation_name : str ,
232- method : str ,
233- path : str ,
234- path_params : dict [str , str ] | None = None ,
235- body : dict [str , Any ] | list [Any ] | str | bytes | None = None ,
236- query_params = None ,
237- headers = None ,
238- options : dict [str , Any ] | None = None ,
239- response_types_map : dict | None = None ,
240- telemetry_attributes : dict | None = None ,
241- _skip_builder : bool = False ,
242- ) -> AsyncIterator [dict [str , Any ]]:
243- """Implementation for streaming API requests.
244-
245- When _skip_builder=True, query_params must already be a list of tuples
246- and headers must already be a fully-built dict (used when called from _execute).
247- When response_types_map is provided, it is merged with _COMMON_ERROR_RESPONSE_TYPES.
248- When telemetry_attributes is provided, it is used as-is instead of building minimal defaults.
249- """
250194 if _skip_builder :
251195 resource_path = path
252196 query_params_list = query_params if query_params is not None else []
253197 final_headers = headers or {}
254198 else :
255- from openfga_sdk .client .execute_api_request_builder import (
256- ExecuteApiRequestBuilder ,
257- )
258-
259199 builder = ExecuteApiRequestBuilder (
260200 operation_name = operation_name ,
261201 method = method ,
@@ -272,6 +212,8 @@ async def _execute_streamed_api_request_internal(
272212 final_headers = builder .build_headers ()
273213
274214 retry_params = options .get ("retry_params" ) if options else None
215+ request_timeout = options .get ("_request_timeout" ) if options else None
216+ async_req = options .get ("async_req" ) if options else None
275217
276218 if telemetry_attributes is None :
277219 telemetry_attributes = {
@@ -287,62 +229,103 @@ async def _execute_streamed_api_request_internal(
287229 ** self ._COMMON_ERROR_RESPONSE_TYPES ,
288230 ** response_types_map ,
289231 }
290- else :
291- merged_response_types_map = {}
232+ return await self .api_client .call_api (
233+ resource_path = resource_path ,
234+ method = method .upper (),
235+ path_params = {},
236+ query_params = query_params_list if query_params_list else [],
237+ header_params = final_headers ,
238+ body = body ,
239+ post_params = [],
240+ files = {},
241+ response_types_map = merged_response_types_map ,
242+ auth_settings = [],
243+ async_req = async_req ,
244+ _return_http_data_only = True ,
245+ _preload_content = True ,
246+ _request_timeout = request_timeout ,
247+ _retry_params = retry_params ,
248+ collection_formats = {},
249+ _oauth2_client = self ._oauth2_client ,
250+ _telemetry_attributes = telemetry_attributes ,
251+ _streaming = False ,
252+ )
292253
293- stream = await self .api_client .call_api (
254+ # No response_types_map: public caller path → return RawResponse
255+ await self .api_client .call_api (
294256 resource_path = resource_path ,
295257 method = method .upper (),
296258 query_params = query_params_list if query_params_list else None ,
297259 header_params = final_headers ,
298260 body = body ,
299- response_types_map = merged_response_types_map ,
261+ response_types_map = {} ,
300262 auth_settings = [],
301263 _return_http_data_only = True ,
302264 _preload_content = True ,
303265 _retry_params = retry_params ,
304266 _oauth2_client = self ._oauth2_client ,
305267 _telemetry_attributes = telemetry_attributes ,
306- _streaming = True ,
268+ _streaming = False ,
307269 )
308270
309- async for chunk in stream :
310- yield chunk
271+ rest_response = getattr (self .api_client , "last_response" , None )
272+ if rest_response is None :
273+ raise RuntimeError (
274+ f"No response for { method .upper ()} { resource_path } "
275+ f"(operation: { operation_name } )"
276+ )
277+
278+ return RawResponse (
279+ status = rest_response .status ,
280+ headers = dict (rest_response .getheaders ()),
281+ body = ResponseParser .parse_body (rest_response .data ),
282+ )
311283
312- async def _execute_api_request_internal (
284+ async def execute_streamed_api_request (
313285 self ,
314286 * ,
315287 operation_name : str ,
316288 method : str ,
317289 path : str ,
318290 path_params : dict [str , str ] | None = None ,
319291 body : dict [str , Any ] | list [Any ] | str | bytes | None = None ,
320- query_params = None ,
321- headers = None ,
292+ query_params : dict [ str , str | int | list [ str | int ]] | list | None = None ,
293+ headers : dict [ str , str ] | None = None ,
322294 options : dict [str , Any ] | None = None ,
323295 response_types_map : dict | None = None ,
324296 telemetry_attributes : dict | None = None ,
325297 _skip_builder : bool = False ,
326- ) -> Any :
327- """Implementation for execute_api_request (and _execute delegation).
328-
329- When _skip_builder=True, query_params must already be a list of tuples
330- and headers must already be a fully-built dict (used when called from _execute).
331- When response_types_map is provided, it is merged with _COMMON_ERROR_RESPONSE_TYPES
332- and the deserialized typed result from call_api is returned directly.
333- When telemetry_attributes is provided, it is used as-is instead of building minimal defaults.
298+ ) -> AsyncIterator [dict [str , Any ]]:
334299 """
335- from openfga_sdk .client .execute_api_request_builder import (
336- ExecuteApiRequestBuilder ,
337- ResponseParser ,
338- )
339- from openfga_sdk .client .models .raw_response import RawResponse
300+ Execute an arbitrary HTTP request to a streaming OpenFGA API endpoint.
301+
302+ Yields parsed JSON objects as they arrive. Use with async for:
303+
304+ async for chunk in api.execute_streamed_api_request(...):
305+ process(chunk)
340306
307+ :param operation_name: Operation name for telemetry (e.g., "StreamedListObjects")
308+ :param method: HTTP method (GET, POST, PUT, DELETE, PATCH)
309+ :param path: API path, e.g. "/stores/{store_id}/streamed-list-objects".
310+ :param path_params: Path parameter substitutions (URL-encoded automatically).
311+ All path parameters, including store_id, must be provided explicitly.
312+ :param body: Request body for POST/PUT/PATCH
313+ :param query_params: Query string parameters
314+ :param headers: Custom headers (SDK enforces Content-Type and Accept)
315+ :param options: Extra options e.g. {"retry_params": RetryParams(max_retry=3)}
316+ :param response_types_map: When provided, merge with common error types.
317+ :param telemetry_attributes: When provided, use as-is for telemetry.
318+ :param _skip_builder: When True, path/headers/query_params are used as-is.
319+ """
341320 if _skip_builder :
342321 resource_path = path
343322 query_params_list = query_params if query_params is not None else []
344323 final_headers = headers or {}
345324 else :
325+ from openfga_sdk .client .execute_api_request_builder import (
326+ ExecuteApiRequestBuilder ,
327+ )
328+
346329 builder = ExecuteApiRequestBuilder (
347330 operation_name = operation_name ,
348331 method = method ,
@@ -359,8 +342,6 @@ async def _execute_api_request_internal(
359342 final_headers = builder .build_headers ()
360343
361344 retry_params = options .get ("retry_params" ) if options else None
362- request_timeout = options .get ("_request_timeout" ) if options else None
363- async_req = options .get ("async_req" ) if options else None
364345
365346 if telemetry_attributes is None :
366347 telemetry_attributes = {
@@ -376,58 +357,27 @@ async def _execute_api_request_internal(
376357 ** self ._COMMON_ERROR_RESPONSE_TYPES ,
377358 ** response_types_map ,
378359 }
379- # call_api returns a deserialized typed model when response_types_map is non-empty
380- return await self .api_client .call_api (
381- resource_path = resource_path ,
382- method = method .upper (),
383- path_params = {},
384- query_params = query_params_list if query_params_list else [],
385- header_params = final_headers ,
386- body = body ,
387- post_params = [],
388- files = {},
389- response_types_map = merged_response_types_map ,
390- auth_settings = [],
391- async_req = async_req ,
392- _return_http_data_only = True ,
393- _preload_content = True ,
394- _request_timeout = request_timeout ,
395- _retry_params = retry_params ,
396- collection_formats = {},
397- _oauth2_client = self ._oauth2_client ,
398- _telemetry_attributes = telemetry_attributes ,
399- _streaming = False ,
400- )
360+ else :
361+ merged_response_types_map = {}
401362
402- # No response_types_map: public execute_api_request path → return RawResponse
403- await self .api_client .call_api (
363+ stream = await self .api_client .call_api (
404364 resource_path = resource_path ,
405365 method = method .upper (),
406366 query_params = query_params_list if query_params_list else None ,
407367 header_params = final_headers ,
408368 body = body ,
409- response_types_map = {} ,
369+ response_types_map = merged_response_types_map ,
410370 auth_settings = [],
411371 _return_http_data_only = True ,
412372 _preload_content = True ,
413373 _retry_params = retry_params ,
414374 _oauth2_client = self ._oauth2_client ,
415375 _telemetry_attributes = telemetry_attributes ,
416- _streaming = False ,
376+ _streaming = True ,
417377 )
418378
419- rest_response = getattr (self .api_client , "last_response" , None )
420- if rest_response is None :
421- raise RuntimeError (
422- f"No response for { method .upper ()} { resource_path } "
423- f"(operation: { operation_name } )"
424- )
425-
426- return RawResponse (
427- status = rest_response .status ,
428- headers = dict (rest_response .getheaders ()),
429- body = ResponseParser .parse_body (rest_response .data ),
430- )
379+ async for chunk in stream :
380+ yield chunk
431381
432382 async def batch_check (self , body , ** kwargs ):
433383 """Send a list of `check` operations in a single request
0 commit comments