Skip to content

feat: reverse sync python sdk#696

Open
SoulPancake wants to merge 8 commits into
mainfrom
feat/reverse-sync-python-sdk
Open

feat: reverse sync python sdk#696
SoulPancake wants to merge 8 commits into
mainfrom
feat/reverse-sync-python-sdk

Conversation

@SoulPancake
Copy link
Copy Markdown
Member

@SoulPancake SoulPancake commented Apr 21, 2026

Description

Generates openfga/python-sdk#289

What problem is being solved?

How is it being solved?

What changes are made to solve it?

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for making raw HTTP requests to custom API endpoints using new execution methods.
    • Added support for streaming responses from endpoint calls.
  • Documentation

    • Updated initialization guide with expanded OAuth2 configuration options and best practices.
    • Added new section documenting how to call custom endpoints with examples.
  • Improvements

    • Enhanced error handling and exception messages with better context and classification helpers.
    • Updated Python SDK version to 0.10.3.

Review Change Stack

SoulPancake and others added 2 commits April 21, 2026 09:08
Co-authored-by: SoulPancake <70265851+SoulPancake@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5bc126a0-dee6-42d5-8e92-58b6b3d7043e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR refactors Python SDK generator templates to centralize HTTP request execution across async and sync API classes, introducing raw HTTP request capabilities (execute_api_request, execute_streamed_api_request), enhancing exception handling with operation context and classification helpers, and updating documentation to demonstrate the new raw endpoint calling patterns.

Changes

Python SDK Request Execution Refactoring with Raw HTTP Support

Layer / File(s) Summary
Configuration and build setup
Makefile, config/clients/python/.openapi-generator-ignore, config/clients/python/config.overrides.json, config/clients/python/template/pyproject.toml.mustache, config/common/files/README.mustache
Version bumped to 0.10.3, constants.py excluded from code generation, supportsCallingOtherEndpoints feature flag added, build patch simplified to only patch documentation file, and pytest configured with strict marker enforcement and integration marker definition.
Exception handling enhancement
config/clients/python/template/src/exceptions.py.mustache
ApiException extended with operation_name parameter, structured str output, code/error_message/request_id properties, and boolean classification helpers (is_validation_error, is_authentication_error, is_rate_limit_error, is_retryable, is_client_error, is_server_error). All exception subclasses updated to propagate operation_name. RETRY_AFTER header added to tracked response headers.
Async API executor refactoring
config/clients/python/template/src/api.py.mustache
Introduced shared _COMMON_PARAMS and _COMMON_ERROR_RESPONSE_TYPES constants, private _execute() method for centralized request assembly, and public execute_api_request/execute_streamed_api_request methods for raw HTTP access. Context manager behavior standardized with async aenter/aexit/close(). Operation methods restructured to delegate through _with_http_info() with centralized parameter validation and response type handling.
Sync API executor refactoring
config/clients/python/template/src/sync/api.py.mustache
Mirrors async refactoring with identical architectural changes: shared constants, _execute() executor, execute_api_request/execute_streamed_api_request helpers, and operation method delegation with centralized parameter validation.
Module exports and constants
config/clients/python/template/src/constants.mustache, config/clients/python/template/src/__init__.py.mustache
USER_AGENT constant now explicitly typed with Final[str]. Package version sourced from SDK_VERSION instead of packageVersion, exception imports consolidated into grouped statement, and RawResponse added to module exports.
Documentation and examples
config/clients/python/template/README_calling_api.mustache, config/clients/python/template/README_custom_badges.mustache, config/clients/python/template/README_initializing.mustache
New "Calling Other Endpoints" section with examples for execute_api_request and execute_streamed_api_request, path_params documentation, and custom endpoint POST/GET examples. Initialization examples updated to remove explicit close() calls within async contexts. Added api_audience field and standard OAuth2 Client Credentials (using scopes) example. Socket Badge line includes inline release marker.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • evansims
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: reverse sync python sdk' is concise and directly reflects the main objective described in the PR—reverse syncing the Python SDK generation to align with changes in the upstream python-sdk repository.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/reverse-sync-python-sdk

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@SoulPancake SoulPancake marked this pull request as ready for review May 12, 2026 18:20
@SoulPancake SoulPancake requested a review from a team as a code owner May 12, 2026 18:20
Copilot AI review requested due to automatic review settings May 12, 2026 18:20
@SoulPancake SoulPancake force-pushed the feat/reverse-sync-python-sdk branch from 3007e82 to ebb8c1e Compare May 12, 2026 18:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
config/clients/python/template/src/exceptions.py.mustache (2)

