Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ You need your store id to call the OpenFGA API (unless it is to call the [Create

If your server is configured with [authentication enabled](https://openfga.dev/docs/getting-started/setup-openfga#configuring-authentication), you also need to have your credentials ready.

To call a different store for a single request, pass `store_id` in the `options`. It overrides the store ID in the configuration for that request only, so one client can work with several stores. If the client has an `authorization_model_id` configured, pass the other store's model ID in the options as well:

```python
store = await fga_client.get_store(options={"store_id": "01JD9Z1F6Y0XWAGKM9KYQ8GXMC"})

response = await fga_client.check(
body=ClientCheckRequest(user="user:anne", relation="viewer", object="document:roadmap"),
options={"store_id": "01JD9Z1F6Y0XWAGKM9KYQ8GXMC"},
)
```

### Calling the API

#### Stores
Expand Down
110 changes: 29 additions & 81 deletions openfga_sdk/api/open_fga_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class OpenFgaApi:
"_headers",
"_retry_params",
"_streaming",
"_store_id",
]

_COMMON_ERROR_RESPONSE_TYPES = {
Expand Down Expand Up @@ -71,6 +72,16 @@ async def __aexit__(self, exc_type, exc_value, traceback):
async def close(self):
await self.api_client.close()

def _resolve_store_id(self, options: dict | None = None) -> str:
"""
Return the store ID passed for this request in `_store_id`, falling back
to the store ID in the api_client's configuration.
"""
store_id = (options or {}).get("_store_id")
if store_id:
return store_id
return self.api_client._get_store_id()

async def _execute(
self,
method: str,
Expand Down Expand Up @@ -103,7 +114,8 @@ async def _execute(

telemetry_attributes: dict[TelemetryAttribute, str | bool | int | float] = {
TelemetryAttributes.fga_client_request_method: operation_name,
TelemetryAttributes.fga_client_request_store_id: self.api_client.get_store_id(),
TelemetryAttributes.fga_client_request_store_id: options.get("_store_id")
or self.api_client.get_store_id(),
TelemetryAttributes.fga_client_request_model_id: options.get(
"authorization_model_id", ""
),
Expand Down Expand Up @@ -467,11 +479,7 @@ async def batch_check_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `batch_check`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `batch_check`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/batch-check",
Expand Down Expand Up @@ -564,11 +572,7 @@ async def check_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `check`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `check`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/check",
Expand Down Expand Up @@ -739,11 +743,7 @@ async def delete_store_with_http_info(self, **kwargs):
)
local_var_params[key] = val
del local_var_params["kwargs"]
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `delete_store`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="DELETE",
path=f"/stores/{store_id}",
Expand Down Expand Up @@ -835,11 +835,7 @@ async def expand_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `expand`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `expand`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/expand",
Expand Down Expand Up @@ -918,11 +914,7 @@ async def get_store_with_http_info(self, **kwargs):
)
local_var_params[key] = val
del local_var_params["kwargs"]
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `get_store`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
return await self._execute(
method="GET",
path=f"/stores/{store_id}",
Expand Down Expand Up @@ -1014,11 +1006,7 @@ async def list_objects_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `list_objects`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `list_objects`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/list-objects",
Expand Down Expand Up @@ -1214,11 +1202,7 @@ async def list_users_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `list_users`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `list_users`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/list-users",
Expand Down Expand Up @@ -1311,11 +1295,7 @@ async def read_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `read`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `read`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/read",
Expand Down Expand Up @@ -1409,11 +1389,7 @@ async def read_assertions_with_http_info(self, authorization_model_id, **kwargs)
raise ApiValueError(
"Missing the required parameter `authorization_model_id` when calling `read_assertions`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `read_assertions`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="GET",
path=f"/stores/{store_id}/assertions/{authorization_model_id}",
Expand Down Expand Up @@ -1504,11 +1480,7 @@ async def read_authorization_model_with_http_info(self, id, **kwargs):
raise ApiValueError(
"Missing the required parameter `id` when calling `read_authorization_model`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `read_authorization_model`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="GET",
path=f"/stores/{store_id}/authorization-models/{id}",
Expand Down Expand Up @@ -1597,11 +1569,7 @@ async def read_authorization_models_with_http_info(self, **kwargs):
)
local_var_params[key] = val
del local_var_params["kwargs"]
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `read_authorization_models`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
query_params = []
if local_var_params.get("page_size") is not None:
query_params.append(("page_size", local_var_params["page_size"]))
Expand Down Expand Up @@ -1708,11 +1676,7 @@ async def read_changes_with_http_info(self, **kwargs):
)
local_var_params[key] = val
del local_var_params["kwargs"]
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `read_changes`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
query_params = []
if local_var_params.get("type") is not None:
query_params.append(("type", local_var_params["type"]))
Expand Down Expand Up @@ -1816,11 +1780,7 @@ async def streamed_list_objects_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `streamed_list_objects`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `streamed_list_objects`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/streamed-list-objects",
Expand Down Expand Up @@ -1913,11 +1873,7 @@ async def write_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `write`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `write`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/write",
Expand Down Expand Up @@ -2026,11 +1982,7 @@ async def write_assertions_with_http_info(
raise ApiValueError(
"Missing the required parameter `body` when calling `write_assertions`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `write_assertions`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="PUT",
path=f"/stores/{store_id}/assertions/{authorization_model_id}",
Expand Down Expand Up @@ -2123,11 +2075,7 @@ async def write_authorization_model_with_http_info(self, body, **kwargs):
raise ApiValueError(
"Missing the required parameter `body` when calling `write_authorization_model`"
)
if self.api_client._get_store_id() is None:
raise ApiValueError(
"Store ID expected in api_client's configuration when calling `write_authorization_model`"
)
store_id = self.api_client._get_store_id()
store_id = self._resolve_store_id(local_var_params)
return await self._execute(
method="POST",
path=f"/stores/{store_id}/authorization-models",
Expand Down
4 changes: 3 additions & 1 deletion openfga_sdk/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def options_to_kwargs(
options: dict[str, int | str | dict[str, int | str]] | None = None,
) -> dict[str, int | str | dict[str, int | str]]:
"""
Return kwargs with continuation_token and page_size
Return the API kwargs for the client options
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
"""
kwargs = {}
if options is not None:
Expand All @@ -124,6 +124,8 @@ def options_to_kwargs(
kwargs["_headers"] = options["headers"]
if options.get("retry_params"):
kwargs["_retry_params"] = options["retry_params"]
if options.get("store_id"):
kwargs["_store_id"] = options["store_id"]
return kwargs


Expand Down
4 changes: 3 additions & 1 deletion openfga_sdk/sync/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def options_to_kwargs(
options: dict[str, int | str | dict[str, int | str]] | None = None,
) -> dict[str, int | str | dict[str, int | str]]:
"""
Return kwargs with continuation_token and page_size
Return the API kwargs for the client options
"""
kwargs = {}
if options is not None:
Expand All @@ -124,6 +124,8 @@ def options_to_kwargs(
kwargs["_headers"] = options["headers"]
if options.get("retry_params"):
kwargs["_retry_params"] = options["retry_params"]
if options.get("store_id"):
kwargs["_store_id"] = options["store_id"]
return kwargs


Expand Down
Loading