diff --git a/Makefile b/Makefile index 420c8ce9..f4cacff8 100644 --- a/Makefile +++ b/Makefile @@ -157,9 +157,15 @@ build-client-python: test-client-python: build-client-python make run-in-docker sdk_language=python image=ghcr.io/astral-sh/uv:python${PYTHON_DOCKER_TAG}-alpine command="/bin/sh -c 'export UV_LINK_MODE=copy && \ uv sync && \ - uv run pytest --cov-report term-missing --cov=openfga_sdk test/ && \ + uv run pytest -m \"not integration\" --cov-report term-missing --cov=openfga_sdk test/ && \ uv run ruff check .'" +.PHONY: test-integration-client-python +test-integration-client-python: build-client-python + make run-in-docker sdk_language=python image=ghcr.io/astral-sh/uv:python${PYTHON_DOCKER_TAG}-alpine command="/bin/sh -c 'export UV_LINK_MODE=copy && \ + uv sync && \ + uv run pytest -m integration test/'" + ### Java .PHONY: tag-client-java tag-client-java: test-client-java diff --git a/config/clients/python/config.overrides.json b/config/clients/python/config.overrides.json index 4d6c245e..027930c3 100644 --- a/config/clients/python/config.overrides.json +++ b/config/clients/python/config.overrides.json @@ -2,7 +2,7 @@ "sdkId": "python", "gitRepoId": "python-sdk", "packageName": "openfga_sdk", - "packageVersion": "0.9.7", + "packageVersion": "0.9.9", "packageDescription": "Python SDK for OpenFGA", "packageDetailedDescription": "This is an autogenerated python SDK for OpenFGA. It provides a wrapper around the [OpenFGA API definition](https://openfga.dev/api).", "fossaComplianceNoticeId": "2f8a8629-b46c-435e-b8cd-1174a674fb4b", diff --git a/config/clients/python/template/README_calling_api.mustache b/config/clients/python/template/README_calling_api.mustache index e7348c67..ebffc901 100644 --- a/config/clients/python/template/README_calling_api.mustache +++ b/config/clients/python/template/README_calling_api.mustache @@ -638,6 +638,9 @@ response = await fga_client.batch_check(ClientBatchCheckRequest(checks=checks), # ] ``` +##### Client Batch Check + + If you are using an OpenFGA version less than 1.8.0, you can use `client_batch_check`, which calls `check` in parallel. It will return `allowed: false` if it encounters an error, and will return the error in the body. If 429s or 5xxs are encountered, the underlying check will retry up to 3 times before giving up. diff --git a/config/clients/python/template/README_retries.mustache b/config/clients/python/template/README_retries.mustache index 0d35277b..b130f432 100644 --- a/config/clients/python/template/README_retries.mustache +++ b/config/clients/python/template/README_retries.mustache @@ -20,3 +20,27 @@ async def main(): async with {{appShortName}}Client(config) as client: return await client.read_authorization_models() ``` + + +### Error Handling + +The SDK provides comprehensive error handling with detailed error information and convenient helper methods. + +Key features: +- Operation context in error messages (e.g., `[write]`, `[check]`) +- Detailed error codes and messages from the API +- Helper methods for error categorization (`is_validation_error()`, `is_retryable()`, etc.) + +```python +from {{packageName}}.exceptions import ApiException + +try: + await client.write([tuple]) +except ApiException as e: + print(f"Error: {e}") # [write] HTTP 400 type 'invalid_type' not found (validation_error) [request-id: abc-123] + + if e.is_validation_error(): + print(f"Validation error: {e.error_message}") + elif e.is_retryable(): + print(f"Temporary error - retrying... (Request ID: {e.request_id})") +```