254-261: ⚡ Quick win

Consider checking isinstance(RateLimitExceededError) for consistency.

Similar to the previous comment, this predicate could benefit from an isinstance check to align with the pattern used in is_validation_error and is_not_found_error.

♻️ Suggested improvement
 def is_rate_limit_error(self):
     """
     Check if this is a rate limit (429) error.

     Returns:
         True if HTTP status is 429 or error code indicates rate limiting
     """
-    return self.status == 429 or (self.code and "rate_limit" in self.code.lower())
+    return isinstance(self, RateLimitExceededError) or self.status == 429 or (self.code and "rate_limit" in self.code.lower())
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/clients/python/template/src/exceptions.py.mustache` around lines 254 -
261, Update the is_rate_limit_error predicate to mirror the pattern used in
is_validation_error and is_not_found_error by also checking for the specific
exception class; change the return to include an isinstance(self,
RateLimitExceededError) check in addition to the existing status == 429 and
error code check so that RateLimitExceededError instances are recognized
consistently.

245-252: ⚡ Quick win

Consider checking isinstance(AuthenticationError) for consistency.

The predicate only checks status == 401, but is_validation_error and is_not_found_error also check their respective exception types using isinstance. For consistency and to handle cases where an AuthenticationError is raised without a status code, consider adding an isinstance check.

♻️ Suggested improvement
 def is_authentication_error(self):
     """
     Check if this is an authentication (401) error.

     Returns:
         True if HTTP status is 401
     """
-    return self.status == 401
+    return isinstance(self, AuthenticationError) or self.status == 401
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/clients/python/template/src/exceptions.py.mustache` around lines 245 -
252, The is_authentication_error method currently only checks status == 401;
update it to also return True when the exception instance is of type
AuthenticationError (i.e., use isinstance(self, AuthenticationError) ||
self.status == 401) to match the pattern used by is_validation_error and
is_not_found_error (and to handle cases where status is missing); locate the
method is_authentication_error and the AuthenticationError class to add the
isinstance check and ensure import/definition visibility.
config/clients/python/template/src/api.py.mustache (1)

105-118: 💤 Low value

Streaming branch of async _execute returns an async generator without awaiting — works, but worth a clarifying comment.

