Skip to content

release(python-sdk): v0.5.0 #380

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ build-client-python:
make run-in-docker sdk_language=python image=busybox:${BUSYBOX_DOCKER_TAG} command="/bin/sh -c 'patch -p1 /module/openfga_sdk/api/open_fga_api.py /config/clients/python/patches/open_fga_api.py.patch'"
make run-in-docker sdk_language=python image=busybox:${BUSYBOX_DOCKER_TAG} command="/bin/sh -c 'patch -p1 /module/openfga_sdk/sync/open_fga_api.py /config/clients/python/patches/open_fga_api_sync.py.patch'"
make run-in-docker sdk_language=python image=busybox:${BUSYBOX_DOCKER_TAG} command="/bin/sh -c 'patch -p1 /module/docs/OpenFgaApi.md /config/clients/python/patches/OpenFgaApi.md.patch'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install pyupgrade==3.15.1 isort==5.13.2 black==24.2.0 autoflake==2.3.0; pyupgrade \`find . -name *.py -type f\` --py310-plus --keep-runtime-typing; isort . --profile black; black .; autoflake --exclude=__init__.py --in-place --remove-unused-variables --remove-all-unused-imports -r .'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install pyupgrade==3.15.2 isort==5.13.2 black==24.4.2 autoflake==2.3.1; pyupgrade \`find . -name *.py -type f\` --py310-plus --keep-runtime-typing; isort . --profile black; autoflake --exclude=__init__.py --in-place --remove-unused-variables --remove-all-unused-imports -r .; black .'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'pip install setuptools wheel && python setup.py sdist bdist_wheel'"

.PHONY: test-client-python
Expand Down
9 changes: 9 additions & 0 deletions config/clients/python/CHANGELOG.md.mustache
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## v0.4.4

### [0.4.4](https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/compare/v0.4.3...v0.4.4) (2024-06-17)

- fix: ClientTuple condition property type
- fix: list_users should accept FgaObject type
- fix: remove ReadAuthorizationModel calls from BatchCheck and writes
- chore!: remove excluded users from ListUsers response

## v0.4.3

### [0.4.3](https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}/compare/v0.4.2...v0.4.3) (2024-06-07)
Expand Down
2 changes: 1 addition & 1 deletion config/clients/python/config.overrides.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"sdkId": "python",
"gitRepoId": "python-sdk",
"packageName": "openfga_sdk",
"packageVersion": "0.4.3",
"packageVersion": "0.4.4",
"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",
Expand Down
8 changes: 8 additions & 0 deletions config/clients/python/template/.github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ updates:
- "*"
ignore:
- dependency-name: "urllib3"
- package-ecosystem: "pip"
directory: "/example/example1"
schedule:
interval: "monthly"
groups:
dependencies:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0

Expand Down Expand Up @@ -60,7 +60,7 @@ jobs:

- if: matrix.python-version == '3.10'
name: Upload coverage to Codecov
uses: codecov/codecov-action@84508663e988701840491b86de86b666e8a86bed # v4.3.0
uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1
continue-on-error: true
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand All @@ -75,7 +75,7 @@ jobs:
id-token: write # Required for PyPI trusted publishing

steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0

Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
needs: [publish]

steps:
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ List the users who have a certain relation to a particular type.

