Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,4 @@ dmypy.json
# Cython debug symbols
cython_debug/

*.idea
8 changes: 7 additions & 1 deletion clerk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(
self, token: str, base_url: str = "https://api.clerk.dev/v1/", timeout_seconds: float = 30.0
) -> None:
self._session = aiohttp.ClientSession(
headers={"Authorization": f"Bearer {token}"},
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
timeout=aiohttp.ClientTimeout(total=timeout_seconds),
)
self._base_url = base_url
Expand Down Expand Up @@ -51,6 +51,12 @@ def users(self):

return UsersService(self)

@property
def organizations(self):
from clerk.organizations import OrganizationsService

return OrganizationsService(self)

@asynccontextmanager
async def get(
self, endpoint: str, params: Optional[Mapping[str, str]] = None
Expand Down
31 changes: 31 additions & 0 deletions clerk/organizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import List

from clerk import types
from clerk.client import Service


class OrganizationsService(Service):
endpoint = "organizations"

async def list(self) -> List[types.Organization]:
"""Retrieve a list of all organizations"""
async with self._client.get(self.endpoint) as resp:
resp_json = await resp.json()
return [types.Organization.parse_obj(obj) for obj in resp_json.get("data", [])]

async def get(self, organization_id: str) -> types.Organization:
"""Retrieve an organization by their id"""
async with self._client.get(f"{self.endpoint}/{organization_id}") as resp:
return types.Organization.parse_obj(await resp.json())

async def delete(self, organization_id: str) -> types.DeleteOrganizationResponse:
"""Delete an organization by their id"""
async with self._client.delete(f"{self.endpoint}/{organization_id}") as resp:
return types.DeleteOrganizationResponse.parse_obj(await resp.json())

async def update(self, organization_id: str, request: types.UpdateOrganizationRequest) -> types.Organization:
"""Update an organization by their id"""
async with self._client.patch(
f"{self.endpoint}/{organization_id}", data=request.json(exclude_unset=True)
) as resp:
return types.Organization.parse_obj(await resp.json())
29 changes: 28 additions & 1 deletion clerk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,43 @@ class VerifyRequest(BaseModel):
token: str


class DeleteUserResponse(BaseModel):
class DeleteResponse(BaseModel):
object: str
id: str
deleted: bool


class DeleteUserResponse(DeleteResponse):
pass


class UpdateUserRequest(BaseModel):
first_name: Optional[str] = None
last_name: Optional[str] = None
primary_email_address_id: Optional[str] = None
primary_phone_number_id: Optional[str] = None
profile_image: Optional[str] = None
password: Optional[str] = None


class Organization(BaseModel):
object: str
id: str
name: str
slug: str
max_allowed_memberships: int
admin_delete_enabled: bool | None = None
public_metadata: dict
private_metadata: dict
created_by: str | None = None


class DeleteOrganizationResponse(DeleteResponse):
pass


class UpdateOrganizationRequest(BaseModel):
name: str | None = None
slug: str | None = None
max_allowed_memberships: int | None = None
admin_delete_enabled: bool | None = None
Loading