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
34 changes: 34 additions & 0 deletions tests/test_organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Union
import pytest
from tests.types.test_auto_pagination_function import TestAutoPaginationFunction
from tests.utils.fixtures.mock_feature_flag import MockFeatureFlag
from tests.utils.fixtures.mock_organization import MockOrganization
from tests.utils.fixtures.mock_role import MockRole
from tests.utils.list_resource import list_response_of
Expand Down Expand Up @@ -77,6 +78,14 @@ def mock_organization_roles(self):
"object": "list",
}

@pytest.fixture
def mock_feature_flags(self):
return {
"data": [MockFeatureFlag(id=f"flag_{str(i)}").dict() for i in range(2)],
"object": "list",
"list_metadata": {"before": None, "after": None},
}

def test_list_organizations(
self, mock_organizations, capture_and_mock_http_client_request
):
Expand Down Expand Up @@ -264,3 +273,28 @@ def to_dict(x):
list(map(to_dict, organization_roles_response.data))
== mock_organization_roles["data"]
)

def test_list_feature_flags(
self, mock_feature_flags, capture_and_mock_http_client_request
):
request_kwargs = capture_and_mock_http_client_request(
self.http_client, mock_feature_flags, 200
)

feature_flags_response = syncify(
self.organizations.list_feature_flags(
organization_id="org_01EHT88Z8J8795GZNQ4ZP1J81T"
)
)

def to_dict(x):
return x.dict()

assert request_kwargs["method"] == "get"
assert request_kwargs["url"].endswith(
"/organizations/org_01EHT88Z8J8795GZNQ4ZP1J81T/feature-flags"
)
assert (
list(map(to_dict, feature_flags_response.data))
== mock_feature_flags["data"]
)
17 changes: 17 additions & 0 deletions tests/utils/fixtures/mock_feature_flag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import datetime

from workos.types.feature_flags.feature_flag import FeatureFlag


class MockFeatureFlag(FeatureFlag):
def __init__(self, id):
now = datetime.datetime.now().isoformat()
super().__init__(
object="feature_flag",
id=id,
slug="test-feature",
name="Test Feature",
description="A test feature flag",
created_at=now,
updated_at=now,
)
85 changes: 85 additions & 0 deletions workos/organizations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Optional, Protocol, Sequence

from workos.types.feature_flags import FeatureFlag
from workos.types.feature_flags.list_filters import FeatureFlagListFilters
from workos.types.metadata import Metadata
from workos.types.organizations.domain_data_input import DomainDataInput
from workos.types.organizations.list_filters import OrganizationListFilters
Expand All @@ -24,6 +26,10 @@
Organization, OrganizationListFilters, ListMetadata
]

FeatureFlagsListResource = WorkOSListResource[
FeatureFlag, FeatureFlagListFilters, ListMetadata
]


class OrganizationsModule(Protocol):
"""Offers methods through the WorkOS Organizations service."""
Expand Down Expand Up @@ -128,6 +134,29 @@ def delete_organization(self, organization_id: str) -> SyncOrAsync[None]:
"""
...

def list_feature_flags(
self,
organization_id: str,
*,
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
before: Optional[str] = None,
after: Optional[str] = None,
order: PaginationOrder = "desc",
) -> SyncOrAsync[FeatureFlagsListResource]:
"""Retrieve a list of feature flags for an organization

Args:
organization_id (str): Organization's unique identifier
limit (int): Maximum number of records to return. (Optional)
before (str): Pagination cursor to receive records before a provided Feature Flag ID. (Optional)
after (str): Pagination cursor to receive records after a provided Feature Flag ID. (Optional)
order (Literal["asc","desc"]): Sort records in either ascending or descending (default) order by created_at timestamp. (Optional)

Returns:
FeatureFlagsListResource: Feature flags list response from WorkOS.
"""
...


class Organizations(OrganizationsModule):
_http_client: SyncHTTPClient
Expand Down Expand Up @@ -247,6 +276,34 @@ def list_organization_roles(self, organization_id: str) -> RoleList:

return RoleList.model_validate(response)

def list_feature_flags(
self,
organization_id: str,
*,
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
before: Optional[str] = None,
after: Optional[str] = None,
order: PaginationOrder = "desc",
) -> FeatureFlagsListResource:
list_params: FeatureFlagListFilters = {
"limit": limit,
"before": before,
"after": after,
"order": order,
}

response = self._http_client.request(
f"organizations/{organization_id}/feature-flags",
method=REQUEST_METHOD_GET,
params=list_params,
)

return WorkOSListResource[FeatureFlag, FeatureFlagListFilters, ListMetadata](
list_method=self.list_feature_flags,
list_args=list_params,
**ListPage[FeatureFlag](**response).model_dump(),
)


class AsyncOrganizations(OrganizationsModule):
_http_client: AsyncHTTPClient
Expand Down Expand Up @@ -365,3 +422,31 @@ async def list_organization_roles(self, organization_id: str) -> RoleList:
)

return RoleList.model_validate(response)

async def list_feature_flags(
self,
organization_id: str,
*,
limit: int = DEFAULT_LIST_RESPONSE_LIMIT,
before: Optional[str] = None,
after: Optional[str] = None,
order: PaginationOrder = "desc",
) -> FeatureFlagsListResource:
list_params: FeatureFlagListFilters = {
"limit": limit,
"before": before,
"after": after,
"order": order,
}

response = await self._http_client.request(
f"organizations/{organization_id}/feature-flags",
method=REQUEST_METHOD_GET,
params=list_params,
)

return WorkOSListResource[FeatureFlag, FeatureFlagListFilters, ListMetadata](
list_method=self.list_feature_flags,
list_args=list_params,
**ListPage[FeatureFlag](**response).model_dump(),
)
3 changes: 3 additions & 0 deletions workos/types/feature_flags/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from workos.types.feature_flags.feature_flag import FeatureFlag

__all__ = ["FeatureFlag"]
12 changes: 12 additions & 0 deletions workos/types/feature_flags/feature_flag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from typing import Literal, Optional
from workos.types.workos_model import WorkOSModel


class FeatureFlag(WorkOSModel):
id: str
object: Literal["feature_flag"]
slug: str
name: str
description: Optional[str]
created_at: str
updated_at: str
5 changes: 5 additions & 0 deletions workos/types/feature_flags/list_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from workos.types.list_resource import ListArgs


class FeatureFlagListFilters(ListArgs, total=False):
pass
2 changes: 2 additions & 0 deletions workos/types/list_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
DirectoryUserWithGroups,
)
from workos.types.events import Event
from workos.types.feature_flags import FeatureFlag
from workos.types.fga import (
Warrant,
AuthorizationResource,
Expand All @@ -46,6 +47,7 @@
DirectoryGroup,
DirectoryUserWithGroups,
Event,
FeatureFlag,
Invitation,
Organization,
OrganizationMembership,
Expand Down