```python
from openfga_sdk import OpenFgaClient
from openfga_sdk.models.fga_object import FgaObject
from openfga_sdk.client.models import ClientListUsersRequest, ClientTuple

configuration = ClientConfiguration(
Expand All @@ -697,7 +698,7 @@ async with OpenFgaClient(configuration) as api_client:
}

request = ClientListUsersRequest(
object="document:2021-budget",
object=FgaObject(type="document", id="2021-budget"),
relation="can_read",
user_filters=[
UserTypeFilter(type="user"),
Expand Down
25 changes: 9 additions & 16 deletions config/clients/python/template/client/client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ from {{packageName}}.client.models.list_users_request import ClientListUsersRequ
from {{packageName}}.client.models.write_single_response import construct_write_single_response
from {{packageName}}.client.models.write_transaction_opts import WriteTransactionOpts
from {{packageName}}.client.models.read_changes_request import ClientReadChangesRequest
from {{packageName}}.exceptions import FgaValidationException
from {{packageName}}.exceptions import (
AuthenticationError,
FgaValidationException,
UnauthorizedException,
)
from {{packageName}}.models.assertion import Assertion
from {{packageName}}.models.check_request import CheckRequest
from {{packageName}}.models.contextual_tuple_keys import ContextualTupleKeys
Expand Down Expand Up @@ -165,16 +169,6 @@ class OpenFgaClient:
"""
return self._client_configuration.authorization_model_id

{{#asyncio}}async {{/asyncio}}def _check_valid_api_connection(self, options: dict[str, int | str]):
"""
Checks that a connection with the given configuration can be established
"""
authorization_model_id = self._get_authorization_model_id(options)
if authorization_model_id is not None and authorization_model_id != "":
{{#asyncio}}await {{/asyncio}}self.read_authorization_model(options)
else:
{{#asyncio}}await {{/asyncio}}self.read_latest_authorization_model(options)

#################
# Stores
#################
Expand Down Expand Up @@ -380,6 +374,8 @@ class OpenFgaClient:
delete_batch = batch
{{#asyncio}}await {{/asyncio}}self._write_with_transaction(ClientWriteRequest(writes=write_batch, deletes=delete_batch), options)
return [construct_write_single_response(i, True, None) for i in batch]
except (AuthenticationError, UnauthorizedException) as err:
raise err
except Exception as err:
return [construct_write_single_response(i, False, err) for i in batch]

Expand Down Expand Up @@ -449,8 +445,6 @@ class OpenFgaClient:
return results

options = set_heading_if_not_set(options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()))
# TODO: this should be run in parallel
{{#asyncio}}await {{/asyncio}}self._check_valid_api_connection(options)

# otherwise, it is not a transaction and it is a batch write requests
writes_response = None
Expand Down Expand Up @@ -533,6 +527,8 @@ class OpenFgaClient:
try:
api_response = {{#asyncio}}await {{/asyncio}}self.check(body, options)
return BatchCheckResponse(allowed=api_response.allowed, request=body, response=api_response, error=None)
except (AuthenticationError, UnauthorizedException) as err:
raise err
except Exception as err:
return BatchCheckResponse(allowed=False, request=body, response=None, error=err)
{{#asyncio}}
Expand All @@ -554,9 +550,6 @@ class OpenFgaClient:
options = set_heading_if_not_set(options, CLIENT_METHOD_HEADER, "BatchCheck")
options = set_heading_if_not_set(options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()))

# TODO: this should be run in parallel
{{#asyncio}}await {{/asyncio}}self._check_valid_api_connection(options)

max_parallel_requests = {{ clientMaxMethodParallelRequests }}
if options is not None and "max_parallel_requests" in options:
max_parallel_requests = options["max_parallel_requests"]
Expand Down
25 changes: 9 additions & 16 deletions config/clients/python/template/client/client_sync.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ from {{packageName}}.client.models.list_users_request import ClientListUsersRequ
from {{packageName}}.client.models.write_single_response import construct_write_single_response
from {{packageName}}.client.models.write_transaction_opts import WriteTransactionOpts
from {{packageName}}.client.models.read_changes_request import ClientReadChangesRequest
from {{packageName}}.exceptions import FgaValidationException
from {{packageName}}.exceptions import (
AuthenticationError,
FgaValidationException,
UnauthorizedException,
)
from {{packageName}}.models.assertion import Assertion
from {{packageName}}.models.check_request import CheckRequest
from {{packageName}}.models.contextual_tuple_keys import ContextualTupleKeys
Expand Down Expand Up @@ -151,16 +155,6 @@ class OpenFgaClient:
"""
return self._client_configuration.authorization_model_id

def _check_valid_api_connection(self, options: dict[str, int | str]):
"""
Checks that a connection with the given configuration can be established
"""
authorization_model_id = self._get_authorization_model_id(options)
if authorization_model_id is not None and authorization_model_id != "":
self.read_authorization_model(options)
else:
self.read_latest_authorization_model(options)

#################
# Stores
#################
Expand Down Expand Up @@ -366,6 +360,8 @@ class OpenFgaClient:
delete_batch = batch
self._write_with_transaction(ClientWriteRequest(writes=write_batch, deletes=delete_batch), options)
return [construct_write_single_response(i, True, None) for i in batch]
except (AuthenticationError, UnauthorizedException) as err:
raise err
except Exception as err:
return [construct_write_single_response(i, False, err) for i in batch]

Expand Down Expand Up @@ -429,8 +425,6 @@ class OpenFgaClient:
return results

options = set_heading_if_not_set(options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()))
# TODO: this should be run in parallel
self._check_valid_api_connection(options)

# otherwise, it is not a transaction and it is a batch write requests
writes_response = None
Expand Down Expand Up @@ -512,6 +506,8 @@ class OpenFgaClient:
try:
api_response = self.check(body, options)
return BatchCheckResponse(allowed=api_response.allowed, request=body, response=api_response, error=None)
except (AuthenticationError, UnauthorizedException) as err:
raise err
except Exception as err:
return BatchCheckResponse(allowed=False, request=body, response=None, error=err)

Expand All @@ -529,9 +525,6 @@ class OpenFgaClient:
options = set_heading_if_not_set(options, CLIENT_METHOD_HEADER, "BatchCheck")
options = set_heading_if_not_set(options, CLIENT_BULK_REQUEST_ID_HEADER, str(uuid.uuid4()))

# TODO: this should be run in parallel
self._check_valid_api_connection(options)

max_parallel_requests = {{ clientMaxMethodParallelRequests }}
if options is not None and "max_parallel_requests" in options:
max_parallel_requests = options["max_parallel_requests"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{{>partial_header}}

from {{packageName}}.client.models.tuple import ClientTuple
from {{packageName}}.models.fga_object import FgaObject
from {{packageName}}.models.user_type_filter import UserTypeFilter


Expand All @@ -11,7 +12,7 @@ class ClientListUsersRequest:

def __init__(
self,
object: str = None,
object: FgaObject = None,
relation: str = None,
user_filters: list[UserTypeFilter] = None,
contextual_tuples: list[ClientTuple] = None,
Expand All @@ -24,7 +25,7 @@ class ClientListUsersRequest:
self._context = context

@property
def object(self):
def object(self) -> FgaObject:
"""Gets the object of this ClientListUsersRequest.


Expand All @@ -34,7 +35,7 @@ class ClientListUsersRequest:
return self._object

@object.setter
def object(self, object):
def object(self, object: FgaObject):
"""Sets the object of this ClientListUsersRequest.


Expand All @@ -45,7 +46,7 @@ class ClientListUsersRequest:
self._object = object

@property
def relation(self):
def relation(self) -> str:
"""Gets the relation of this ClientListUsersRequest.


Expand All @@ -55,7 +56,7 @@ class ClientListUsersRequest:
return self._relation

@relation.setter
def relation(self, relation):
def relation(self, relation: str):
"""Sets the relation of this ClientListUsersRequest.


Expand All @@ -66,7 +67,7 @@ class ClientListUsersRequest:
self._relation = relation

@property
def user_filters(self):
def user_filters(self) -> list[UserTypeFilter]:
"""Gets the user_filters of this ClientListUsersRequest.


Expand All @@ -76,7 +77,7 @@ class ClientListUsersRequest:
return self._user_filters

@user_filters.setter
def user_filters(self, user_filters):
def user_filters(self, user_filters: list[UserTypeFilter]):
"""Sets the user_filters of this ClientListUsersRequest.


Expand All @@ -87,7 +88,7 @@ class ClientListUsersRequest:
self._user_filters = user_filters

@property
def contextual_tuples(self):
def contextual_tuples(self) -> list[ClientTuple]:
"""Gets the contextual_tuples of this ClientListUsersRequest.


Expand All @@ -97,7 +98,7 @@ class ClientListUsersRequest:
return self._contextual_tuples

@contextual_tuples.setter
def contextual_tuples(self, contextual_tuples):
def contextual_tuples(self, contextual_tuples: list[ClientTuple]):
"""Sets the contextual_tuples of this ClientListUsersRequest.


Expand All @@ -108,7 +109,7 @@ class ClientListUsersRequest:
self._contextual_tuples = contextual_tuples

@property
def context(self):
def context(self) -> object:
"""Gets the context of this ClientListUsersRequest.

Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation.
Expand All @@ -119,7 +120,7 @@ class ClientListUsersRequest:
return self._context

@context.setter
def context(self, context):
def context(self, context: object):
"""Sets the context of this ClientListUsersRequest.

Additional request context that will be used to evaluate any ABAC conditions encountered in the query evaluation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ class ClientTuple:
ClientTuple encapsulates the client tuple
"""

def __init__(self, user: str, relation: str, object: str, condition: RelationshipCondition = None):
def __init__(
self,
user: str,
relation: str,
object: str,
condition: RelationshipCondition | None = None,
):
self._user = user
self._relation = relation
self._object = object
Expand Down
Loading
Loading