From f0777d12e7a2a3c68001b16c56ec486cf1a2b918 Mon Sep 17 00:00:00 2001 From: Adrian Tam Date: Thu, 25 Aug 2022 11:56:57 -0400 Subject: [PATCH 1/4] feat: adding python SDK to docs Close https://github.com/openfga/openfga.dev/issues/178 --- .github/workflows/markdown.links.config.json | 6 +++ .../getting-started/configure-model.mdx | 3 +- docs/content/getting-started/create-store.mdx | 31 +++++++++++++ docs/content/getting-started/install-sdk.mdx | 22 +++++++++ .../content/getting-started/perform-check.mdx | 8 +++- .../getting-started/setup-sdk-client.mdx | 43 ++++++++++++++++++ .../content/getting-started/update-tuples.mdx | 9 +++- .../interacting/read-tuple-changes.mdx | 18 ++++++++ docusaurus.config.js | 8 ++++ .../Docs/SnippetViewer/CheckRequestViewer.tsx | 31 +++++++++++++ .../SnippetViewer/ExpandRequestViewer.tsx | 13 ++++++ .../ListObjectsRequestViewer.tsx | 28 ++++++++++++ .../ReadChangesRequestViewer.tsx | 22 +++++++++ .../Docs/SnippetViewer/ReadRequestViewer.tsx | 16 +++++++ .../Docs/SnippetViewer/SdkSetup.tsx | 17 +++++++ .../Docs/SnippetViewer/SupportedLanguage.tsx | 3 ++ .../SnippetViewer/WriteAuthzModelViewer.tsx | 21 +++++++++ .../Docs/SnippetViewer/WriteRequestViewer.tsx | 45 +++++++++++++++++++ 18 files changed, 341 insertions(+), 3 deletions(-) diff --git a/.github/workflows/markdown.links.config.json b/.github/workflows/markdown.links.config.json index beca0ac658..a858a7c6eb 100644 --- a/.github/workflows/markdown.links.config.json +++ b/.github/workflows/markdown.links.config.json @@ -23,6 +23,12 @@ }, { "pattern": "https://github.com/openfga/dotnet-sdk" + }, + { + "pattern": "https://github.com/openfga/python-sdk" + }, + { + "pattern": "https://pypi.org/project/openfga-sdk" } ], "httpHeaders": [ diff --git a/docs/content/getting-started/configure-model.mdx b/docs/content/getting-started/configure-model.mdx index 97682e2781..4671f39379 100644 --- a/docs/content/getting-started/configure-model.mdx +++ b/docs/content/getting-started/configure-model.mdx @@ -29,7 +29,7 @@ This article explains how to configure an -{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK].map(lang => +{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, SupportedLanguage.PYTHON_SDK].map(lang => 1. @@ -97,6 +97,7 @@ To configure authorization model, we can invoke the [write authorization models SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> diff --git a/docs/content/getting-started/create-store.mdx b/docs/content/getting-started/create-store.mdx index 397c3aa91a..8d9827e183 100644 --- a/docs/content/getting-started/create-store.mdx +++ b/docs/content/getting-started/create-store.mdx @@ -97,6 +97,37 @@ class MyProgram { + + +```python +import os +import openfga_sdk +from openfga_sdk.api import open_fga_api +from openfga_sdk.model.create_store_request import CreateStoreRequest + + +configuration = openfga_sdk.Configuration( + scheme = os.environ.get('FGA_API_SCHEME') + api_host = os.environ.get('FGA_API_HOST'), +) + +# Create an instance of the API class +fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration)) + +try: + # Create a store + body = CreateStoreRequest( + name = "FGA Demo", + ) + api_response = fga_client_instance.create_store(body) +except openfga_sdk.ApiException as e: + print("Exception when calling OpenFgaApi->create_store: %s\n" % e) + +``` + + + + ```console diff --git a/docs/content/getting-started/install-sdk.mdx b/docs/content/getting-started/install-sdk.mdx index bdf0db2415..0665d7a1a7 100644 --- a/docs/content/getting-started/install-sdk.mdx +++ b/docs/content/getting-started/install-sdk.mdx @@ -101,6 +101,23 @@ Install-Package OpenFGA.Sdk - [Visual Studio](https://docs.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio), [Visual Studio for Mac](https://docs.microsoft.com/en-us/visualstudio/mac/nuget-walkthrough) and [IntelliJ Rider](https://www.jetbrains.com/help/rider/Using_NuGet.html): Search for and install `OpenFGA.Sdk` in each of their respective package manager UIs. + + + +The Python SDK is available on [PyPI](https://pypi.org/project/openfga-sdk/). + +To install: + +``` +pip install openfga_sdk +``` + +In your code, import the module and use it: + +```python +import openfga_sdk +``` + @@ -126,5 +143,10 @@ Install-Package OpenFGA.Sdk description: 'Connect your .NET service with {ProductName} using our .NET SDK', link: 'https://github.com/openfga/dotnet-sdk', }, + { + title: '{ProductName} Python SDK', + description: 'Connect your Python service with {ProductName} using our .NET SDK', + link: 'https://github.com/openfga/python-sdk', + }, ]} /> diff --git a/docs/content/getting-started/perform-check.mdx b/docs/content/getting-started/perform-check.mdx index ebd4ca42fc..5c0c6917c8 100644 --- a/docs/content/getting-started/perform-check.mdx +++ b/docs/content/getting-started/perform-check.mdx @@ -28,7 +28,7 @@ This section will illustrate how to perform a -{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK].map(lang => +{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, SupportedLanguage.PYTHON_SDK].map(lang => 1. @@ -70,6 +70,11 @@ Before calling the check API, you will need to configure the API client. + + + + + @@ -94,6 +99,7 @@ To check whether user `anne` has relationship `reader` with object `document:Z` SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> diff --git a/docs/content/getting-started/setup-sdk-client.mdx b/docs/content/getting-started/setup-sdk-client.mdx index b9a5e9bd34..cbe728c244 100644 --- a/docs/content/getting-started/setup-sdk-client.mdx +++ b/docs/content/getting-started/setup-sdk-client.mdx @@ -86,6 +86,27 @@ class MyProgram { ``` + + +```python +import os +import openfga_sdk +from openfga_sdk.api import open_fga_api + + +configuration = openfga_sdk.Configuration( + scheme = os.environ.get('FGA_API_SCHEME') + api_host = os.environ.get('FGA_API_HOST'), + store_id = os.environ.get('FGA_STORE_ID') +) + +# Create an instance of the API class +fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration)) + +``` + + + ## Using Shared Key Authentication @@ -167,5 +188,27 @@ class MyProgram { } ``` + + + +```python +import os +import openfga_sdk +from openfga_sdk.api import open_fga_api +from open_fga_api.credentials import Credentials, CredentialConfiguration + + +credentials = Credentials(method='api_token', + configuration=CredentialConfiguration(api_token=os.environ.get(FGA_BEARER_TOKEN))) +configuration = openfga_sdk.Configuration( + scheme = os.environ.get(OPENFGA_API_SCHEME), + api_host = os.environ.get(OPENFGA_API_HOST), + credentials = credentials) + +# Create an instance of the API class +fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration)) + +``` + diff --git a/docs/content/getting-started/update-tuples.mdx b/docs/content/getting-started/update-tuples.mdx index fa68a6cb6d..9c36a71b1a 100644 --- a/docs/content/getting-started/update-tuples.mdx +++ b/docs/content/getting-started/update-tuples.mdx @@ -28,7 +28,7 @@ This section will illustrate how to update _ -{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK].map(lang => +{[SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, SupportedLanguage.PYTHON_SDK].map(lang => 1. @@ -78,6 +78,11 @@ Before calling the write API, you will need to configure the API client. + + + + + @@ -105,6 +110,7 @@ To add the relationship tuples, we can invoke the write API. SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> @@ -136,6 +142,7 @@ Assume that you want to delete user `anne`'s `reader` relationship with object ` SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> diff --git a/docs/content/interacting/read-tuple-changes.mdx b/docs/content/interacting/read-tuple-changes.mdx index fdd777bab9..f284624ae7 100644 --- a/docs/content/interacting/read-tuple-changes.mdx +++ b/docs/content/interacting/read-tuple-changes.mdx @@ -51,6 +51,14 @@ This section illustrates how to call the Read Changes API to get the list of rel 3. You have [configured the _authorization model_](../modeling). 4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. + + + +1. +2. You have [installed the SDK](../getting-started/install-sdk.mdx). +3. You have [configured the _authorization model_](../modeling). +4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. + @@ -87,6 +95,12 @@ First you will need to configure the API client. + + + + + + To obtain the [access token](https://auth0.com/docs/authorization/flows/call-your-api-using-the-client-credentials-flow): @@ -108,6 +122,7 @@ To get a paginated list of changes that happened in your store: SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> @@ -124,6 +139,7 @@ You can then use this token to get the next set of changes: SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> @@ -182,6 +198,7 @@ It is possible to get a list of changes that happened in your store that relate SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> @@ -197,6 +214,7 @@ The response will include a continuation token. In subsequent calls, you have to SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]} /> \ No newline at end of file diff --git a/docusaurus.config.js b/docusaurus.config.js index 103d6e058e..4b365bb7fd 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -99,6 +99,14 @@ using OpenFga.Sdk.Configuration;`, apiName: `OpenFgaApi`, setupNote: `// ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.\n`, }, + python: { + importStatement: `import os +import json +import openfga_sdk +from openfga_sdk.api import open_fga_api`, + apiName: `OpenFgaApi`, + setupNote: `# ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.\n`, + } }, contentSecurityPolicy: `default-src 'none'; base-uri 'self'; diff --git a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx index bd12f99e0b..c7e0127d9e 100644 --- a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx @@ -126,6 +126,36 @@ var response = await fgaClient.Check(new CheckRequest(new TupleKey() { }); // response.Allowed = ${allowed}`; + case SupportedLanguage.PYTHON_SDK: + return ` +# Run a check +body = openfga_sdk.model.check_request.CheckRequest( + tuple_key=openfga_sdk.model.tuple_key.TupleKey( + user="${user}", + relation="${relation}", + object="${object}", + ), +${ + contextualTuples + ? ` + contextual_tuples=openfga_sdk.model.contextual_tuple_keys.ContextualTupleKeys( + tuple_keys=[ + ${contextualTuples + .map( + (tuple) => + `openfga_sdk.model.tuple_key.TupleKey(user="${tuple.user}", relation="${tuple.relation}", object="${tuple.object}")`, + ) + .join(',\n ')} + ], + ), +` + : `` +} +) +response = fga_client_instance.check(body) +# response.allowed = ${allowed} + +`; case SupportedLanguage.RPC: return `check( "${user}", // check if the user \`${user}\` @@ -154,6 +184,7 @@ export function CheckRequestViewer(opts: CheckRequestViewerOpts): JSX.Element { SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, SupportedLanguage.RPC, ]; diff --git a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx index b2223040a3..8279071515 100644 --- a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx @@ -64,6 +64,18 @@ var response = await fgaClient.Expand(new ExpandRequest(new TupleKey() { Reply: {tree:...}`; + case SupportedLanguage.PYTHON_SDK: + return ` +body = openfga_sdk.model.expand_request.ExpandRequest( + tuple_key=openfga_sdk.model.tuple_key.TupleKey( + relation: "${opts.relation}", + object: "${opts.object}", + ) +) +response = fga_client_instance.expand(body) +# response = openfga_sdk.model.expand_response.ExpandResponse({"tree":...}) +`; + case SupportedLanguage.PLAYGROUND: return ''; default: @@ -76,6 +88,7 @@ export function ExpandRequestViewer(opts: ExpandRequestViewerOpts): JSX.Element SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, SupportedLanguage.RPC, ]; diff --git a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx index 2b4e2cac40..52528af51b 100644 --- a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx @@ -138,6 +138,33 @@ data, response, err := apiClient.${ var response = await openFgaApi.ListObjects(body); // response.ObjectIds = [${expectedResults.map((r) => `"${r}"`).join(', ')}]`; + case SupportedLanguage.PYTHON_SDK: + return ` +body = openfga_sdk.model.list_objects_request.ListObjectsRequest(${ + authorizationModelId ? `authorization_model_id="${authorizationModelId}",` : `` + } + user="${user}", + relation="${relation}", + type="${objectType}",${ + contextualTuples?.length + ? ` + contextual_tuples=openfga_sdk.model.contextual_tuple_keys.ContextualTupleKeys( + tuple_keys=[ + ${contextualTuples + .map( + (tupleKey) => `openfga_sdk.model.tuple_key.TupleKeys( + user="${tupleKey.user}", + relation="${tupleKey.relation}", + object="${tupleKey.object}")`, + ) + .join(',\n ')} + ] + )` + : `` + } +) +response = fga_client_instance.list_objects(body) +`; case SupportedLanguage.RPC: return `listObjects( "${user}", // list the objects that the user \`${user}\` @@ -170,6 +197,7 @@ export function ListObjectsRequestViewer(opts: ListObjectsRequestViewerOpts): JS SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, SupportedLanguage.RPC, ]; diff --git a/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx b/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx index 5f9e5f7bd3..e983e96d45 100644 --- a/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx @@ -63,6 +63,27 @@ if err != nil { await fgaClient.ReadChanges(type, pageSize, continuationToken);`; } + case SupportedLanguage.PYTHON_SDK: { + return ` +response = fga_client_instance.read_changes(${ + opts.type + ? ` + type="${opts.type}",` + : `` + }${ + opts.pageSize + ? ` + page_size="${opts.pageSize}",` + : `` + }${ + opts.continuationToken + ? ` + continuation_token="${opts.continuationToken}",` + : `` + } +)`; + } + default: { return ``; } @@ -75,6 +96,7 @@ export function ReadChangesRequestViewer(opts: ReadChangesRequestViewerOpts): JS SupportedLanguage.GO_SDK, SupportedLanguage.CURL, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, ]; const allowedLanguages = getFilteredAllowedLangs(opts.allowedLanguages, defaultLangs); return defaultOperationsViewer(allowedLanguages, opts, readChangesRequestViewer); diff --git a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx index 3dae954c13..74796dd02b 100644 --- a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx @@ -92,6 +92,21 @@ var response = fgaClient.Read(new ReadRequest(new TupleKey() { })); // data = { "tuples": [${readTuples}] }`; + } + case SupportedLanguage.PYTHON_SDK: { + const requestTuples = + (opts.user ? ` user="${opts.user}",\n` : '') + + (opts.relation ? ` relation="${opts.relation}",\n` : '') + + ` object="${opts.object}",\n`; + + return ` +body = openfga_sdk.model.read_request.ReadRequest( + tuple_key=openfga_sdk.model.tuple_key.TupleKey( +${requestTuples} + ) +) +response = fga_client_instance.read(body) +# response = openfga_sdk.model.read_response.ReadResponse({"tuples":[${readTuples}]})`; } case SupportedLanguage.RPC: { const objectOrType = opts.object.slice(-1) === ':' ? 'type' : 'object'; @@ -133,6 +148,7 @@ export function ReadRequestViewer(opts: ReadRequestViewerOpts): JSX.Element { SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, SupportedLanguage.RPC, ]; diff --git a/src/components/Docs/SnippetViewer/SdkSetup.tsx b/src/components/Docs/SnippetViewer/SdkSetup.tsx index 0ee7501bab..8c305e9e7a 100644 --- a/src/components/Docs/SnippetViewer/SdkSetup.tsx +++ b/src/components/Docs/SnippetViewer/SdkSetup.tsx @@ -13,6 +13,8 @@ function getMapping(lang: SupportedLanguage, languageMappings: LanguageMappings) return languageMappings['go']; case SupportedLanguage.DOTNET_SDK: return languageMappings['dotnet']; + case SupportedLanguage.PYTHON_SDK: + return languageMappings['python']; } return { importStatement: '', @@ -85,6 +87,20 @@ class MyProgram { var fgaClient = new ${languageMappings['js'].apiName}(configuration); } }`; + /* eslint-enable no-tabs */ + case SupportedLanguage.PYTHON_SDK: + return ` +${importSdkStatement(lang, languageMappings)} + +configuration = openfga_sdk.Configuration( + scheme = os.environ.get('FGA_API_SCHEME'), + host = os.environ.get('FGA_API_HOST'), + store_id = os.environ.get('FGA_STORE_ID') +) + +# Create an instance of the API class +fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration)) +`; case SupportedLanguage.RPC: case SupportedLanguage.PLAYGROUND: throw new Error(`Lang ${lang} support has not been implemented`); @@ -115,6 +131,7 @@ export function GenerateSetupHeader(lang: SupportedLanguage, skipSetup?: boolean case SupportedLanguage.JS_SDK: case SupportedLanguage.GO_SDK: case SupportedLanguage.DOTNET_SDK: + case SupportedLanguage.PYTHON_SDK: content = getMapping(lang, configuredLanguage).setupNote + sdkSetupHeader(lang, configuredLanguage); break; case SupportedLanguage.CURL: diff --git a/src/components/Docs/SnippetViewer/SupportedLanguage.tsx b/src/components/Docs/SnippetViewer/SupportedLanguage.tsx index 7dd27e1454..a2a1f42b3a 100644 --- a/src/components/Docs/SnippetViewer/SupportedLanguage.tsx +++ b/src/components/Docs/SnippetViewer/SupportedLanguage.tsx @@ -2,6 +2,7 @@ export enum SupportedLanguage { JS_SDK = 'js-sdk', GO_SDK = 'go-sdk', DOTNET_SDK = 'dotnet-sdk', + PYTHON_SDK = 'python-sdk', CURL = 'curl', RPC = 'rpc', PLAYGROUND = 'playground', @@ -11,6 +12,7 @@ export const languageLabelMap: Map = new Map([ [SupportedLanguage.JS_SDK, 'Node.js'], [SupportedLanguage.GO_SDK, 'Go'], [SupportedLanguage.DOTNET_SDK, '.NET'], + [SupportedLanguage.PYTHON_SDK, 'Python'], [SupportedLanguage.CURL, 'curl'], [SupportedLanguage.RPC, 'Pseudocode'], [SupportedLanguage.PLAYGROUND, 'Playground'], @@ -20,6 +22,7 @@ export const languageCodeMap: Map = new Map([ [SupportedLanguage.JS_SDK, 'javascript'], [SupportedLanguage.GO_SDK, 'go'], [SupportedLanguage.DOTNET_SDK, 'dotnet'], + [SupportedLanguage.PYTHON_SDK, 'python'], [SupportedLanguage.CURL, 'shell'], [SupportedLanguage.RPC, 'shell'], [SupportedLanguage.PLAYGROUND, 'shell'], diff --git a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx index 71df46f1f0..dfb4e3b282 100644 --- a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx @@ -55,6 +55,22 @@ function writeAuthZModelViewerDotnet(authorizationModel: AuthorizationModel): st // response.AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"`; } +function writeAuthZModelViewerPython(authorizationModel: AuthorizationModel): string { + return ` +body_string = ${JSON.stringify(JSON.stringify(authorizationModel))} +type_definitions = openfga_sdk.model_utils.validate_and_convert_types( + json.loads(body_string), + (openfga_sdk.model.type_definitions.TypeDefinitions,), + ['openfga_sdk.model.type_definitions.TypeDefinitions'], + True, + True, + configuration=configuration +) +response = fga_client_instance.write_authorization_model(type_definitions) +# response.authorization_model_id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw" +`; +} + function writeAuthZModelViewer( lang: SupportedLanguage, opts: WriteAuthzModelViewerOpts, @@ -77,6 +93,10 @@ function writeAuthZModelViewer( return writeAuthZModelViewerDotnet(opts.authorizationModel); } + case SupportedLanguage.PYTHON_SDK: { + return writeAuthZModelViewerPython(opts.authorizationModel); + } + case SupportedLanguage.RPC: case SupportedLanguage.PLAYGROUND: return ''; @@ -90,6 +110,7 @@ export function WriteAuthzModelViewer(opts: WriteAuthzModelViewerOpts): JSX.Elem SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, ]; const allowedLanguages = getFilteredAllowedLangs(opts.allowedLanguages, defaultLangs); diff --git a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx index 1f90e5c85e..5e0b0a35d0 100644 --- a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx @@ -157,6 +157,50 @@ await fgaClient.Write(new WriteRequest{ });`; } + case SupportedLanguage.PYTHON_SDK: { + const writeTuples = opts.relationshipTuples + ? opts.relationshipTuples + .map( + ({ user, relation, object, _description }) => ` + openfga_sdk.model.tuple_key.TupleKey( +${_description ? ` # ${_description}\n ` : ' '}user= "${user}", + relation= "${relation}", + object="${object}", + ),`, + ) + .join('') + : ''; + const deleteTuples = opts.deleteRelationshipTuples + ? opts.deleteRelationshipTuples + .map( + ({ user, relation, object, _description }) => ` + openfga_sdk.model.tuple_key.TupleKey( +${_description ? ` # ${_description}\n ` : ' '}user= "${user}", + relation= "${relation}", + object="${object}", + ),`, + ) + .join('') + : ''; + const writes = ` writes=openfga_sdk.model.tuple_keys.TupleKeys( + tuple_keys= [${writeTuples} + ], + ), +`; + const deletes = ` deletes=openfga_sdk.model.tuple_keys.TupleKeys( + tuple_keys= [${deleteTuples} + ], + ), +`; + + return ` +body = openfga_sdk.model.write_request.WriteRquest( +${opts.relationshipTuples ? writes : ''}${opts.deleteRelationshipTuples ? deletes : ''} +) +response = fga_client_instance.write(body) +`; + } + case SupportedLanguage.RPC: { const writeTuples = opts.relationshipTuples ?.map( @@ -211,6 +255,7 @@ export function WriteRequestViewer(opts: WriteRequestViewerOpts): JSX.Element { SupportedLanguage.JS_SDK, SupportedLanguage.GO_SDK, SupportedLanguage.DOTNET_SDK, + SupportedLanguage.PYTHON_SDK, SupportedLanguage.CURL, SupportedLanguage.RPC, ]; From 066ad99bdccbd698bec1d059670aa975a5883af4 Mon Sep 17 00:00:00 2001 From: Adrian Tam Date: Thu, 25 Aug 2022 15:07:56 -0400 Subject: [PATCH 2/4] feat: mention Python SDK in overview --- docs/README.md | 2 +- docs/content/authorization-and-openfga.mdx | 2 +- docs/content/getting-started/install-sdk.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 24a72b0d72..bcb62b798c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ hide_title: true ## About OpenFGA -[OpenFGA](https://github.com/openfga/openfga) is an open source Fine-Grained Authorization solution based on Google's Zanzibar. It was created by the Auth0 FGA team and welcomes community contribution. OpenFGA is designed to make it easy for application builders to quickly add fine-grained authorization to their applications. It offers an HTTP API and has SDKs for programming languages including [JavaScript](https://github.com/openfga/js-sdk), [GoLang](https://github.com/openfga/go-sdk) and [.NET](https://github.com/openfga/dotnet-sdk). More SDKs and integrations such as Rego are planned for the future. OpenFGA is designed and optimized for reliability and low latency at a high scale. +[OpenFGA](https://github.com/openfga/openfga) is an open source Fine-Grained Authorization solution based on Google's Zanzibar. It was created by the Auth0 FGA team and welcomes community contribution. OpenFGA is designed to make it easy for application builders to quickly add fine-grained authorization to their applications. It offers an HTTP API and has SDKs for programming languages including [JavaScript](https://github.com/openfga/js-sdk), [GoLang](https://github.com/openfga/go-sdk), [.NET](https://github.com/openfga/dotnet-sdk) and [Python](https://github.com/openfga/python-sdk). More SDKs and integrations such as Rego are planned for the future. OpenFGA is designed and optimized for reliability and low latency at a high scale. ## Resources diff --git a/docs/content/authorization-and-openfga.mdx b/docs/content/authorization-and-openfga.mdx index e4a8d4d4d8..13b13a4e91 100644 --- a/docs/content/authorization-and-openfga.mdx +++ b/docs/content/authorization-and-openfga.mdx @@ -15,7 +15,7 @@ This section explains [authorization](#authentication-vs-authorization), [fine-g ## What Is OpenFGA? -**OpenFGA** is an open source solution to [Fine-Grained Authorization](#what-is-fine-grained-authorization-fga) that applies the concept of [ReBAC](#what-is-relationship-based-access-control-rebac). It was created by the [Auth0 FGA](https://docs.fga.dev/) team and was inspired by [Zanzibar](#what-is-zanzibar). It was designed for reliability and low latency at a high scale. It offers an HTTP API and has SDKs for programming languages including [Node.js/JavaScript](https://www.npmjs.com/package/@openfga/sdk), [GoLang](https://github.com/openfga/go-sdk) and [.NET](https://www.nuget.org/packages/OpenFga.Sdk). More SDKs and integrations such as Rego are planned for the future. +**OpenFGA** is an open source solution to [Fine-Grained Authorization](#what-is-fine-grained-authorization-fga) that applies the concept of [ReBAC](#what-is-relationship-based-access-control-rebac). It was created by the [Auth0 FGA](https://docs.fga.dev/) team and was inspired by [Zanzibar](#what-is-zanzibar). It was designed for reliability and low latency at a high scale. It offers an HTTP API and has SDKs for programming languages including [Node.js/JavaScript](https://www.npmjs.com/package/@openfga/sdk), [GoLang](https://github.com/openfga/go-sdk), [.NET](https://www.nuget.org/packages/OpenFga.Sdk) and [Python](https://pypi.org/project/openfga-sdk). More SDKs and integrations such as Rego are planned for the future. diff --git a/docs/content/getting-started/install-sdk.mdx b/docs/content/getting-started/install-sdk.mdx index 0665d7a1a7..ce172168e8 100644 --- a/docs/content/getting-started/install-sdk.mdx +++ b/docs/content/getting-started/install-sdk.mdx @@ -104,7 +104,7 @@ Install-Package OpenFGA.Sdk -The Python SDK is available on [PyPI](https://pypi.org/project/openfga-sdk/). +The Python SDK is available on [PyPI](https://pypi.org/project/openfga-sdk). To install: From e5d7e037a8e146a58b1aa20ec83ae0620222793a Mon Sep 17 00:00:00 2001 From: Adrian Tam Date: Wed, 31 Aug 2022 14:59:06 -0400 Subject: [PATCH 3/4] fix: update based on code review --- docs/content/getting-started/install-sdk.mdx | 2 +- .../content/getting-started/setup-sdk-client.mdx | 3 +-- docs/content/interacting/read-tuple-changes.mdx | 10 +++++----- .../Docs/SnippetViewer/CheckRequestViewer.tsx | 16 +++++++++------- .../Docs/SnippetViewer/ExpandRequestViewer.tsx | 10 +++++++--- .../SnippetViewer/ListObjectsRequestViewer.tsx | 12 +++++++----- .../Docs/SnippetViewer/ReadRequestViewer.tsx | 10 +++++++--- src/components/Docs/SnippetViewer/SdkSetup.tsx | 4 ++-- .../Docs/SnippetViewer/WriteAuthzModelViewer.tsx | 6 ++++-- .../Docs/SnippetViewer/WriteRequestViewer.tsx | 14 +++++++++----- 10 files changed, 52 insertions(+), 35 deletions(-) diff --git a/docs/content/getting-started/install-sdk.mdx b/docs/content/getting-started/install-sdk.mdx index ce172168e8..964edb9941 100644 --- a/docs/content/getting-started/install-sdk.mdx +++ b/docs/content/getting-started/install-sdk.mdx @@ -109,7 +109,7 @@ The Python SDK is available To install: ``` -pip install openfga_sdk +pip3 install openfga_sdk ``` In your code, import the module and use it: diff --git a/docs/content/getting-started/setup-sdk-client.mdx b/docs/content/getting-started/setup-sdk-client.mdx index cbe728c244..760126be78 100644 --- a/docs/content/getting-started/setup-sdk-client.mdx +++ b/docs/content/getting-started/setup-sdk-client.mdx @@ -93,9 +93,8 @@ import os import openfga_sdk from openfga_sdk.api import open_fga_api - configuration = openfga_sdk.Configuration( - scheme = os.environ.get('FGA_API_SCHEME') + api_scheme = os.environ.get('FGA_API_SCHEME') api_host = os.environ.get('FGA_API_HOST'), store_id = os.environ.get('FGA_STORE_ID') ) diff --git a/docs/content/interacting/read-tuple-changes.mdx b/docs/content/interacting/read-tuple-changes.mdx index f284624ae7..0e8a5f7ad5 100644 --- a/docs/content/interacting/read-tuple-changes.mdx +++ b/docs/content/interacting/read-tuple-changes.mdx @@ -32,7 +32,7 @@ This section illustrates how to call the Read Changes API to get the list of rel 1. 2. You have [installed the SDK](../getting-started/install-sdk.mdx). 3. You have [configured the _authorization model_](../modeling) and [added some _relationship tuples_](../getting-started/update-tuples.mdx#02-calling-write-api-to-add-new-relationship-tuples). -4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. +4. You have loaded `FGA_STORE_ID` and `FGA_API_HOST` as environment variables. @@ -40,7 +40,7 @@ This section illustrates how to call the Read Changes API to get the list of rel 1. 2. You have [installed the SDK](../getting-started/install-sdk.mdx). 3. You have [configured the _authorization model_](../modeling) and [added some _relationship tuples_](../getting-started/update-tuples.mdx#02-calling-write-api-to-add-new-relationship-tuples). -4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. +4. You have loaded `FGA_STORE_ID` and `FGA_API_HOST` as environment variables. @@ -49,7 +49,7 @@ This section illustrates how to call the Read Changes API to get the list of rel 1. 2. You have [installed the SDK](../getting-started/install-sdk.mdx). 3. You have [configured the _authorization model_](../modeling). -4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. +4. You have loaded `FGA_STORE_ID` and `FGA_API_HOST` as environment variables. @@ -57,14 +57,14 @@ This section illustrates how to call the Read Changes API to get the list of rel 1. 2. You have [installed the SDK](../getting-started/install-sdk.mdx). 3. You have [configured the _authorization model_](../modeling). -4. You have loaded `FGA_ENVIRONMENT`, `FGA_STORE_ID`, `FGA_CLIENT_ID` and `FGA_CLIENT_SECRET` as environment variables. +4. You have loaded `FGA_STORE_ID` and `FGA_API_HOST` as environment variables. 1. 2. You have [configured the _authorization model_](../modeling) and [added some _relationship tuples_](../getting-started/update-tuples.mdx#02-calling-write-api-to-add-new-relationship-tuples). -3. You have loaded `FGA_ENVIRONMENT`, `FGA_BEARER_TOKEN` and `FGA_STORE_ID` as environment variables. +3. You have loaded `FGA_STORE_ID` and `FGA_API_HOST` as environment variables. diff --git a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx index c7e0127d9e..033dc4afe5 100644 --- a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx @@ -128,9 +128,14 @@ var response = await fgaClient.Check(new CheckRequest(new TupleKey() { // response.Allowed = ${allowed}`; case SupportedLanguage.PYTHON_SDK: return ` +# from openfga_sdk.model.check_request import CheckRequest +# from openfga_sdk.model.tuple_key import TupleKey +# from openfga_sdk.model.contextual_tuple_keys import ContextualTupleKeys + # Run a check -body = openfga_sdk.model.check_request.CheckRequest( - tuple_key=openfga_sdk.model.tuple_key.TupleKey( + +body = CheckRequest( + tuple_key=TupleKey( user="${user}", relation="${relation}", object="${object}", @@ -138,13 +143,10 @@ body = openfga_sdk.model.check_request.CheckRequest( ${ contextualTuples ? ` - contextual_tuples=openfga_sdk.model.contextual_tuple_keys.ContextualTupleKeys( + contextual_tuples=ContextualTupleKeys( tuple_keys=[ ${contextualTuples - .map( - (tuple) => - `openfga_sdk.model.tuple_key.TupleKey(user="${tuple.user}", relation="${tuple.relation}", object="${tuple.object}")`, - ) + .map((tuple) => `TupleKey(user="${tuple.user}", relation="${tuple.relation}", object="${tuple.object}")`) .join(',\n ')} ], ), diff --git a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx index 8279071515..54e6948a22 100644 --- a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx @@ -66,14 +66,18 @@ Reply: {tree:...}`; case SupportedLanguage.PYTHON_SDK: return ` -body = openfga_sdk.model.expand_request.ExpandRequest( - tuple_key=openfga_sdk.model.tuple_key.TupleKey( +# from openfga_sdk.model.expand_request import ExpandRequest +# from openfga_sdk.model.expand_response import ExpandResponse +# from openfga_sdk.model.tuple_key import TupleKey + +body = ExpandRequest( + tuple_key=TupleKey( relation: "${opts.relation}", object: "${opts.object}", ) ) response = fga_client_instance.expand(body) -# response = openfga_sdk.model.expand_response.ExpandResponse({"tree":...}) +# response = ExpandResponse({"tree":...}) `; case SupportedLanguage.PLAYGROUND: diff --git a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx index 52528af51b..eb17f2659e 100644 --- a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx @@ -140,19 +140,21 @@ var response = await openFgaApi.ListObjects(body); // response.ObjectIds = [${expectedResults.map((r) => `"${r}"`).join(', ')}]`; case SupportedLanguage.PYTHON_SDK: return ` -body = openfga_sdk.model.list_objects_request.ListObjectsRequest(${ - authorizationModelId ? `authorization_model_id="${authorizationModelId}",` : `` - } +# from openfga_sdk.model.list_objects_request import ListObjectsRequest +# from openfga_sdk.model.tuple_key import TupleKey +# from openfga_sdk.model.contextual_tuple_keys import ContextualTupleKeys + +body = ListObjectsRequest(${authorizationModelId ? `authorization_model_id="${authorizationModelId}",` : ``} user="${user}", relation="${relation}", type="${objectType}",${ contextualTuples?.length ? ` - contextual_tuples=openfga_sdk.model.contextual_tuple_keys.ContextualTupleKeys( + contextual_tuples=ContextualTupleKeys( tuple_keys=[ ${contextualTuples .map( - (tupleKey) => `openfga_sdk.model.tuple_key.TupleKeys( + (tupleKey) => `TupleKey( user="${tupleKey.user}", relation="${tupleKey.relation}", object="${tupleKey.object}")`, diff --git a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx index 74796dd02b..089f91a46d 100644 --- a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx @@ -100,13 +100,17 @@ var response = fgaClient.Read(new ReadRequest(new TupleKey() { ` object="${opts.object}",\n`; return ` -body = openfga_sdk.model.read_request.ReadRequest( - tuple_key=openfga_sdk.model.tuple_key.TupleKey( +# from openfga_sdk.model.read_request import ReadRequest +# from openfga_sdk.model.read_response import ReadResponse +# from openfga_sdk.model.tuple_key import TupleKey + +body = ReadRequest( + tuple_key=TupleKey( ${requestTuples} ) ) response = fga_client_instance.read(body) -# response = openfga_sdk.model.read_response.ReadResponse({"tuples":[${readTuples}]})`; +# response = ReadResponse({"tuples":[${readTuples}]})`; } case SupportedLanguage.RPC: { const objectOrType = opts.object.slice(-1) === ':' ? 'type' : 'object'; diff --git a/src/components/Docs/SnippetViewer/SdkSetup.tsx b/src/components/Docs/SnippetViewer/SdkSetup.tsx index 8c305e9e7a..12c5933023 100644 --- a/src/components/Docs/SnippetViewer/SdkSetup.tsx +++ b/src/components/Docs/SnippetViewer/SdkSetup.tsx @@ -93,8 +93,8 @@ class MyProgram { ${importSdkStatement(lang, languageMappings)} configuration = openfga_sdk.Configuration( - scheme = os.environ.get('FGA_API_SCHEME'), - host = os.environ.get('FGA_API_HOST'), + api_scheme = os.environ.get('FGA_API_SCHEME'), + api_host = os.environ.get('FGA_API_HOST'), store_id = os.environ.get('FGA_STORE_ID') ) diff --git a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx index dfb4e3b282..4a479329b8 100644 --- a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx @@ -57,11 +57,13 @@ function writeAuthZModelViewerDotnet(authorizationModel: AuthorizationModel): st function writeAuthZModelViewerPython(authorizationModel: AuthorizationModel): string { return ` +# from openfga_sdk.model.type_definitions import TypeDefinitions + body_string = ${JSON.stringify(JSON.stringify(authorizationModel))} type_definitions = openfga_sdk.model_utils.validate_and_convert_types( json.loads(body_string), - (openfga_sdk.model.type_definitions.TypeDefinitions,), - ['openfga_sdk.model.type_definitions.TypeDefinitions'], + (TypeDefinitions,), + ['TypeDefinitions'], True, True, configuration=configuration diff --git a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx index 5e0b0a35d0..37c0877a64 100644 --- a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx @@ -162,7 +162,7 @@ await fgaClient.Write(new WriteRequest{ ? opts.relationshipTuples .map( ({ user, relation, object, _description }) => ` - openfga_sdk.model.tuple_key.TupleKey( + TupleKey( ${_description ? ` # ${_description}\n ` : ' '}user= "${user}", relation= "${relation}", object="${object}", @@ -174,7 +174,7 @@ ${_description ? ` # ${_description}\n ` : ' ? opts.deleteRelationshipTuples .map( ({ user, relation, object, _description }) => ` - openfga_sdk.model.tuple_key.TupleKey( + TupleKey( ${_description ? ` # ${_description}\n ` : ' '}user= "${user}", relation= "${relation}", object="${object}", @@ -182,19 +182,23 @@ ${_description ? ` # ${_description}\n ` : ' ) .join('') : ''; - const writes = ` writes=openfga_sdk.model.tuple_keys.TupleKeys( + const writes = ` writes=TupleKeys( tuple_keys= [${writeTuples} ], ), `; - const deletes = ` deletes=openfga_sdk.model.tuple_keys.TupleKeys( + const deletes = ` deletes=TupleKeys( tuple_keys= [${deleteTuples} ], ), `; return ` -body = openfga_sdk.model.write_request.WriteRquest( +# from openfga_sdk.model.tuple_key import TupleKey +# from openfga_sdk.model.tuple_keys import TupleKeys +# from openfga_sdk.model.write_request import WriteRequest + +body = WriteRequest( ${opts.relationshipTuples ? writes : ''}${opts.deleteRelationshipTuples ? deletes : ''} ) response = fga_client_instance.write(body) From f5ca62fdfcc6e0db41aefbc48bd4c7cdf829f61c Mon Sep 17 00:00:00 2001 From: Adrian Tam Date: Thu, 22 Sep 2022 13:35:21 -0400 Subject: [PATCH 4/4] feat: switch to use async python (#214) Need to wrap await call with async function --- docs/content/getting-started/create-store.mdx | 19 +++---- .../getting-started/setup-sdk-client.mdx | 5 +- .../Docs/SnippetViewer/CheckRequestViewer.tsx | 53 +++++++++---------- .../SnippetViewer/ExpandRequestViewer.tsx | 21 ++++---- .../ListObjectsRequestViewer.tsx | 43 +++++++-------- .../ReadChangesRequestViewer.tsx | 19 +++---- .../Docs/SnippetViewer/ReadRequestViewer.tsx | 23 ++++---- .../Docs/SnippetViewer/SdkSetup.tsx | 6 +-- .../SnippetViewer/WriteAuthzModelViewer.tsx | 27 +++++----- .../Docs/SnippetViewer/WriteRequestViewer.tsx | 47 ++++++++-------- 10 files changed, 135 insertions(+), 128 deletions(-) diff --git a/docs/content/getting-started/create-store.mdx b/docs/content/getting-started/create-store.mdx index 8d9827e183..06ca86e638 100644 --- a/docs/content/getting-started/create-store.mdx +++ b/docs/content/getting-started/create-store.mdx @@ -103,7 +103,7 @@ class MyProgram { import os import openfga_sdk from openfga_sdk.api import open_fga_api -from openfga_sdk.model.create_store_request import CreateStoreRequest +from openfga_sdk.models.create_store_request import CreateStoreRequest configuration = openfga_sdk.Configuration( @@ -114,14 +114,15 @@ configuration = openfga_sdk.Configuration( # Create an instance of the API class fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration)) -try: - # Create a store - body = CreateStoreRequest( - name = "FGA Demo", - ) - api_response = fga_client_instance.create_store(body) -except openfga_sdk.ApiException as e: - print("Exception when calling OpenFgaApi->create_store: %s\n" % e) +async def create_store(): + try: + # Create a store + body = CreateStoreRequest( + name = "FGA Demo", + ) + api_response = await fga_client_instance.create_store(body) + except openfga_sdk.ApiException as e: + print("Exception when calling OpenFgaApi->create_store: %s\n" % e) ``` diff --git a/docs/content/getting-started/setup-sdk-client.mdx b/docs/content/getting-started/setup-sdk-client.mdx index 760126be78..a65ffa3a2d 100644 --- a/docs/content/getting-started/setup-sdk-client.mdx +++ b/docs/content/getting-started/setup-sdk-client.mdx @@ -200,8 +200,9 @@ from open_fga_api.credentials import Credentials, CredentialConfiguration credentials = Credentials(method='api_token', configuration=CredentialConfiguration(api_token=os.environ.get(FGA_BEARER_TOKEN))) configuration = openfga_sdk.Configuration( - scheme = os.environ.get(OPENFGA_API_SCHEME), - api_host = os.environ.get(OPENFGA_API_HOST), + api_scheme = os.environ.get(FGA_API_SCHEME), # optional, defaults to "https" + api_host = os.environ.get(FGA_API_HOST), # required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example) + store_id = os.environ.get(FGA_STORE_ID), # optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods credentials = credentials) # Create an instance of the API class diff --git a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx index 033dc4afe5..63c485d301 100644 --- a/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/CheckRequestViewer.tsx @@ -128,35 +128,34 @@ var response = await fgaClient.Check(new CheckRequest(new TupleKey() { // response.Allowed = ${allowed}`; case SupportedLanguage.PYTHON_SDK: return ` -# from openfga_sdk.model.check_request import CheckRequest -# from openfga_sdk.model.tuple_key import TupleKey -# from openfga_sdk.model.contextual_tuple_keys import ContextualTupleKeys +# from openfga_sdk.models.check_request import CheckRequest +# from openfga_sdk.models.tuple_key import TupleKey +# from openfga_sdk.models.contextual_tuple_keys import ContextualTupleKeys # Run a check - -body = CheckRequest( - tuple_key=TupleKey( - user="${user}", - relation="${relation}", - object="${object}", - ), -${ - contextualTuples - ? ` - contextual_tuples=ContextualTupleKeys( - tuple_keys=[ - ${contextualTuples - .map((tuple) => `TupleKey(user="${tuple.user}", relation="${tuple.relation}", object="${tuple.object}")`) - .join(',\n ')} - ], - ), -` - : `` -} -) -response = fga_client_instance.check(body) -# response.allowed = ${allowed} - +async def check(): + body = CheckRequest( + tuple_key=TupleKey( + user="${user}", + relation="${relation}", + object="${object}", + ), ${ + contextualTuples + ? ` + contextual_tuples=ContextualTupleKeys( + tuple_keys=[ + ${contextualTuples + .map( + (tuple) => `TupleKey(user="${tuple.user}", relation="${tuple.relation}", object="${tuple.object}")`, + ) + .join(',\n ')} + ], + ),` + : `` + } + ) + response = await fga_client_instance.check(body) + # response.allowed = ${allowed} `; case SupportedLanguage.RPC: return `check( diff --git a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx index d0d5d0fb2e..6be3316044 100644 --- a/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ExpandRequestViewer.tsx @@ -65,18 +65,19 @@ Reply: {tree:...}`; case SupportedLanguage.PYTHON_SDK: return ` -# from openfga_sdk.model.expand_request import ExpandRequest -# from openfga_sdk.model.expand_response import ExpandResponse -# from openfga_sdk.model.tuple_key import TupleKey +# from openfga_sdk.models.expand_request import ExpandRequest +# from openfga_sdk.models.expand_response import ExpandResponse +# from openfga_sdk.models.tuple_key import TupleKey -body = ExpandRequest( - tuple_key=TupleKey( - relation: "${opts.relation}", - object: "${opts.object}", +async def expand(): + body = ExpandRequest( + tuple_key=TupleKey( + relation: "${opts.relation}", + object: "${opts.object}", + ) ) -) -response = fga_client_instance.expand(body) -# response = ExpandResponse({"tree":...}) + response = await fga_client_instance.expand(body) + # response = ExpandResponse({"tree":...}) `; case SupportedLanguage.PLAYGROUND: diff --git a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx index eb17f2659e..5f7d9fe345 100644 --- a/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ListObjectsRequestViewer.tsx @@ -140,32 +140,33 @@ var response = await openFgaApi.ListObjects(body); // response.ObjectIds = [${expectedResults.map((r) => `"${r}"`).join(', ')}]`; case SupportedLanguage.PYTHON_SDK: return ` -# from openfga_sdk.model.list_objects_request import ListObjectsRequest -# from openfga_sdk.model.tuple_key import TupleKey -# from openfga_sdk.model.contextual_tuple_keys import ContextualTupleKeys +# from openfga_sdk.models.list_objects_request import ListObjectsRequest +# from openfga_sdk.models.tuple_key import TupleKey +# from openfga_sdk.models.contextual_tuple_keys import ContextualTupleKeys -body = ListObjectsRequest(${authorizationModelId ? `authorization_model_id="${authorizationModelId}",` : ``} - user="${user}", - relation="${relation}", - type="${objectType}",${ +async def list_objects(): + body = ListObjectsRequest(${authorizationModelId ? `authorization_model_id="${authorizationModelId}",` : ``} + user="${user}", + relation="${relation}", + type="${objectType}",${ contextualTuples?.length ? ` - contextual_tuples=ContextualTupleKeys( - tuple_keys=[ - ${contextualTuples - .map( - (tupleKey) => `TupleKey( - user="${tupleKey.user}", - relation="${tupleKey.relation}", - object="${tupleKey.object}")`, - ) - .join(',\n ')} - ] - )` + contextual_tuples=ContextualTupleKeys( + tuple_keys=[ + ${contextualTuples + .map( + (tupleKey) => `TupleKey( + user="${tupleKey.user}", + relation="${tupleKey.relation}", + object="${tupleKey.object}")`, + ) + .join(',\n ')} + ] + )` : `` } -) -response = fga_client_instance.list_objects(body) + ) + response = await fga_client_instance.list_objects(body) `; case SupportedLanguage.RPC: return `listObjects( diff --git a/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx b/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx index e983e96d45..9271436a4a 100644 --- a/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ReadChangesRequestViewer.tsx @@ -65,23 +65,24 @@ await fgaClient.ReadChanges(type, pageSize, continuationToken);`; case SupportedLanguage.PYTHON_SDK: { return ` -response = fga_client_instance.read_changes(${ - opts.type - ? ` - type="${opts.type}",` - : `` - }${ +async def read_changes(): + response = await fga_client_instance.read_changes(${ + opts.type + ? ` + type="${opts.type}",` + : `` + }${ opts.pageSize ? ` - page_size="${opts.pageSize}",` + page_size="${opts.pageSize}",` : `` }${ opts.continuationToken ? ` - continuation_token="${opts.continuationToken}",` + continuation_token="${opts.continuationToken}",` : `` } -)`; + )`; } default: { diff --git a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx index 089f91a46d..10d777f387 100644 --- a/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/ReadRequestViewer.tsx @@ -95,22 +95,23 @@ var response = fgaClient.Read(new ReadRequest(new TupleKey() { } case SupportedLanguage.PYTHON_SDK: { const requestTuples = - (opts.user ? ` user="${opts.user}",\n` : '') + - (opts.relation ? ` relation="${opts.relation}",\n` : '') + - ` object="${opts.object}",\n`; + (opts.user ? ` user="${opts.user}",\n` : '') + + (opts.relation ? ` relation="${opts.relation}",\n` : '') + + ` object="${opts.object}",\n`; return ` -# from openfga_sdk.model.read_request import ReadRequest -# from openfga_sdk.model.read_response import ReadResponse -# from openfga_sdk.model.tuple_key import TupleKey +# from openfga_sdk.models.read_request import ReadRequest +# from openfga_sdk.models.read_response import ReadResponse +# from openfga_sdk.models.tuple_key import TupleKey -body = ReadRequest( - tuple_key=TupleKey( +async def read(): + body = ReadRequest( + tuple_key=TupleKey( ${requestTuples} + ) ) -) -response = fga_client_instance.read(body) -# response = ReadResponse({"tuples":[${readTuples}]})`; + response = await fga_client_instance.read(body) + # response = ReadResponse({"tuples":[${readTuples}]})`; } case SupportedLanguage.RPC: { const objectOrType = opts.object.slice(-1) === ':' ? 'type' : 'object'; diff --git a/src/components/Docs/SnippetViewer/SdkSetup.tsx b/src/components/Docs/SnippetViewer/SdkSetup.tsx index 12c5933023..1aea3d5de5 100644 --- a/src/components/Docs/SnippetViewer/SdkSetup.tsx +++ b/src/components/Docs/SnippetViewer/SdkSetup.tsx @@ -93,9 +93,9 @@ class MyProgram { ${importSdkStatement(lang, languageMappings)} configuration = openfga_sdk.Configuration( - api_scheme = os.environ.get('FGA_API_SCHEME'), - api_host = os.environ.get('FGA_API_HOST'), - store_id = os.environ.get('FGA_STORE_ID') + api_scheme = os.environ.get('FGA_API_SCHEME'), # Either "http" or "https", defaults to "https" + api_host = os.environ.get('FGA_API_HOST'), # required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example) + store_id = os.environ.get('FGA_STORE_ID') # optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods ) # Create an instance of the API class diff --git a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx index 4a479329b8..d44e18c2a1 100644 --- a/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteAuthzModelViewer.tsx @@ -57,19 +57,20 @@ function writeAuthZModelViewerDotnet(authorizationModel: AuthorizationModel): st function writeAuthZModelViewerPython(authorizationModel: AuthorizationModel): string { return ` -# from openfga_sdk.model.type_definitions import TypeDefinitions - -body_string = ${JSON.stringify(JSON.stringify(authorizationModel))} -type_definitions = openfga_sdk.model_utils.validate_and_convert_types( - json.loads(body_string), - (TypeDefinitions,), - ['TypeDefinitions'], - True, - True, - configuration=configuration -) -response = fga_client_instance.write_authorization_model(type_definitions) -# response.authorization_model_id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw" +# from openfga_sdk.models.write_authorization_model_request import WriteAuthorizationModelRequest + +async def write_authorization_model(): + body_string = ${JSON.stringify(JSON.stringify(authorizationModel))} + body = openfga_sdk.model_utils.validate_and_convert_types( + json.loads(body_string), + (WriteAuthorizationModelRequest,), + ['WriteAuthorizationModelRequest'], + True, + True, + configuration=configuration + ) + response = await fga_client_instance.write_authorization_model(body) + # response.authorization_model_id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw" `; } diff --git a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx index 37c0877a64..90c906bccd 100644 --- a/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx +++ b/src/components/Docs/SnippetViewer/WriteRequestViewer.tsx @@ -162,11 +162,11 @@ await fgaClient.Write(new WriteRequest{ ? opts.relationshipTuples .map( ({ user, relation, object, _description }) => ` - TupleKey( -${_description ? ` # ${_description}\n ` : ' '}user= "${user}", - relation= "${relation}", - object="${object}", - ),`, + TupleKey( +${_description ? ` # ${_description}\n ` : ' '}user="${user}", + relation="${relation}", + object="${object}", + ),`, ) .join('') : ''; @@ -174,34 +174,35 @@ ${_description ? ` # ${_description}\n ` : ' ? opts.deleteRelationshipTuples .map( ({ user, relation, object, _description }) => ` - TupleKey( -${_description ? ` # ${_description}\n ` : ' '}user= "${user}", - relation= "${relation}", - object="${object}", - ),`, + TupleKey( +${_description ? ` # ${_description}\n ` : ' '}user="${user}", + relation="${relation}", + object="${object}", + ),`, ) .join('') : ''; const writes = ` writes=TupleKeys( - tuple_keys= [${writeTuples} - ], - ), + tuple_keys=[${writeTuples} + ], + ), `; const deletes = ` deletes=TupleKeys( - tuple_keys= [${deleteTuples} - ], - ), + tuple_keys=[${deleteTuples} + ], + ), `; return ` -# from openfga_sdk.model.tuple_key import TupleKey -# from openfga_sdk.model.tuple_keys import TupleKeys -# from openfga_sdk.model.write_request import WriteRequest +# from openfga_sdk.models.tuple_key import TupleKey +# from openfga_sdk.models.tuple_keys import TupleKeys +# from openfga_sdk.models.write_request import WriteRequest -body = WriteRequest( -${opts.relationshipTuples ? writes : ''}${opts.deleteRelationshipTuples ? deletes : ''} -) -response = fga_client_instance.write(body) +async def write(): + body = WriteRequest( + ${opts.relationshipTuples ? writes : ''}${opts.deleteRelationshipTuples ? deletes : ''} + ) + await fga_client_instance.write(body) `; }