circle-so-python-sdk 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. circle/__init__.py +24 -0
  2. circle/api/__init__.py +1 -0
  3. circle/api/admin_access_groups.py +133 -0
  4. circle/api/admin_community.py +122 -0
  5. circle/api/admin_courses.py +172 -0
  6. circle/api/admin_events.py +101 -0
  7. circle/api/admin_misc.py +305 -0
  8. circle/api/admin_posts.py +200 -0
  9. circle/api/admin_spaces.py +301 -0
  10. circle/api/admin_tags.py +146 -0
  11. circle/api/auth.py +63 -0
  12. circle/api/headless_chat_notif_members.py +323 -0
  13. circle/api/headless_misc.py +218 -0
  14. circle/api/headless_spaces_posts.py +279 -0
  15. circle/client.py +197 -0
  16. circle/constants.py +5 -0
  17. circle/exceptions.py +34 -0
  18. circle/http.py +227 -0
  19. circle/models/__init__.py +5 -0
  20. circle/models/admin/__init__.py +47 -0
  21. circle/models/admin/community.py +82 -0
  22. circle/models/admin/courses.py +30 -0
  23. circle/models/admin/events.py +67 -0
  24. circle/models/admin/members.py +105 -0
  25. circle/models/admin/misc.py +240 -0
  26. circle/models/admin/posts.py +172 -0
  27. circle/models/admin/spaces.py +146 -0
  28. circle/models/admin/tags.py +85 -0
  29. circle/models/auth.py +21 -0
  30. circle/models/base.py +28 -0
  31. circle/models/headless/__init__.py +50 -0
  32. circle/models/headless/chat.py +134 -0
  33. circle/models/headless/comments.py +60 -0
  34. circle/models/headless/courses.py +109 -0
  35. circle/models/headless/members.py +105 -0
  36. circle/models/headless/misc.py +120 -0
  37. circle/models/headless/notifications.py +66 -0
  38. circle/models/headless/posts.py +137 -0
  39. circle/models/headless/spaces.py +80 -0
  40. circle/pagination.py +116 -0
  41. circle/py.typed +1 -0
  42. circle/rate_limit.py +36 -0
  43. circle/validation.py +67 -0
  44. circle/webhooks.py +39 -0
  45. circle_so_python_sdk-0.1.0.dist-info/METADATA +120 -0
  46. circle_so_python_sdk-0.1.0.dist-info/RECORD +48 -0
  47. circle_so_python_sdk-0.1.0.dist-info/WHEEL +4 -0
  48. circle_so_python_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
