Skip to content

Commit

Permalink
feat(python-sdk): Introduce synchronous OpenFgaClient
Browse files Browse the repository at this point in the history
  • Loading branch information
booniepepper committed Oct 20, 2023
1 parent 7b2d673 commit 5185beb
Show file tree
Hide file tree
Showing 12 changed files with 383 additions and 263 deletions.
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,23 @@ tag-client-python: test-client-python

.PHONY: build-client-python
build-client-python:
make build-client sdk_language=python tmpdir=${TMP_DIR} package_name=openfga_sdk_sync
make run-in-docker sdk_language=python image=busybox:${BUSYBOX_DOCKER_TAG} command="/bin/sh -c 'patch -p1 /module/openfga_sdk_sync/api/open_fga_api.py /config/clients/python/patches/open_fga_sync_api.py.patch'"
make run-in-docker sdk_language=python image=busybox:${BUSYBOX_DOCKER_TAG} command="/bin/sh -c 'mv /module/openfga_sdk/* /module/openfga_sdk_sync/ && rmdir /module/openfga_sdk'"

make build-client sdk_language=python tmpdir=${TMP_DIR} library="asyncio"
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/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 pycodestyle==2.10.0 autopep8==2.0.2; autopep8 --in-place --ignore E402 --recursive openfga_sdk; autopep8 --in-place --recursive test'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install pycodestyle==2.10.0 autopep8==2.0.2; autopep8 --in-place --ignore E402 --recursive openfga_sdk_sync; autopep8 --in-place --recursive test'"
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
test-client-python: build-client-python
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install -r test-requirements.txt; python -m unittest test/*'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install -r test-requirements.txt; python -m flake8 --ignore F401,E402,E501,W504 openfga_sdk'"
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install -r test-requirements.txt; python -m flake8 --ignore F401,E402,E501,W504 openfga_sdk_sync'"
# Need to ignore E402 (import order) to avoid circular dependency
make run-in-docker sdk_language=python image=python:${PYTHON_DOCKER_TAG} command="/bin/sh -c 'python -m pip install -r test-requirements.txt; python -m flake8 --ignore E501 test'"

Expand Down Expand Up @@ -161,7 +168,7 @@ run-in-docker:
.EXPORT_ALL_VARIABLES:
.PHONY: build-client
build-client: build-openapi
SDK_LANGUAGE="${sdk_language}" TMP_DIR="${tmpdir}" LIBRARY_TEMPLATE="${library}" \
SDK_LANGUAGE="${sdk_language}" TMP_DIR="${tmpdir}" LIBRARY_TEMPLATE="${library}" PACKAGE_NAME="${package_name}"\
./scripts/build_client.sh

.PHONY: build-openapi
Expand Down
68 changes: 68 additions & 0 deletions config/clients/python/patches/open_fga_sync_api.py.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
--- clients/fga-python-sdk/openfga_sdk_sync/api/open_fga_api.py 2022-09-13 14:15:46.000000000 -0400
+++ open_fga_api.py 2022-09-13 14:14:01.000000000 -0400
@@ -197,13 +197,15 @@
collection_formats=collection_formats,
_request_auth=local_var_params.get('_request_auth'))

- def create_store(self, **kwargs): # noqa: E501
+ def create_store(self, body, **kwargs): # noqa: E501
"""Create a store # noqa: E501

Create a unique OpenFGA store which will be used to store authorization models and relationship tuples. # noqa: E501

- >>> thread = api.create_store()
+ >>> thread = api.create_store(body)

+ :param body: (required)
+ :type body: CreateStoreRequest
:param async_req: Whether to execute the request asynchronously.
:type async_req: bool, optional
:param _preload_content: if False, the urllib3.HTTPResponse object will
@@ -216,15 +218,17 @@
:rtype: CreateStoreResponse
"""
kwargs['_return_http_data_only'] = True
- return self.create_store_with_http_info(**kwargs) # noqa: E501
+ return self.create_store_with_http_info(body, **kwargs) # noqa: E501

- def create_store_with_http_info(self, **kwargs): # noqa: E501
+ def create_store_with_http_info(self, body, **kwargs): # noqa: E501
"""Create a store # noqa: E501

Create a unique OpenFGA store which will be used to store authorization models and relationship tuples. # noqa: E501

- >>> thread = api.create_store_with_http_info()
+ >>> thread = api.create_store_with_http_info(body)

+ :param body: (required)
+ :type body: CreateStoreRequest
: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
@@ -253,6 +257,8 @@

all_params = [

+ 'body'
+
]
all_params.extend(
[
@@ -312,7 +318,7 @@
}

return self.api_client.call_api(
- '/stores'.replace('{store_id}', store_id), 'POST',
+ '/stores', 'POST',
path_params,
query_params,
header_params,
@@ -998,7 +1004,7 @@
}

return self.api_client.call_api(
- '/stores'.replace('{store_id}', store_id), 'GET',
+ '/stores', 'GET',
path_params,
query_params,
header_params,
18 changes: 14 additions & 4 deletions config/clients/python/template/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class {{classname}}(object):
api_client = ApiClient()
self.api_client = api_client

{{#asyncio}}
{{#asyncio}}
async def __aenter__(self):
return self

Expand All @@ -37,7 +37,17 @@ class {{classname}}(object):

async def close(self):
await self.api_client.close()
{{/asyncio}}
{{/asyncio}}
{{^asyncio}}
def __enter__(self):
return self

def __exit__(self):
self.close()

def close(self):
self.api_client.close()
{{/asyncio}}

{{#operation}}

Expand All @@ -49,10 +59,10 @@ class {{classname}}(object):
{{/notes}}

{{#sortParamsByRequiredFlag}}
>>> thread = await api.{{operationId}}({{#allParams}}{{#required}}{{^-first}}{{paramName}}{{^-last}}, {{/-last}}{{/-first}}{{/required}}{{/allParams}})
>>> thread = {{#asyncio}}await {{/asyncio}}api.{{operationId}}({{#allParams}}{{#required}}{{^-first}}{{paramName}}{{^-last}}, {{/-last}}{{/-first}}{{/required}}{{/allParams}})
{{/sortParamsByRequiredFlag}}
{{^sortParamsByRequiredFlag}}
>>> thread = await api.{{operationId}}({{#allParams}}{{#required}}{{^-first}}{{paramName}}={{paramName}}_value{{^-last}}, {{/-last}} {{/-first}}{{/required}}{{/allParams}})
>>> thread = {{#asyncio}}await {{/asyncio}}api.{{operationId}}({{#allParams}}{{#required}}{{^-first}}{{paramName}}={{paramName}}_value{{^-last}}, {{/-last}} {{/-first}}{{/required}}{{/allParams}})
{{/sortParamsByRequiredFlag}}

{{#requiredParams}}
Expand Down
6 changes: 5 additions & 1 deletion config/clients/python/template/api_client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
{{#asyncio}}
import asyncio
{{/asyncio}}
{{^asyncio}}
import time
{{/asyncio}}
import atexit
import datetime
from dateutil.parser import parse
Expand Down Expand Up @@ -222,7 +225,8 @@ class ApiClient(object):
_request_timeout=_request_timeout)
except RateLimitExceededError as e:
if x < max_retry:
{{#asyncio}}await asyncio{{/asyncio}}.sleep(random_time(x, min_wait_in_ms))
{{#asyncio}}await asyncio.sleep(random_time(x, min_wait_in_ms)){{/asyncio}}
{{^asyncio}}time.sleep(random_time(x, min_wait_in_ms)){{/asyncio}}
continue
e.body = e.body.decode('utf-8') if six.PY3 else e.body
response_type = response_types_map.get(e.status, None)
Expand Down
Loading

0 comments on commit 5185beb

Please sign in to comment.