execute_streamed_api_request is an async def containing yield, so it is an async generator function: calling it (without await) immediately returns an AsyncGenerator object. Wrapping that return in async def _execute means callers see await self._execute(...) resolving to an async generator they must then async for over. This is correct (and matches {{operationId}} doing return await ..._with_http_info(...)), but it's easy to misread — a one-line comment on line 107 noting that the async generator is intentionally returned (not awaited) would save future maintainers a double-take.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/clients/python/template/src/api.py.mustache` around lines 105 - 118,
The streaming branch in async _execute intentionally returns the AsyncGenerator
produced by execute_streamed_api_request rather than awaiting it; add a concise
inline comment above the return in the _execute function (near the
execute_streamed_api_request call) stating that execute_streamed_api_request is
an async generator and that returning it (not awaiting) is deliberate so callers
can await _execute and then async for over the returned generator.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/clients/python/template/src/api.py.mustache`:
- Around line 245-273: The async RawResponse path in execute_api_request is racy
because it reads ApiClient.last_response after an await; instead capture the
call_api return value directly (like the typed-response path) instead of relying
on last_response and remove the getattr(last_response) usage; call
self.api_client.call_api(...) with the same full argument set used by the typed
path (include path_params, post_params, files, async_req, _request_timeout,
collection_formats, plus the existing
query_params_list/header_params/body/response_types_map/auth_settings/_preload_content/_retry_params/_oauth2_client/_telemetry_attributes/_streaming),
await its result into a variable (e.g. rest_response), then build and return
RawResponse(status=rest_response.status,
headers=dict(rest_response.getheaders()),
body=ResponseParser.parse_body(rest_response.data)).

In `@config/clients/python/template/src/sync/api.py.mustache`:
- Around line 96-105: Telemetry attribute
TelemetryAttributes.fga_client_request_method is populated with inconsistent
casing between _execute (uses operation_name as-is) and execute_api_request
(uses operation_name.lower()), causing fragmented telemetry; normalize to a
single canonical casing (e.g., always lower()) by converting operation_name to
the chosen form in both _execute and the execute_api_request defaulting branch
before assigning to telemetry_attributes and before calling
TelemetryAttributes.fromBody; update references in _execute and
execute_api_request so TelemetryAttributes.fga_client_request_method always
receives the same cased value.
- Around line 246-274: The public/RawResponse branch currently discards the
return value of self.api_client.call_api and reads self.api_client.last_response
(fragile) and also omits several arguments present in the typed branch; instead,
capture call_api's return (e.g., response = self.api_client.call_api(...)) and
build RawResponse from that return value rather than getattr(self.api_client,
"last_response"), and make the call_api invocation mirror the typed branch by
including path_params={}, post_params=[], files={}, async_req=...,
_request_timeout=_request_timeout, and collection_formats={} (and any other
kwargs present in lines 224–244) so call_api signatures are consistent and
thread-safe.

---

Nitpick comments:
In `@config/clients/python/template/src/api.py.mustache`:
- Around line 105-118: The streaming branch in async _execute intentionally
returns the AsyncGenerator produced by execute_streamed_api_request rather than
awaiting it; add a concise inline comment above the return in the _execute
function (near the execute_streamed_api_request call) stating that
execute_streamed_api_request is an async generator and that returning it (not
awaiting) is deliberate so callers can await _execute and then async for over
the returned generator.

In `@config/clients/python/template/src/exceptions.py.mustache`:
- Around line 254-261: Update the is_rate_limit_error predicate to mirror the
pattern used in is_validation_error and is_not_found_error by also checking for
the specific exception class; change the return to include an isinstance(self,
RateLimitExceededError) check in addition to the existing status == 429 and
error code check so that RateLimitExceededError instances are recognized
consistently.
- Around line 245-252: The is_authentication_error method currently only checks
status == 401; update it to also return True when the exception instance is of
type AuthenticationError (i.e., use isinstance(self, AuthenticationError) ||
self.status == 401) to match the pattern used by is_validation_error and
is_not_found_error (and to handle cases where status is missing); locate the
method is_authentication_error and the AuthenticationError class to add the
isinstance check and ensure import/definition visibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44597864-173f-45f0-88ef-51d2e269ffcb

📥 Commits

Reviewing files that changed from the base of the PR and between f65b3d7 and 3007e82.

📒 Files selected for processing (13)
  • Makefile
  • config/clients/python/.openapi-generator-ignore
  • config/clients/python/config.overrides.json
  • config/clients/python/template/README_calling_api.mustache
  • config/clients/python/template/README_custom_badges.mustache
  • config/clients/python/template/README_initializing.mustache
  • config/clients/python/template/pyproject.toml.mustache
  • config/clients/python/template/src/__init__.py.mustache
  • config/clients/python/template/src/api.py.mustache
  • config/clients/python/template/src/constants.mustache
  • config/clients/python/template/src/exceptions.py.mustache
  • config/clients/python/template/src/sync/api.py.mustache
  • config/common/files/README.mustache

Comment thread config/clients/python/template/src/api.py.mustache
Comment thread config/clients/python/template/src/sync/api.py.mustache
Comment thread config/clients/python/template/src/sync/api.py.mustache
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the SDK generator to align Python SDK generation with downstream changes (referenced python-sdk PR #289), including documentation and template updates intended to support calling non-wrapped endpoints and improving generated client behavior.

Changes:

  • Updates Python API templates to add execute_api_request / execute_streamed_api_request and refactors endpoint execution through a shared _execute.
  • Refreshes Python templates/docs (README sections, exception formatting, pytest config) and bumps the Python SDK version to 0.10.3.
  • Adjusts the Python build flow by removing the open_fga_api.py patch application step.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
Makefile Removes application of the open_fga_api.py patch during Python client build.
config/common/files/README.mustache Adds conditional TOC entry for “Calling Other Endpoints”.
config/clients/python/template/src/sync/api.py.mustache Adds shared execution path + raw/stream execution helpers to sync API template.
config/clients/python/template/src/api.py.mustache Adds shared execution path + raw/stream execution helpers to async API template.
config/clients/python/template/src/exceptions.py.mustache Updates exception formatting and adds operation context helpers.
config/clients/python/template/src/constants.mustache Annotates USER_AGENT for versioning automation.
config/clients/python/template/src/init.py.mustache Reworks exports/version source; adds RawResponse export.
config/clients/python/template/README_initializing.mustache Updates initialization examples and expands OAuth2 credential guidance.
config/clients/python/template/README_custom_badges.mustache Adds release-please marker comment to the Socket badge line.
config/clients/python/template/README_calling_api.mustache Adds documentation for calling other endpoints + streaming examples.
config/clients/python/template/pyproject.toml.mustache Enables --strict-markers and declares integration marker.
config/clients/python/config.overrides.json Bumps Python packageVersion and enables supportsCallingOtherEndpoints.
config/clients/python/.openapi-generator-ignore Adds openfga_sdk/constants.py to ignored outputs.

Comment thread config/clients/python/template/src/api.py.mustache
Comment on lines +201 to +208
retry_params = (
options.get("retry_params") or options.get("_retry_params")
if options
else None
)
request_timeout = options.get("_request_timeout") if options else None
async_req = options.get("async_req") if options else None

Comment on lines +253 to +255
auth_settings=[],
_return_http_data_only=True,
_preload_content=True,
Comment on lines 452 to 498
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _return_http_data_only: response data without head status code
and headers
:type _return_http_data_only: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
:param _retry_param: if specified, override the retry parameters specified in configuration
:type _request_auth: dict, optional
:type _content_type: string, optional: force content-type for the request
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: {{#returnType}}tuple({{.}}, status_code(int), headers(HTTPHeaderDict)){{/returnType}}{{^returnType}}None{{/returnType}}
"""

{{#servers.0}}
local_var_hosts = [
{{#servers}}
'{{{url}}}'{{^-last}},{{/-last}}
{{/servers}}
]
local_var_host = local_var_hosts[0]
if kwargs.get('_host_index'):
_host_index = int(kwargs.get('_host_index'))
if _host_index < 0 or _host_index >= len(local_var_hosts):
raise ApiValueError(
"Invalid host index. Must be 0 <= index < %s"
% len(local_var_host)
)
local_var_host = local_var_hosts[_host_index]
{{/servers.0}}
local_var_params = locals()

all_params = [
{{#requiredParams}}{{^-first}}
'{{paramName}}'{{^-last}},{{/-last}}
{{/-first}}{{/requiredParams}}
{{#requiredParams}}
{{#isPathParam}}
{{^-first}}
"{{paramName}}",
{{/-first}}
{{/isPathParam}}
{{^isPathParam}}
"{{paramName}}",
{{/isPathParam}}
{{/requiredParams}}
{{#optionalParams}}
'{{paramName}}'{{^-last}},{{/-last}}
"{{paramName}}",
{{/optionalParams}}
]
all_params.extend(
[
'async_req',
'_return_http_data_only',
'_preload_content',
'_request_timeout',
'_request_auth',
'_content_type',
'_headers',
'_retry_params',
'_streaming',
]
)
all_params.extend(self._COMMON_PARAMS)

for key, val in local_var_params['kwargs'].items():
if key not in all_params{{#servers.0}} and key != "_host_index"{{/servers.0}}:
for key, val in local_var_params["kwargs"].items():
if key not in all_params:
raise FgaValidationException(
Comment on lines +176 to +181
from {{packageName}}.client.execute_api_request_builder import (
ExecuteApiRequestBuilder,
ResponseParser,
)
from {{packageName}}.client.models.raw_response import RawResponse

Comment on lines +202 to +208
retry_params = (
options.get("retry_params") or options.get("_retry_params")
if options
else None
)
request_timeout = options.get("_request_timeout") if options else None
async_req = options.get("async_req") if options else None
Comment on lines 452 to 498
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _return_http_data_only: response data without head status code
and headers
:type _return_http_data_only: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
be returned without reading/decoding response
data. Default is True.
:type _preload_content: bool, optional
:param _request_timeout: timeout setting for this request. If one
number provided, it will be total request
timeout. It can also be a pair (tuple) of
(connection, read) timeouts.
:param _request_auth: set to override the auth_settings for an a single
request; this effectively ignores the authentication
in the spec for a single request.
:param _retry_param: if specified, override the retry parameters specified in configuration
:type _request_auth: dict, optional
:type _content_type: string, optional: force content-type for the request
:return: Returns the result object.
If the method is called asynchronously,
returns the request thread.
:rtype: {{#returnType}}tuple({{.}}, status_code(int), headers(HTTPHeaderDict)){{/returnType}}{{^returnType}}None{{/returnType}}
"""

{{#servers.0}}
local_var_hosts = [
{{#servers}}
'{{{url}}}'{{^-last}},{{/-last}}
{{/servers}}
]
local_var_host = local_var_hosts[0]
if kwargs.get('_host_index'):
_host_index = int(kwargs.get('_host_index'))
if _host_index < 0 or _host_index >= len(local_var_hosts):
raise ApiValueError(
"Invalid host index. Must be 0 <= index < %s"
% len(local_var_host)
)
local_var_host = local_var_hosts[_host_index]
{{/servers.0}}
local_var_params = locals()

all_params = [
{{#requiredParams}}{{^-first}}
'{{paramName}}'{{^-last}},{{/-last}}
{{/-first}}{{/requiredParams}}
{{#requiredParams}}
{{#isPathParam}}
{{^-first}}
"{{paramName}}",
{{/-first}}
{{/isPathParam}}
{{^isPathParam}}
"{{paramName}}",
{{/isPathParam}}
{{/requiredParams}}
{{#optionalParams}}
'{{paramName}}'{{^-last}},{{/-last}}
"{{paramName}}",
{{/optionalParams}}
]
all_params.extend(
[
"async_req",
"_return_http_data_only",
"_preload_content",
"_request_timeout",
"_request_auth",
"_content_type",
"_headers",
"_retry_params",
"_streaming",
]
)
all_params.extend(self._COMMON_PARAMS)

for key, val in local_var_params['kwargs'].items():
if key not in all_params{{#servers.0}} and key != "_host_index"{{/servers.0}}:
for key, val in local_var_params["kwargs"].items():
if key not in all_params:
raise FgaValidationException(
Comment thread Makefile
@@ -144,8 +144,7 @@ build-client-python:

sort -uo ${CLIENTS_OUTPUT_DIR}/fga-python-sdk/.openapi-generator/FILES{,}

@SoulPancake SoulPancake linked an issue May 14, 2026 that may be closed by this pull request
10 tasks
openfga_sdk/sync/open_fga_api.py
openfga_sdk/api_client.py
openfga_sdk/configuration.py
openfga_sdk/constants.py
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't ignore constants

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh the reason I removed it was because of the sdk version and user agent driven from the generator
Since now we are using release please to handle and bump that, but you're right there's a lot of other common configs in this that are controlled from the generator.
Maybe we move the versions to a different file?
Or sync it back once in a while 🤔

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have extracted it to a version file that is SDK maintained @rhamzeh

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to fail in CI, investigating, maybe my sequencing is not correct

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@SoulPancake SoulPancake requested a review from rhamzeh May 15, 2026 14:00
@SoulPancake
Copy link
Copy Markdown
Member Author

The check should pass after this is merged openfga/python-sdk#289

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reverse synch all the ApiExecutor API layer changes back to the generator

3 participants