Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from http import client
import os
import pytest
from workos import AsyncWorkOSClient, WorkOSClient
Expand Down Expand Up @@ -65,6 +64,9 @@ def test_initialize_portal(self, default_client):
def test_initialize_user_management(self, default_client):
assert bool(default_client.user_management)

def test_initialize_widgets(self, default_client):
assert bool(default_client.widgets)

def test_enforce_trailing_slash_for_base_url(
self,
):
Expand Down
25 changes: 25 additions & 0 deletions tests/test_widgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest

from workos.widgets import Widgets


class TestWidgets(object):
@pytest.fixture(autouse=True)
def setup(self, sync_http_client_for_test):
self.http_client = sync_http_client_for_test
self.widgets = Widgets(http_client=self.http_client)

@pytest.fixture
def mock_widget_token(self):
return {"token": "abc123456"}

def test_get_token(self, mock_widget_token, mock_http_client_with_response):
mock_http_client_with_response(self.http_client, mock_widget_token, 201)

response = self.widgets.get_token(
organization_id="org_01EHQMYV6MBK39QC5PZXHY59C3",
user_id="user_01EHQMYV6MBK39QC5PZXHY59C3",
scopes=["widgets:users-table:manage"],
)

assert response.token == "abc123456"
7 changes: 7 additions & 0 deletions workos/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from workos.user_management import AsyncUserManagement
from workos.utils.http_client import AsyncHTTPClient
from workos.webhooks import WebhooksModule
from workos.widgets import WidgetsModule


class AsyncClient(BaseClient):
Expand Down Expand Up @@ -105,3 +106,9 @@ def user_management(self) -> AsyncUserManagement:
http_client=self._http_client, client_configuration=self
)
return self._user_management

@property
def widgets(self) -> WidgetsModule:
raise NotImplementedError(
"Widgets APIs are not yet supported in the async client."
)
7 changes: 7 additions & 0 deletions workos/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from workos.events import Events
from workos.user_management import UserManagement
from workos.utils.http_client import SyncHTTPClient
from workos.widgets import Widgets


class SyncClient(BaseClient):
Expand Down Expand Up @@ -109,3 +110,9 @@ def user_management(self) -> UserManagement:
http_client=self._http_client, client_configuration=self
)
return self._user_management

@property
def widgets(self) -> Widgets:
if not getattr(self, "_widgets", None):
self._widgets = Widgets(http_client=self._http_client)
return self._widgets
2 changes: 2 additions & 0 deletions workos/types/widgets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .widget_scope import *
from .widget_token_response import *
4 changes: 4 additions & 0 deletions workos/types/widgets/widget_scope.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from typing import Literal


WidgetScope = Literal["widgets:users-table:manage"]
7 changes: 7 additions & 0 deletions workos/types/widgets/widget_token_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from workos.types.workos_model import WorkOSModel


class WidgetTokenResponse(WorkOSModel):
"""Representation of a WorkOS widget token response."""

token: str
55 changes: 55 additions & 0 deletions workos/widgets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from typing import Protocol, Sequence
from workos.types.widgets.widget_scope import WidgetScope
from workos.types.widgets.widget_token_response import WidgetTokenResponse
from workos.utils.http_client import SyncHTTPClient
from workos.utils.request_helper import REQUEST_METHOD_POST


WIDGETS_GENERATE_TOKEN_PATH = "widgets/token"


class WidgetsModule(Protocol):
def get_token(
self,
*,
organization_id: str,
user_id: str,
scopes: Sequence[WidgetScope],
) -> WidgetTokenResponse:
"""Generate a new widget token for the specified organization and user with the provided scopes.

Kwargs:
organization_id (str): The ID of the organization the widget token will be generated for.
user_id (str): The ID of the AuthKit user the widget token will be generated for.
scopes (Sequence[WidgetScope]): The widget scopes for the generated widget token.

Returns:
WidgetTokenResponse: WidgetTokenResponse object with token string.
"""
...


class Widgets(WidgetsModule):

_http_client: SyncHTTPClient

def __init__(self, http_client: SyncHTTPClient):
self._http_client = http_client

def get_token(
self,
*,
organization_id: str,
user_id: str,
scopes: Sequence[WidgetScope],
) -> WidgetTokenResponse:
json = {
"organization_id": organization_id,
"user_id": user_id,
"scopes": scopes,
}
response = self._http_client.request(
WIDGETS_GENERATE_TOKEN_PATH, method=REQUEST_METHOD_POST, json=json
)

return WidgetTokenResponse.model_validate(response)
Loading