Skip to content

Commit 886255d

Browse files
TejasRGitHubclaude
andauthored
client(dataall_url=...): connect from the data.all front page, 0.6.0 (#56)
* Document client(dataall_url=...) and require dataall-core 0.6.0 The SDK passes dataall_url through to DataallClient.client, which now discovers and saves the profile from the data.all front page. Version 0.6.0 (also fixes __version__, which still said 0.3.0a1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * Lock dataall-core 0.6.0 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 9a19451 commit 886255d

6 files changed

Lines changed: 95 additions & 28 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import dataall_sdk
2626
# Profile w/ UserA (assuming UserA profile configured in ~/.dataall/config.yaml)
2727
da_client = dataall.client(profile="UserA")
2828

29+
# Or discover the settings from the data.all front page (profile saved under its host name)
30+
da_client = dataall.client(dataall_url="https://DATAALL_DOMAIN_URL")
31+
2932
list_org_response = da_client.list_organizations()
3033
print(list_org_response)
3134
```

‎dataall_sdk/__metadata__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77

88
__title__: str = "dataall_sdk"
99
__description__: str = "AWS Dataall SDK"
10-
__version__: str = "0.3.0a1"
10+
__version__: str = "0.6.0"
1111
__license__: str = "Apache License 2.0"

‎poetry.lock‎

Lines changed: 21 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎pyproject.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "dataall-sdk"
3-
version = "0.4.3"
3+
version = "0.6.0"
44
description = "AWS data.all SDK"
55
authors = [{ name = "Amazon Web Services" }]
66
license = { text = "Apache License 2.0" }
@@ -20,7 +20,7 @@ dependencies = [
2020
"packaging>=24.2",
2121
"build>=0.10.0,<1.0.0",
2222
"setuptools; python_version >= '3.12'",
23-
"dataall-core>=0.4.3",
23+
"dataall-core>=0.6.0,<0.7.0",
2424
]
2525

2626
[tool.poetry]

‎tests/functional/test_datall_sdk_client.py‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import os
22
from unittest.mock import patch
33

4+
import pytest
45
from dataall_core.base_client import BaseClient
56
from dataall_core.dataall_client import DataallClient
7+
from dataall_core.exceptions import MissingParametersException
68
from dataall_core.profile import get_profile
79

810
import dataall_sdk
@@ -75,3 +77,48 @@ def test_default_client_loaded_methods():
7577
{},
7678
)
7779
assert getattr(client, method).__doc__ == op_dict[method]["docstring"]
80+
81+
82+
OIDC_DISCOVERY = {
83+
"frontend_url": "https://dataall.example.com",
84+
"auth_type": "OidcBrowserAuth",
85+
"idp_domain_url": "https://idp/oauth2/aus1",
86+
"client_id": "0oaCLIENT",
87+
"api_endpoint_url": "https://api/prod",
88+
}
89+
90+
91+
def test_client_from_frontend_url(tmp_path):
92+
config_path = str(tmp_path / "config.yaml")
93+
with patch(
94+
"dataall_core.discovery.discover_from_frontend",
95+
side_effect=lambda url: dict(OIDC_DISCOVERY),
96+
) as discover:
97+
client = dataall_sdk.client(
98+
dataall_url="https://dataall.example.com/console", config_path=config_path
99+
)
100+
assert isinstance(client, BaseClient)
101+
assert type(client.authorizer).__name__ == "OidcBrowserAuth"
102+
assert client.authorizer.profile.profile_name == "dataall.example.com"
103+
assert client.authorizer.profile.client_id == "0oaCLIENT"
104+
assert client.authorizer.profile.frontend_url == "https://dataall.example.com"
105+
106+
again = dataall_sdk.client(
107+
dataall_url="https://dataall.example.com", config_path=config_path
108+
)
109+
assert again.authorizer.profile == get_profile(
110+
"dataall.example.com", config_path=config_path
111+
)
112+
discover.assert_called_once()
113+
114+
115+
def test_client_from_frontend_url_missing_values(tmp_path):
116+
with patch(
117+
"dataall_core.discovery.discover_from_frontend",
118+
return_value={"frontend_url": "https://dataall.example.com"},
119+
):
120+
with pytest.raises(MissingParametersException, match="auth_type"):
121+
dataall_sdk.client(
122+
dataall_url="https://dataall.example.com",
123+
config_path=str(tmp_path / "config.yaml"),
124+
)

‎tutorials/002 - Getting Started.md‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,24 @@
55

66
Dataall's SDK requires user profile information to be stored either in a local file or in AWS Secrets Manager. The user information required includes:
77

8-
- auth_type: Either `CognitoAuth` or `CustomAuth`
8+
- auth_type: `CognitoAuth`, `CustomAuth` or `OidcBrowserAuth` (browser login, no password)
99
- client_id: The App Client ID
1010
- api_endpoint_url: The URL data.all API Gateway Endpoint
11-
- redirect_uri: The data.all domain URL
12-
- idp_domain_url: The Identity Providers URL
11+
- redirect_uri: The data.all domain URL (for `OidcBrowserAuth`: the loopback URI registered for the client, default `http://localhost:8765/callback`)
12+
- idp_domain_url: The Identity Providers URL (for `OidcBrowserAuth`: the OIDC issuer URL)
1313
- client_secret (optional): The client secret used for the data.all App Client
1414
- auth_server (optional, used for CustomAuth): The Custom Authorization Server used if applicable
1515
- session_token_endpoint (optional, required for CustomAuth): The Identity Provider API endpoint to retrieve session tokens
16+
- scopes (optional, OidcBrowserAuth): OIDC scopes, default `openid offline_access`
17+
- fallback_redirect_uri (optional, OidcBrowserAuth): second loopback URI tried when the first port is busy
18+
- frontend_url (optional): the data.all UI URL, sent as `Origin` and `Referer` headers; required where the API only accepts calls carrying the UI origin
1619
- profile: The Profile Name
1720

1821
Data.all's SDK uses the profile information to fetch and save tokens from the data.all application.
1922

2023
By default the user information is provided at `~/.dataall/config.yaml` and the token information is saved at `~/.dataall/credentials.yaml`
2124

22-
If a valid token or refresh token exists for the given user, that will be used to fetch a new token and authenticate the profile. Otherwise, the user will be prompted for username and password when running an API request and the fetched tokens will be saved.
25+
If a valid token or refresh token exists for the given user, that will be used to fetch a new token and authenticate the profile. Otherwise, the user will be prompted for username and password when running an API request and the fetched tokens will be saved. With `OidcBrowserAuth` the SDK opens the identity provider's login page in the browser instead (or prints a device code on hosts without a browser).
2326

2427

2528
### Configuring your first data.all User profile
@@ -49,6 +52,20 @@ TestCustomProfile:
4952
session_token_endpoint: testtokenendpoint
5053
```
5154

55+
56+
### Connecting with just the front page URL
57+
58+
You do not have to write a profile by hand. Point the client at the data.all front page and the SDK reads the authentication type, identity provider, client id and API endpoint from the deployed application:
59+
60+
```py3
61+
import dataall_sdk as dataall
62+
63+
client = dataall.client(dataall_url="https://DATAALL_DOMAIN_URL")
64+
client.list_organizations()
65+
```
66+
67+
The discovered profile is saved in `~/.dataall/config.yaml` under the page's host name (pass `profile="..."` to choose the name), so the next call reuses it without contacting the front page, and the tokens are kept in `credentials.yaml` as for any other profile. If a profile with that name already exists it is used as is. For OIDC deployments the first API call opens the browser for the login; the identity provider app must allow the loopback redirect URIs (`http://localhost:8765/callback` and `http://localhost:8766/callback`). Values that cannot be read from the page raise `MissingParametersException` naming them.
68+
5269
### Specifying your user profile
5370

5471
Once you have configured your user profile appropriately, you can begin running data.all API requests via the SDK using your configured profile(s) such as:

0 commit comments

Comments
 (0)