-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(python-sdk): add streamed-list-objects endpoint (#469)
- Loading branch information
Showing
39 changed files
with
5,481 additions
and
2,574 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ openfga-sdk >= {{packageVersion}} | |
python-dateutil >= 2.8.2 | ||
urllib3 >= 2.1.0 | ||
yarl >= 1.9.4 | ||
python-dotenv >= 1, <2 |
1 change: 1 addition & 0 deletions
1
config/clients/python/template/example/streamed-list-objects/.env.example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
FGA_API_URL="http://localhost:8080" |
1 change: 1 addition & 0 deletions
1
config/clients/python/template/example/streamed-list-objects/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.env |
39 changes: 39 additions & 0 deletions
39
config/clients/python/template/example/streamed-list-objects/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Streamed List Objects example for OpenFGA's Python SDK | ||
|
||
This example demonstrates working with the `POST` `/stores/:id/streamed-list-objects` endpoint in OpenFGA using the Python SDK. | ||
|
||
## Prerequisites | ||
|
||
If you do not already have an OpenFGA instance running, you can start one using the following command: | ||
|
||
```bash | ||
docker run -d -p 8080:8080 openfga/openfga | ||
``` | ||
|
||
## Configure the example | ||
|
||
You may need to configure the example for your environment: | ||
|
||
```bash | ||
cp .env.example .env | ||
``` | ||
|
||
Now edit the `.env` file and set the values as appropriate. | ||
|
||
## Running the example | ||
|
||
Begin by installing the required dependencies: | ||
|
||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
Next, run the example. You can use either the synchronous or asynchronous client: | ||
|
||
```bash | ||
python asynchronous.py | ||
``` | ||
|
||
```bash | ||
python synchronous.py | ||
``` |
121 changes: 121 additions & 0 deletions
121
config/clients/python/template/example/streamed-list-objects/asynchronous.py.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import asyncio | ||
import json | ||
import os | ||
import sys | ||
from operator import attrgetter | ||
from typing import Any | ||
|
||
from dotenv import load_dotenv | ||
|
||
sdk_path = os.path.realpath(os.path.join(os.path.abspath(__file__), "..", "..", "..")) | ||
sys.path.insert(0, sdk_path) | ||
|
||
from {{packageName}} import ( | ||
ClientConfiguration, | ||
OpenFgaClient, | ||
) | ||
from {{packageName}}.client.models import ( | ||
ClientListObjectsRequest, | ||
ClientTuple, | ||
ClientWriteRequest, | ||
) | ||
from {{packageName}}.models import CreateStoreRequest | ||
|
||
|
||
class app: | ||
def __init__( | ||
self, | ||
client: OpenFgaClient = None, | ||
configuration: ClientConfiguration = None, | ||
): | ||
self._client = client | ||
self._configuration = configuration | ||
|
||
async def fga_client(self, env: dict[str, str] = {}) -> OpenFgaClient: | ||
if not self._client or not self._configuration: | ||
load_dotenv() | ||
|
||
if not self._configuration: | ||
self._configuration = ClientConfiguration( | ||
api_url=os.getenv("FGA_API_URL"), | ||
) | ||
|
||
self._client = OpenFgaClient(self._configuration) | ||
return self._client | ||
|
||
|
||
def unpack( | ||
response, | ||
attr: str, | ||
) -> Any: | ||
return attrgetter(attr)(response) | ||
|
||
|
||
async def main(): | ||
async with await app().fga_client() as fga_client: | ||
# Create a temporary store | ||
store = unpack( | ||
await fga_client.create_store(CreateStoreRequest(name="Test Store")), | ||
"id", | ||
) | ||
print(f"Created temporary store ({store})") | ||
fga_client.set_store_id(store) | ||
|
||
# Create a temporary authorization model | ||
model = unpack( | ||
await fga_client.write_authorization_model( | ||
json.loads( | ||
'{"schema_version":"1.1","type_definitions":[{"type":"user","relations":{}},{"type":"group","relations":{"member":{"this":{}}},"metadata":{"relations":{"member":{"directly_related_user_types":[{"type":"user"}]}}}},{"type":"folder","relations":{"can_create_file":{"computedUserset":{"object":"","relation":"owner"}},"owner":{"this":{}},"parent":{"this":{}},"viewer":{"union":{"child":[{"this":{}},{"computedUserset":{"object":"","relation":"owner"}},{"tupleToUserset":{"tupleset":{"object":"","relation":"parent"},"computedUserset":{"object":"","relation":"viewer"}}}]}}},"metadata":{"relations":{"can_create_file":{"directly_related_user_types":[]},"owner":{"directly_related_user_types":[{"type":"user"}]},"parent":{"directly_related_user_types":[{"type":"folder"}]},"viewer":{"directly_related_user_types":[{"type":"user"},{"type":"user","wildcard":{}},{"type":"group","relation":"member"}]}}}},{"type":"document","relations":{"can_change_owner":{"computedUserset":{"object":"","relation":"owner"}},"owner":{"this":{}},"parent":{"this":{}},"can_read":{"union":{"child":[{"computedUserset":{"object":"","relation":"viewer"}},{"computedUserset":{"object":"","relation":"owner"}},{"tupleToUserset":{"tupleset":{"object":"","relation":"parent"},"computedUserset":{"object":"","relation":"viewer"}}}]}},"can_share":{"union":{"child":[{"computedUserset":{"object":"","relation":"owner"}},{"tupleToUserset":{"tupleset":{"object":"","relation":"parent"},"computedUserset":{"object":"","relation":"owner"}}}]}},"viewer":{"this":{}},"can_write":{"union":{"child":[{"computedUserset":{"object":"","relation":"owner"}},{"tupleToUserset":{"tupleset":{"object":"","relation":"parent"},"computedUserset":{"object":"","relation":"owner"}}}]}}},"metadata":{"relations":{"can_change_owner":{"directly_related_user_types":[]},"owner":{"directly_related_user_types":[{"type":"user"}]},"parent":{"directly_related_user_types":[{"type":"folder"}]},"can_read":{"directly_related_user_types":[]},"can_share":{"directly_related_user_types":[]},"viewer":{"directly_related_user_types":[{"type":"user"},{"type":"user","wildcard":{}},{"type":"group","relation":"member"}]},"can_write":{"directly_related_user_types":[]}}}}]}' | ||
) | ||
), | ||
"authorization_model_id", | ||
) | ||
print(f"Created temporary authorization model ({model})") | ||
|
||
print(f"Writing 100 mock tuples to store.") | ||
|
||
# Write mock data | ||
writes = [] | ||
for x in range(0, 100): | ||
writes.append( | ||
ClientTuple( | ||
user="user:anne", | ||
relation="owner", | ||
object=f"document:{x}", | ||
) | ||
) | ||
|
||
await fga_client.write( | ||
ClientWriteRequest(writes), | ||
{ | ||
"authorization_model_id": model, | ||
}, | ||
) | ||
|
||
print("Listing objects using streaming endpoint:") | ||
results = [] | ||
|
||
request = ClientListObjectsRequest( | ||
type="document", | ||
relation="owner", | ||
user="user:anne", | ||
) | ||
|
||
async for response in fga_client.streamed_list_objects(request): | ||
print(f" {response}") | ||
results.append(response) | ||
|
||
print(f"API returned {results.__len__()} objects.") | ||
|
||
# Delete the temporary store | ||
try: | ||
await fga_client.delete_store() | ||
print(f"Deleted temporary store ({store})") | ||
except: | ||
pass | ||
|
||
print("Finished.") | ||
|
||
|
||
if __name__ == "__main__": | ||
asyncio.run(main()) |
1 change: 1 addition & 0 deletions
1
config/clients/python/template/example/streamed-list-objects/requirements.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
python-dotenv >= 1, <2 |
2 changes: 2 additions & 0 deletions
2
config/clients/python/template/example/streamed-list-objects/setup.cfg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[flake8] | ||
max-line-length=99 |
30 changes: 30 additions & 0 deletions
30
config/clients/python/template/example/streamed-list-objects/setup.py.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
""" | ||
Python SDK for OpenFGA | ||
|
||
API version: 0.1 | ||
Website: https://openfga.dev | ||
Documentation: https://openfga.dev/docs | ||
Support: https://discord.gg/8naAwJfWN6 | ||
License: [Apache-2.0](https://github.com/openfga/python-sdk/blob/main/LICENSE) | ||
|
||
NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT. | ||
""" | ||
|
||
from setuptools import find_packages, setup | ||
|
||
NAME = "openfga-streamed-list-objects-example" | ||
VERSION = "0.0.1" | ||
REQUIRES = [""] | ||
|
||
setup( | ||
name=NAME, | ||
version=VERSION, | ||
description="An example of using the OpenFGA Python SDK with the Streamed List Objects endpoint.", | ||
author="OpenFGA (https://openfga.dev)", | ||
author_email="[email protected]", | ||
url="https://github.com/openfga/python-sdk", | ||
python_requires=">={{pythonMinimumRuntime}}", | ||
packages=find_packages(exclude=["test", "tests"]), | ||
include_package_data=True, | ||
license="Apache-2.0", | ||
) |
Oops, something went wrong.