circle/__init__.py ADDED
@@ -0,0 +1,24 @@
1
+ """Circle.so Python SDK - Admin V2, Headless Auth, and Headless Client V1 APIs."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ from circle.client import AsyncCircleClient, CircleClient
6
+ from circle.exceptions import (
7
+ AuthenticationError,
8
+ CircleAPIError,
9
+ ForbiddenError,
10
+ NotFoundError,
11
+ RateLimitError,
12
+ ValidationError,
13
+ )
14
+
15
+ __all__ = [
16
+ "CircleClient",
17
+ "AsyncCircleClient",
18
+ "CircleAPIError",
19
+ "AuthenticationError",
20
+ "NotFoundError",
21
+ "ValidationError",
22
+ "ForbiddenError",
23
+ "RateLimitError",
24
+ ]
circle/api/__init__.py ADDED
@@ -0,0 +1 @@
1
+ """API client sub-packages."""
@@ -0,0 +1,133 @@
1
+ """Admin API -- Access Groups & Access Group Members."""
2
+ from __future__ import annotations
3
+ from typing import Any, Dict, Optional
4
+ from circle.constants import ADMIN_V2_PREFIX as _P
5
+ from circle.http import AsyncTransport, SyncTransport
6
+ from circle.models.admin.misc import (
7
+ AccessGroup, AccessGroupList, AccessGroupCommunityMember, AccessGroupCommunityMemberList,
8
+ )
9
+
10
+
11
+ # -- param builders ----------------------------------------------------------
12
+
13
+ def _list_params(page: int, per_page: int, status: Optional[str],
14
+ ids: Optional[list[int]], name: Optional[str]) -> Dict[str, Any]:
15
+ p: Dict[str, Any] = {"page": page, "per_page": per_page}
16
+ if status: p["status"] = status
17
+ if ids: p["ids"] = ids
18
+ if name: p["name"] = name
19
+ return p
20
+
21
+
22
+ def _create_body(name: str, description: Optional[str]) -> Dict[str, Any]:
23
+ ag: Dict[str, Any] = {"name": name}
24
+ if description is not None: ag["description"] = description
25
+ return {"access_group": ag}
26
+
27
+
28
+ def _page_params(page: int, per_page: int) -> Dict[str, Any]:
29
+ return {"page": page, "per_page": per_page}
30
+
31
+
32
+ # -- sync client --------------------------------------------------------------
33
+
34
+ class AccessGroupsClient:
35
+ def __init__(self, transport: SyncTransport) -> None:
36
+ self._t = transport
37
+
38
+ def list_access_groups(self, *, page: int = 1, per_page: int = 60, status: Optional[str] = None,
39
+ ids: Optional[list[int]] = None, name: Optional[str] = None) -> AccessGroupList:
40
+ return AccessGroupList.model_validate(
41
+ self._t.request("GET", f"{_P}/access_groups", params=_list_params(page, per_page, status, ids, name)))
42
+
43
+ def create_access_group(self, *, name: str, description: Optional[str] = None) -> AccessGroup:
44
+ return AccessGroup.model_validate(
45
+ self._t.request("POST", f"{_P}/access_groups", json=_create_body(name, description)))
46
+
47
+ def update_access_group(self, access_group_id: int, **kwargs: Any) -> AccessGroup:
48
+ return AccessGroup.model_validate(
49
+ self._t.request("PUT", f"{_P}/access_groups/{access_group_id}", json={"access_group": kwargs}))
50
+
51
+ def archive_access_group(self, access_group_id: int) -> Dict[str, Any]:
52
+ return self._t.request("DELETE", f"{_P}/access_groups/{access_group_id}")
53
+
54
+ def unarchive_access_group(self, access_group_id: int) -> AccessGroup:
55
+ return AccessGroup.model_validate(
56
+ self._t.request("PATCH", f"{_P}/access_groups/{access_group_id}/unarchive"))
57
+
58
+ def list_access_group_members(self, access_group_id: int, *, page: int = 1,
59
+ per_page: int = 60) -> AccessGroupCommunityMemberList:
60
+ return AccessGroupCommunityMemberList.model_validate(
61
+ self._t.request("GET", f"{_P}/access_groups/{access_group_id}/community_members",
62
+ params=_page_params(page, per_page)))
63
+
64
+ def show_access_group_member(self, access_group_id: int, *, email: str) -> AccessGroupCommunityMember:
65
+ return AccessGroupCommunityMember.model_validate(
66
+ self._t.request("GET", f"{_P}/access_groups/{access_group_id}/community_member",
67
+ params={"email": email}))
68
+
69
+ def add_access_group_member(self, access_group_id: int, *, email: str) -> Dict[str, Any]:
70
+ return self._t.request("POST", f"{_P}/access_groups/{access_group_id}/community_members",
71
+ json={"email": email})
72
+
73
+ def remove_access_group_member(self, access_group_id: int, *, email: str) -> Dict[str, Any]:
74
+ return self._t.request("DELETE", f"{_P}/access_groups/{access_group_id}/community_members",
75
+ params={"email": email})
76
+
77
+ def list_community_member_access_groups(self, community_member_id: int, *, page: int = 1,
78
+ per_page: int = 60) -> AccessGroupList:
79
+ return AccessGroupList.model_validate(
80
+ self._t.request("GET", f"{_P}/community_members/{community_member_id}/access_groups",
81
+ params=_page_params(page, per_page)))
82
+
83
+
84
+ # -- async client --------------------------------------------------------------
85
+
86
+ class AsyncAccessGroupsClient:
87
+ def __init__(self, transport: AsyncTransport) -> None:
88
+ self._t = transport
89
+
90
+ async def list_access_groups(self, *, page: int = 1, per_page: int = 60, status: Optional[str] = None,
91
+ ids: Optional[list[int]] = None, name: Optional[str] = None) -> AccessGroupList:
92
+ return AccessGroupList.model_validate(
93
+ await self._t.request("GET", f"{_P}/access_groups", params=_list_params(page, per_page, status, ids, name)))
94
+
95
+ async def create_access_group(self, *, name: str, description: Optional[str] = None) -> AccessGroup:
96
+ return AccessGroup.model_validate(
97
+ await self._t.request("POST", f"{_P}/access_groups", json=_create_body(name, description)))
98
+
99
+ async def update_access_group(self, access_group_id: int, **kwargs: Any) -> AccessGroup:
100
+ return AccessGroup.model_validate(
101
+ await self._t.request("PUT", f"{_P}/access_groups/{access_group_id}", json={"access_group": kwargs}))
102
+
103
+ async def archive_access_group(self, access_group_id: int) -> Dict[str, Any]:
104
+ return await self._t.request("DELETE", f"{_P}/access_groups/{access_group_id}")
105
+
106
+ async def unarchive_access_group(self, access_group_id: int) -> AccessGroup:
107
+ return AccessGroup.model_validate(
108
+ await self._t.request("PATCH", f"{_P}/access_groups/{access_group_id}/unarchive"))
109
+
110
+ async def list_access_group_members(self, access_group_id: int, *, page: int = 1,
111
+ per_page: int = 60) -> AccessGroupCommunityMemberList:
112
+ return AccessGroupCommunityMemberList.model_validate(
113
+ await self._t.request("GET", f"{_P}/access_groups/{access_group_id}/community_members",
114
+ params=_page_params(page, per_page)))
115
+
116
+ async def show_access_group_member(self, access_group_id: int, *, email: str) -> AccessGroupCommunityMember:
117
+ return AccessGroupCommunityMember.model_validate(
118
+ await self._t.request("GET", f"{_P}/access_groups/{access_group_id}/community_member",
119
+ params={"email": email}))
120
+
121
+ async def add_access_group_member(self, access_group_id: int, *, email: str) -> Dict[str, Any]:
122
+ return await self._t.request("POST", f"{_P}/access_groups/{access_group_id}/community_members",
123
+ json={"email": email})
124
+
125
+ async def remove_access_group_member(self, access_group_id: int, *, email: str) -> Dict[str, Any]:
126
+ return await self._t.request("DELETE", f"{_P}/access_groups/{access_group_id}/community_members",
127
+ params={"email": email})
128
+
129
+ async def list_community_member_access_groups(self, community_member_id: int, *, page: int = 1,
130
+ per_page: int = 60) -> AccessGroupList:
131
+ return AccessGroupList.model_validate(
132
+ await self._t.request("GET", f"{_P}/community_members/{community_member_id}/access_groups",
133
+ params=_page_params(page, per_page)))
@@ -0,0 +1,122 @@
1
+ """Admin API -- Community & Community Members."""
2
+ from __future__ import annotations
3
+ from typing import Any, Dict, Optional
4
+ from circle.constants import ADMIN_V2_PREFIX as _P
5
+ from circle.http import AsyncTransport, SyncTransport
6
+ from circle.models.admin.community import Community
7
+ from circle.models.admin.members import CommunityMember, CommunityMemberList, CommunityMemberCreated
8
+ from circle.models.admin.spaces import SpaceList
9
+
10
+
11
+ def _list_members_params(page: int, per_page: int, status: Optional[str]) -> Dict[str, Any]:
12
+ p: Dict[str, Any] = {"page": page, "per_page": per_page}
13
+ if status:
14
+ p["status"] = status
15
+ return p
16
+
17
+
18
+ def _member_spaces_params(
19
+ page: int, per_page: int,
20
+ community_member_id: Optional[int], user_email: Optional[str],
21
+ ) -> Dict[str, Any]:
22
+ p: Dict[str, Any] = {"page": page, "per_page": per_page}
23
+ if community_member_id:
24
+ p["community_member_id"] = community_member_id
25
+ if user_email:
26
+ p["user_email"] = user_email
27
+ return p
28
+
29
+
30
+ class CommunityClient:
31
+ def __init__(self, transport: SyncTransport) -> None:
32
+ self._t = transport
33
+
34
+ def get_community(self) -> Community:
35
+ return Community.model_validate(self._t.request("GET", f"{_P}/community"))
36
+
37
+ def update_community(self, **kwargs: Any) -> Community:
38
+ return Community.model_validate(self._t.request("PUT", f"{_P}/community", json={"community": kwargs}))
39
+
40
+ def list_community_members(self, *, page: int = 1, per_page: int = 10,
41
+ status: Optional[str] = None) -> CommunityMemberList:
42
+ return CommunityMemberList.model_validate(
43
+ self._t.request("GET", f"{_P}/community_members", params=_list_members_params(page, per_page, status)))
44
+
45
+ def create_community_member(self, *, email: str, **kwargs: Any) -> CommunityMemberCreated:
46
+ return CommunityMemberCreated.model_validate(
47
+ self._t.request("POST", f"{_P}/community_members", json={"email": email, **kwargs}))
48
+
49
+ def show_community_member(self, member_id: int) -> CommunityMember:
50
+ return CommunityMember.model_validate(self._t.request("GET", f"{_P}/community_members/{member_id}"))
51
+
52
+ def update_community_member(self, member_id: int, **kwargs: Any) -> CommunityMember:
53
+ return CommunityMember.model_validate(
54
+ self._t.request("PUT", f"{_P}/community_members/{member_id}", json=kwargs))
55
+
56
+ def deactivate_community_member(self, member_id: int) -> Dict[str, Any]:
57
+ return self._t.request("DELETE", f"{_P}/community_members/{member_id}")
58
+
59
+ def search_community_member(self, *, email: str) -> CommunityMember:
60
+ return CommunityMember.model_validate(
61
+ self._t.request("GET", f"{_P}/community_members/search", params={"email": email}))
62
+
63
+ def ban_community_member(self, member_id: int) -> Dict[str, Any]:
64
+ return self._t.request("PUT", f"{_P}/community_members/{member_id}/ban_member")
65
+
66
+ def delete_community_member(self, member_id: int) -> Dict[str, Any]:
67
+ return self._t.request("PUT", f"{_P}/community_members/{member_id}/delete_member")
68
+
69
+ def list_community_member_spaces(self, *, page: int = 1, per_page: int = 60,
70
+ community_member_id: Optional[int] = None,
71
+ user_email: Optional[str] = None) -> SpaceList:
72
+ return SpaceList.model_validate(
73
+ self._t.request("GET", f"{_P}/community_member_spaces",
74
+ params=_member_spaces_params(page, per_page, community_member_id, user_email)))
75
+
76
+
77
+ class AsyncCommunityClient:
78
+ def __init__(self, transport: AsyncTransport) -> None:
79
+ self._t = transport
80
+
81
+ async def get_community(self) -> Community:
82
+ return Community.model_validate(await self._t.request("GET", f"{_P}/community"))
83
+
84
+ async def update_community(self, **kwargs: Any) -> Community:
85
+ return Community.model_validate(await self._t.request("PUT", f"{_P}/community", json={"community": kwargs}))
86
+
87
+ async def list_community_members(self, *, page: int = 1, per_page: int = 10,
88
+ status: Optional[str] = None) -> CommunityMemberList:
89
+ return CommunityMemberList.model_validate(
90
+ await self._t.request("GET", f"{_P}/community_members",
91
+ params=_list_members_params(page, per_page, status)))
92
+
93
+ async def create_community_member(self, *, email: str, **kwargs: Any) -> CommunityMemberCreated:
94
+ return CommunityMemberCreated.model_validate(
95
+ await self._t.request("POST", f"{_P}/community_members", json={"email": email, **kwargs}))
96
+
97
+ async def show_community_member(self, member_id: int) -> CommunityMember:
98
+ return CommunityMember.model_validate(await self._t.request("GET", f"{_P}/community_members/{member_id}"))
99
+
100
+ async def update_community_member(self, member_id: int, **kwargs: Any) -> CommunityMember:
101
+ return CommunityMember.model_validate(
102
+ await self._t.request("PUT", f"{_P}/community_members/{member_id}", json=kwargs))
103
+
104
+ async def deactivate_community_member(self, member_id: int) -> Dict[str, Any]:
105
+ return await self._t.request("DELETE", f"{_P}/community_members/{member_id}")
106
+
107
+ async def search_community_member(self, *, email: str) -> CommunityMember:
108
+ return CommunityMember.model_validate(
109
+ await self._t.request("GET", f"{_P}/community_members/search", params={"email": email}))
110
+
111
+ async def ban_community_member(self, member_id: int) -> Dict[str, Any]:
112
+ return await self._t.request("PUT", f"{_P}/community_members/{member_id}/ban_member")
113
+
114
+ async def delete_community_member(self, member_id: int) -> Dict[str, Any]:
115
+ return await self._t.request("PUT", f"{_P}/community_members/{member_id}/delete_member")
116
+
117
+ async def list_community_member_spaces(self, *, page: int = 1, per_page: int = 60,
118
+ community_member_id: Optional[int] = None,
119
+ user_email: Optional[str] = None) -> SpaceList:
120
+ return SpaceList.model_validate(
121
+ await self._t.request("GET", f"{_P}/community_member_spaces",
122
+ params=_member_spaces_params(page, per_page, community_member_id, user_email)))
@@ -0,0 +1,172 @@
1
+ """Admin API -- Courses (Sections, Lessons, Progress)."""
2
+ from __future__ import annotations
3
+ from typing import Any, Dict, Optional
4
+ from circle.constants import ADMIN_V2_PREFIX as _P
5
+ from circle.http import AsyncTransport, SyncTransport
6
+ from circle.models.admin.courses import (
7
+ CourseSection, CourseSectionList, CourseLesson, CourseLessonList,
8
+ )
9
+
10
+
11
+ def _list_sections_params(page: int, per_page: int, space_id: Optional[int],
12
+ sort: Optional[str]) -> Dict[str, Any]:
13
+ p: Dict[str, Any] = {"page": page, "per_page": per_page}
14
+ if space_id:
15
+ p["space_id"] = space_id
16
+ if sort:
17
+ p["sort"] = sort
18
+ return p
19
+
20
+
21
+ def _list_lessons_params(page: int, per_page: int, section_id: Optional[int],
22
+ space_id: Optional[int], status: Optional[str],
23
+ sort: Optional[str]) -> Dict[str, Any]:
24
+ p: Dict[str, Any] = {"page": page, "per_page": per_page}
25
+ if section_id:
26
+ p["section_id"] = section_id
27
+ if space_id:
28
+ p["space_id"] = space_id
29
+ if status:
30
+ p["status"] = status
31
+ if sort:
32
+ p["sort"] = sort
33
+ return p
34
+
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # Sync client
38
+ # ---------------------------------------------------------------------------
39
+
40
+ class CoursesClient:
41
+ def __init__(self, transport: SyncTransport) -> None:
42
+ self._t = transport
43
+
44
+ # -- Sections --
45
+ def list_course_sections(self, *, page: int = 1, per_page: int = 10,
46
+ space_id: Optional[int] = None,
47
+ sort: Optional[str] = None) -> CourseSectionList:
48
+ p = _list_sections_params(page, per_page, space_id, sort)
49
+ return CourseSectionList.model_validate(
50
+ self._t.request("GET", f"{_P}/course_sections", params=p))
51
+
52
+ def create_course_section(self, *, name: str, space_id: int) -> CourseSection:
53
+ return CourseSection.model_validate(
54
+ self._t.request("POST", f"{_P}/course_sections",
55
+ json={"name": name, "space_id": space_id}))
56
+
57
+ def show_course_section(self, section_id: int) -> CourseSection:
58
+ return CourseSection.model_validate(
59
+ self._t.request("GET", f"{_P}/course_sections/{section_id}"))
60
+
61
+ def update_course_section(self, section_id: int, *, name: str) -> CourseSection:
62
+ return CourseSection.model_validate(
63
+ self._t.request("PUT", f"{_P}/course_sections/{section_id}",
64
+ json={"name": name}))
65
+
66
+ def delete_course_section(self, section_id: int) -> Dict[str, Any]:
67
+ return self._t.request("DELETE", f"{_P}/course_sections/{section_id}")
68
+
69
+ # -- Lessons --
70
+ def list_course_lessons(self, *, page: int = 1, per_page: int = 10,
71
+ section_id: Optional[int] = None,
72
+ space_id: Optional[int] = None,
73
+ status: Optional[str] = None,
74
+ sort: Optional[str] = None) -> CourseLessonList:
75
+ p = _list_lessons_params(page, per_page, section_id, space_id, status, sort)
76
+ return CourseLessonList.model_validate(
77
+ self._t.request("GET", f"{_P}/course_lessons", params=p))
78
+
79
+ def create_course_lesson(self, *, name: str, section_id: int,
80
+ **kwargs: Any) -> CourseLesson:
81
+ return CourseLesson.model_validate(
82
+ self._t.request("POST", f"{_P}/course_lessons",
83
+ json={"name": name, "section_id": section_id, **kwargs}))
84
+
85
+ def show_course_lesson(self, lesson_id: int) -> CourseLesson:
86
+ return CourseLesson.model_validate(
87
+ self._t.request("GET", f"{_P}/course_lessons/{lesson_id}"))
88
+
89
+ def update_course_lesson(self, lesson_id: int, **kwargs: Any) -> CourseLesson:
90
+ return CourseLesson.model_validate(
91
+ self._t.request("PATCH", f"{_P}/course_lessons/{lesson_id}", json=kwargs))
92
+
93
+ def delete_course_lesson(self, lesson_id: int) -> Dict[str, Any]:
94
+ return self._t.request("DELETE", f"{_P}/course_lessons/{lesson_id}")
95
+
96
+ # -- Progress --
97
+ def update_course_lesson_progress(self, *, lesson_id: int, member_email: str,
98
+ status: str) -> Dict[str, Any]:
99
+ return self._t.request("PUT", f"{_P}/course_lesson_progress",
100
+ json={"lesson_id": lesson_id,
101
+ "member_email": member_email,
102
+ "status": status})
103
+
104
+
105
+ # ---------------------------------------------------------------------------
106
+ # Async client
107
+ # ---------------------------------------------------------------------------
108
+
109
+ class AsyncCoursesClient:
110
+ def __init__(self, transport: AsyncTransport) -> None:
111
+ self._t = transport
112
+
113
+ # -- Sections --
114
+ async def list_course_sections(self, *, page: int = 1, per_page: int = 10,
115
+ space_id: Optional[int] = None,
116
+ sort: Optional[str] = None) -> CourseSectionList:
117
+ p = _list_sections_params(page, per_page, space_id, sort)
118
+ return CourseSectionList.model_validate(
119
+ await self._t.request("GET", f"{_P}/course_sections", params=p))
120
+
121
+ async def create_course_section(self, *, name: str, space_id: int) -> CourseSection:
122
+ return CourseSection.model_validate(
123
+ await self._t.request("POST", f"{_P}/course_sections",
124
+ json={"name": name, "space_id": space_id}))
125
+
126
+ async def show_course_section(self, section_id: int) -> CourseSection:
127
+ return CourseSection.model_validate(
128
+ await self._t.request("GET", f"{_P}/course_sections/{section_id}"))
129
+
130
+ async def update_course_section(self, section_id: int, *, name: str) -> CourseSection:
131
+ return CourseSection.model_validate(
132
+ await self._t.request("PUT", f"{_P}/course_sections/{section_id}",
133
+ json={"name": name}))
134
+
135
+ async def delete_course_section(self, section_id: int) -> Dict[str, Any]:
136
+ return await self._t.request("DELETE", f"{_P}/course_sections/{section_id}")
137
+
138
+ # -- Lessons --
139
+ async def list_course_lessons(self, *, page: int = 1, per_page: int = 10,
140
+ section_id: Optional[int] = None,
141
+ space_id: Optional[int] = None,
142
+ status: Optional[str] = None,
143
+ sort: Optional[str] = None) -> CourseLessonList:
144
+ p = _list_lessons_params(page, per_page, section_id, space_id, status, sort)
145
+ return CourseLessonList.model_validate(
146
+ await self._t.request("GET", f"{_P}/course_lessons", params=p))
147
+
148
+ async def create_course_lesson(self, *, name: str, section_id: int,
149
+ **kwargs: Any) -> CourseLesson:
150
+ return CourseLesson.model_validate(
151
+ await self._t.request("POST", f"{_P}/course_lessons",
152
+ json={"name": name, "section_id": section_id, **kwargs}))
153
+
154
+ async def show_course_lesson(self, lesson_id: int) -> CourseLesson:
155
+ return CourseLesson.model_validate(
156
+ await self._t.request("GET", f"{_P}/course_lessons/{lesson_id}"))
157
+
158
+ async def update_course_lesson(self, lesson_id: int, **kwargs: Any) -> CourseLesson:
159
+ return CourseLesson.model_validate(
160
+ await self._t.request("PATCH", f"{_P}/course_lessons/{lesson_id}",
161
+ json=kwargs))
162
+
163
+ async def delete_course_lesson(self, lesson_id: int) -> Dict[str, Any]:
164
+ return await self._t.request("DELETE", f"{_P}/course_lessons/{lesson_id}")
165
+
166
+ # -- Progress --
167
+ async def update_course_lesson_progress(self, *, lesson_id: int, member_email: str,
168
+ status: str) -> Dict[str, Any]:
169
+ return await self._t.request("PUT", f"{_P}/course_lesson_progress",
170
+ json={"lesson_id": lesson_id,
171
+ "member_email": member_email,
172
+ "status": status})
@@ -0,0 +1,101 @@
1
+ """Admin API -- Events & Event Attendees."""
2
+ from __future__ import annotations
3
+ from typing import Any, Dict, Optional
4
+ from circle.constants import ADMIN_V2_PREFIX as _P
5
+ from circle.http import AsyncTransport, SyncTransport
6
+ from circle.models.admin.events import Event, EventList, EventAttendee, EventAttendeeList
7
+
8
+
9
+ def _list_events_params(
10
+ page: int, per_page: int, space_id: Optional[int], sort: Optional[str], **kwargs: Any,
11
+ ) -> Dict[str, Any]:
12
+ p: Dict[str, Any] = {"page": page, "per_page": per_page, **kwargs}
13
+ if space_id:
14
+ p["space_id"] = space_id
15
+ if sort:
16
+ p["sort"] = sort
17
+ return p
18
+
19
+
20
+ class EventsClient:
21
+ def __init__(self, transport: SyncTransport) -> None:
22
+ self._t = transport
23
+
24
+ def list_events(self, *, page: int = 1, per_page: int = 60, space_id: Optional[int] = None,
25
+ sort: Optional[str] = None, **kwargs: Any) -> EventList:
26
+ return EventList.model_validate(
27
+ self._t.request("GET", f"{_P}/events",
28
+ params=_list_events_params(page, per_page, space_id, sort, **kwargs)))
29
+
30
+ def create_event(self, *, space_id: int, **kwargs: Any) -> Event:
31
+ return Event.model_validate(
32
+ self._t.request("POST", f"{_P}/events", json={"event": kwargs, "space_id": space_id}))
33
+
34
+ def get_event(self, event_id: int) -> Event:
35
+ return Event.model_validate(self._t.request("GET", f"{_P}/events/{event_id}"))
36
+
37
+ def update_event(self, event_id: int, *, space_id: int, **kwargs: Any) -> Event:
38
+ return Event.model_validate(
39
+ self._t.request("PUT", f"{_P}/events/{event_id}", json={"event": kwargs, "space_id": space_id}))
40
+
41
+ def delete_event(self, event_id: int, *, space_id: int) -> Dict[str, Any]:
42
+ return self._t.request("DELETE", f"{_P}/events/{event_id}", params={"space_id": space_id})
43
+
44
+ def duplicate_event(self, space_id: int, event_id: int, **kwargs: Any) -> Event:
45
+ return Event.model_validate(
46
+ self._t.request("POST", f"{_P}/spaces/{space_id}/events/{event_id}/duplicate", json=kwargs))
47
+
48
+ def list_event_attendees(self, *, event_id: int, page: int = 1, per_page: int = 10) -> EventAttendeeList:
49
+ return EventAttendeeList.model_validate(
50
+ self._t.request("GET", f"{_P}/event_attendees",
51
+ params={"event_id": event_id, "page": page, "per_page": per_page}))
52
+
53
+ def create_event_attendee(self, *, event_id: int, member_email: str) -> Dict[str, Any]:
54
+ return self._t.request("POST", f"{_P}/event_attendees",
55
+ json={"event_id": event_id, "member_email": member_email})
56
+
57
+ def delete_event_attendee(self, *, event_id: int, member_email: str) -> Dict[str, Any]:
58
+ return self._t.request("DELETE", f"{_P}/event_attendees",
59
+ json={"event_id": event_id, "member_email": member_email})
60
+
61
+
62
+ class AsyncEventsClient:
63
+ def __init__(self, transport: AsyncTransport) -> None:
64
+ self._t = transport
65
+
66
+ async def list_events(self, *, page: int = 1, per_page: int = 60, space_id: Optional[int] = None,
67
+ sort: Optional[str] = None, **kwargs: Any) -> EventList:
68
+ return EventList.model_validate(
69
+ await self._t.request("GET", f"{_P}/events",
70
+ params=_list_events_params(page, per_page, space_id, sort, **kwargs)))
71
+
72
+ async def create_event(self, *, space_id: int, **kwargs: Any) -> Event:
73
+ return Event.model_validate(
74
+ await self._t.request("POST", f"{_P}/events", json={"event": kwargs, "space_id": space_id}))
75
+
76
+ async def get_event(self, event_id: int) -> Event:
77
+ return Event.model_validate(await self._t.request("GET", f"{_P}/events/{event_id}"))
78
+
79
+ async def update_event(self, event_id: int, *, space_id: int, **kwargs: Any) -> Event:
80
+ return Event.model_validate(
81
+ await self._t.request("PUT", f"{_P}/events/{event_id}", json={"event": kwargs, "space_id": space_id}))
82
+
83
+ async def delete_event(self, event_id: int, *, space_id: int) -> Dict[str, Any]:
84
+ return await self._t.request("DELETE", f"{_P}/events/{event_id}", params={"space_id": space_id})
85
+
86
+ async def duplicate_event(self, space_id: int, event_id: int, **kwargs: Any) -> Event:
87
+ return Event.model_validate(
88
+ await self._t.request("POST", f"{_P}/spaces/{space_id}/events/{event_id}/duplicate", json=kwargs))
89
+
90
+ async def list_event_attendees(self, *, event_id: int, page: int = 1, per_page: int = 10) -> EventAttendeeList:
91
+ return EventAttendeeList.model_validate(
92
+ await self._t.request("GET", f"{_P}/event_attendees",
93
+ params={"event_id": event_id, "page": page, "per_page": per_page}))
94
+
95
+ async def create_event_attendee(self, *, event_id: int, member_email: str) -> Dict[str, Any]:
96
+ return await self._t.request("POST", f"{_P}/event_attendees",
97
+ json={"event_id": event_id, "member_email": member_email})
98
+
99
+ async def delete_event_attendee(self, *, event_id: int, member_email: str) -> Dict[str, Any]:
100
+ return await self._t.request("DELETE", f"{_P}/event_attendees",
101
+ json={"event_id": event_id, "member_email": member_email})