Skip to content

Commit af463b0

Browse files
committed
[owl] Notifications APIs (#907)
* Notification Group CRD * Notification CRD * Notification Client * Trigger org and project invitation * Trigger org/project member joined and owner/role updates * Test cases for CRD * Notify invitation revoke; Test invitation create/revoke and join org/project notification trigger; Markdown body template; * Remove string normalization test * BackgroundTasks fan-out notifications * Storage limit notification and tests * Handle storage deltas and avoid concurrent notif via cache
1 parent 392a887 commit af463b0

File tree

20 files changed

+2212
-25
lines changed

20 files changed

+2212
-25
lines changed

clients/python/src/jamaibase/client.py

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
MultiRowDeleteRequest,
5959
MultiRowRegenRequest,
6060
MultiRowUpdateRequest,
61+
NotificationGroupCreate,
62+
NotificationGroupRead,
63+
NotificationRead,
6164
OkResponse,
6265
OrganizationCreate,
6366
OrganizationRead,
@@ -3985,6 +3988,144 @@ async def delete_secret(
39853988
)
39863989

39873990

3991+
class _NotificationGroupsAsync(_ClientAsync):
3992+
"""NotificationGroup methods (admin)."""
3993+
3994+
async def create_notification_group(
3995+
self,
3996+
body: NotificationGroupCreate,
3997+
**kwargs,
3998+
) -> NotificationGroupRead:
3999+
return await self._post(
4000+
"/v2/notification/group",
4001+
body=body,
4002+
response_model=NotificationGroupRead,
4003+
**kwargs,
4004+
)
4005+
4006+
async def list_notification_groups(
4007+
self,
4008+
*,
4009+
offset: int = 0,
4010+
limit: int = 100,
4011+
order_by: str = "created_at",
4012+
order_ascending: bool = False,
4013+
**kwargs,
4014+
) -> Page[NotificationGroupRead]:
4015+
return await self._get(
4016+
"/v2/notification/group/list",
4017+
params=dict(
4018+
offset=offset,
4019+
limit=limit,
4020+
order_by=order_by,
4021+
order_ascending=order_ascending,
4022+
),
4023+
response_model=Page[NotificationGroupRead],
4024+
**kwargs,
4025+
)
4026+
4027+
async def get_notification_group(
4028+
self,
4029+
notification_group_id: str,
4030+
**kwargs,
4031+
) -> NotificationGroupRead:
4032+
return await self._get(
4033+
"/v2/notification/group",
4034+
params=dict(notification_group_id=notification_group_id),
4035+
response_model=NotificationGroupRead,
4036+
**kwargs,
4037+
)
4038+
4039+
async def delete_notification_group(
4040+
self,
4041+
notification_group_id: str,
4042+
*,
4043+
missing_ok: bool = True,
4044+
**kwargs,
4045+
) -> OkResponse:
4046+
response = await self._delete(
4047+
"/v2/notification/group",
4048+
params=dict(notification_group_id=notification_group_id),
4049+
response_model=None,
4050+
ignore_code=404 if missing_ok else None,
4051+
**kwargs,
4052+
)
4053+
if response.status_code == 404 and missing_ok:
4054+
return OkResponse()
4055+
else:
4056+
return OkResponse.model_validate_json(response.text)
4057+
4058+
4059+
class _NotificationsAsync(_ClientAsync):
4060+
"""Notification methods (user)."""
4061+
4062+
async def list_notifications(
4063+
self,
4064+
*,
4065+
offset: int = 0,
4066+
limit: int = 100,
4067+
order_by: str = "created_at",
4068+
order_ascending: bool = False,
4069+
unread_only: bool = False,
4070+
**kwargs,
4071+
) -> Page[NotificationRead]:
4072+
return await self._get(
4073+
"/v2/notifications/list",
4074+
params=dict(
4075+
offset=offset,
4076+
limit=limit,
4077+
order_by=order_by,
4078+
order_ascending=order_ascending,
4079+
unread_only=unread_only,
4080+
),
4081+
response_model=Page[NotificationRead],
4082+
**kwargs,
4083+
)
4084+
4085+
async def get_notification(
4086+
self,
4087+
notification_group_id: str,
4088+
**kwargs,
4089+
) -> NotificationRead:
4090+
return await self._get(
4091+
"/v2/notifications",
4092+
params=dict(notification_group_id=notification_group_id),
4093+
response_model=NotificationRead,
4094+
**kwargs,
4095+
)
4096+
4097+
async def delete_notification(
4098+
self,
4099+
notification_group_id: str,
4100+
**kwargs,
4101+
) -> OkResponse:
4102+
return await self._delete(
4103+
"/v2/notifications",
4104+
params=dict(notification_group_id=notification_group_id),
4105+
response_model=OkResponse,
4106+
**kwargs,
4107+
)
4108+
4109+
async def set_opened(
4110+
self,
4111+
notification_group_id: str,
4112+
**kwargs,
4113+
) -> OkResponse:
4114+
return await self._patch(
4115+
"/v2/notifications/opened",
4116+
params=dict(notification_group_id=notification_group_id),
4117+
response_model=OkResponse,
4118+
**kwargs,
4119+
)
4120+
4121+
async def set_all_opened(self, **kwargs) -> OkResponse:
4122+
return await self._patch(
4123+
"/v2/notifications/opened/all",
4124+
response_model=OkResponse,
4125+
**kwargs,
4126+
)
4127+
4128+
39884129
class JamAIAsync(_ClientAsync):
39894130
def __init__(
39904131
self,
@@ -4063,6 +4204,8 @@ def __init__(
40634204
self.tasks = _TaskClientAsync(**kwargs)
40644205
self.conversations = _ConversationClientAsync(**kwargs)
40654206
self.secrets = _SecretsAsync(**kwargs)
4207+
self.notification_groups = _NotificationGroupsAsync(**kwargs)
4208+
self.notifications = _NotificationsAsync(**kwargs)
40664209

40674210
async def health(self) -> dict[str, Any]:
40684211
"""
@@ -6602,6 +6745,85 @@ def delete_secret(
66026745
)
66036746

66046747

6748+
class _NotificationGroups(_NotificationGroupsAsync):
6749+
"""Synchronous NotificationGroup methods."""
6750+
6751+
def create_notification_group(
6752+
self, body: NotificationGroupCreate, **kwargs
6753+
) -> NotificationGroupRead:
6754+
return LOOP.run(super().create_notification_group(body, **kwargs))
6755+
6756+
def list_notification_groups(
6757+
self,
6758+
*,
6759+
offset: int = 0,
6760+
limit: int = 100,
6761+
order_by: str = "created_at",
6762+
order_ascending: bool = False,
6763+
**kwargs,
6764+
) -> Page[NotificationGroupRead]:
6765+
return LOOP.run(
6766+
super().list_notification_groups(
6767+
offset=offset,
6768+
limit=limit,
6769+
order_by=order_by,
6770+
order_ascending=order_ascending,
6771+
**kwargs,
6772+
)
6773+
)
6774+
6775+
def get_notification_group(
6776+
self, notification_group_id: str, **kwargs
6777+
) -> NotificationGroupRead:
6778+
return LOOP.run(super().get_notification_group(notification_group_id, **kwargs))
6779+
6780+
def delete_notification_group(
6781+
self, notification_group_id: str, *, missing_ok: bool = True, **kwargs
6782+
) -> OkResponse:
6783+
return LOOP.run(
6784+
super().delete_notification_group(
6785+
notification_group_id, missing_ok=missing_ok, **kwargs
6786+
)
6787+
)
6788+
6789+
6790+
class _Notifications(_NotificationsAsync):
6791+
"""Synchronous Notification methods."""
6792+
6793+
def list_notifications(
6794+
self,
6795+
*,
6796+
offset: int = 0,
6797+
limit: int = 100,
6798+
order_by: str = "created_at",
6799+
order_ascending: bool = False,
6800+
unread_only: bool = False,
6801+
**kwargs,
6802+
) -> Page[NotificationRead]:
6803+
return LOOP.run(
6804+
super().list_notifications(
6805+
offset=offset,
6806+
limit=limit,
6807+
order_by=order_by,
6808+
order_ascending=order_ascending,
6809+
unread_only=unread_only,
6810+
**kwargs,
6811+
)
6812+
)
6813+
6814+
def get_notification(self, notification_group_id: str, **kwargs) -> NotificationRead:
6815+
return LOOP.run(super().get_notification(notification_group_id, **kwargs))
6816+
6817+
def delete_notification(self, notification_group_id: str, **kwargs) -> OkResponse:
6818+
return LOOP.run(super().delete_notification(notification_group_id, **kwargs))
6819+
6820+
def set_opened(self, notification_group_id: str, **kwargs) -> OkResponse:
6821+
return LOOP.run(super().set_opened(notification_group_id, **kwargs))
6822+
6823+
def set_all_opened(self, **kwargs) -> OkResponse:
6824+
return LOOP.run(super().set_all_opened(**kwargs))
6825+
6826+
66056827
class JamAI(JamAIAsync):
66066828
def __init__(
66076829
self,
@@ -6670,6 +6892,8 @@ def __init__(
66706892
self.tasks = _TaskClient(**kwargs)
66716893
self.conversations = _ConversationClient(**kwargs)
66726894
self.secrets = _Secrets(**kwargs)
6895+
self.notification_groups = _NotificationGroups(**kwargs)
6896+
self.notifications = _Notifications(**kwargs)
66736897

66746898
def health(self) -> dict[str, Any]:
66756899
"""

clients/python/src/jamaibase/types/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@
8686
ModelInfoRead,
8787
ModelProvider,
8888
ModelType,
89+
Notification_,
90+
NotificationCreate,
91+
NotificationGroup_,
92+
NotificationGroupCreate,
93+
NotificationGroupRead,
94+
NotificationRead,
95+
NotificationScope,
96+
NotificationType,
8997
OnPremProvider,
9098
Organization_,
9199
OrganizationCreate,

0 commit comments

Comments
 (0)