Skip to content

Commit b529a6b

Browse files
authored
Add widgets module and widget get token API endpoint. (#380)
1 parent adaac88 commit b529a6b

File tree

8 files changed

+110
-1
lines changed

8 files changed

+110
-1
lines changed

tests/test_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from http import client
21
import os
32
import pytest
43
from workos import AsyncWorkOSClient, WorkOSClient
@@ -65,6 +64,9 @@ def test_initialize_portal(self, default_client):
6564
def test_initialize_user_management(self, default_client):
6665
assert bool(default_client.user_management)
6766

67+
def test_initialize_widgets(self, default_client):
68+
assert bool(default_client.widgets)
69+
6870
def test_enforce_trailing_slash_for_base_url(
6971
self,
7072
):

tests/test_widgets.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import pytest
2+
3+
from workos.widgets import Widgets
4+
5+
6+
class TestWidgets(object):
7+
@pytest.fixture(autouse=True)
8+
def setup(self, sync_http_client_for_test):
9+
self.http_client = sync_http_client_for_test
10+
self.widgets = Widgets(http_client=self.http_client)
11+
12+
@pytest.fixture
13+
def mock_widget_token(self):
14+
return {"token": "abc123456"}
15+
16+
def test_get_token(self, mock_widget_token, mock_http_client_with_response):
17+
mock_http_client_with_response(self.http_client, mock_widget_token, 201)
18+
19+
response = self.widgets.get_token(
20+
organization_id="org_01EHQMYV6MBK39QC5PZXHY59C3",
21+
user_id="user_01EHQMYV6MBK39QC5PZXHY59C3",
22+
scopes=["widgets:users-table:manage"],
23+
)
24+
25+
assert response.token == "abc123456"

workos/async_client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from workos.user_management import AsyncUserManagement
1414
from workos.utils.http_client import AsyncHTTPClient
1515
from workos.webhooks import WebhooksModule
16+
from workos.widgets import WidgetsModule
1617

1718

1819
class AsyncClient(BaseClient):
@@ -105,3 +106,9 @@ def user_management(self) -> AsyncUserManagement:
105106
http_client=self._http_client, client_configuration=self
106107
)
107108
return self._user_management
109+
110+
@property
111+
def widgets(self) -> WidgetsModule:
112+
raise NotImplementedError(
113+
"Widgets APIs are not yet supported in the async client."
114+
)

workos/client.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from workos.events import Events
1414
from workos.user_management import UserManagement
1515
from workos.utils.http_client import SyncHTTPClient
16+
from workos.widgets import Widgets
1617

1718

1819
class SyncClient(BaseClient):
@@ -109,3 +110,9 @@ def user_management(self) -> UserManagement:
109110
http_client=self._http_client, client_configuration=self
110111
)
111112
return self._user_management
113+
114+
@property
115+
def widgets(self) -> Widgets:
116+
if not getattr(self, "_widgets", None):
117+
self._widgets = Widgets(http_client=self._http_client)
118+
return self._widgets

workos/types/widgets/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .widget_scope import *
2+
from .widget_token_response import *
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from typing import Literal
2+
3+
4+
WidgetScope = Literal["widgets:users-table:manage"]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from workos.types.workos_model import WorkOSModel
2+
3+
4+
class WidgetTokenResponse(WorkOSModel):
5+
"""Representation of a WorkOS widget token response."""
6+
7+
token: str

workos/widgets.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from typing import Protocol, Sequence
2+
from workos.types.widgets.widget_scope import WidgetScope
3+
from workos.types.widgets.widget_token_response import WidgetTokenResponse
4+
from workos.utils.http_client import SyncHTTPClient
5+
from workos.utils.request_helper import REQUEST_METHOD_POST
6+
7+
8+
WIDGETS_GENERATE_TOKEN_PATH = "widgets/token"
9+
10+
11+
class WidgetsModule(Protocol):
12+
def get_token(
13+
self,
14+
*,
15+
organization_id: str,
16+
user_id: str,
17+
scopes: Sequence[WidgetScope],
18+
) -> WidgetTokenResponse:
19+
"""Generate a new widget token for the specified organization and user with the provided scopes.
20+
21+
Kwargs:
22+
organization_id (str): The ID of the organization the widget token will be generated for.
23+
user_id (str): The ID of the AuthKit user the widget token will be generated for.
24+
scopes (Sequence[WidgetScope]): The widget scopes for the generated widget token.
25+
26+
Returns:
27+
WidgetTokenResponse: WidgetTokenResponse object with token string.
28+
"""
29+
...
30+
31+
32+
class Widgets(WidgetsModule):
33+
34+
_http_client: SyncHTTPClient
35+
36+
def __init__(self, http_client: SyncHTTPClient):
37+
self._http_client = http_client
38+
39+
def get_token(
40+
self,
41+
*,
42+
organization_id: str,
43+
user_id: str,
44+
scopes: Sequence[WidgetScope],
45+
) -> WidgetTokenResponse:
46+
json = {
47+
"organization_id": organization_id,
48+
"user_id": user_id,
49+
"scopes": scopes,
50+
}
51+
response = self._http_client.request(
52+
WIDGETS_GENERATE_TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
53+
)
54+
55+
return WidgetTokenResponse.model_validate(response)

0 commit comments

Comments
 (0)