fountain-life-service-clients 3.28.2__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 (28) hide show
  1. fountain_life_service_clients/__init__.py +0 -0
  2. fountain_life_service_clients/_base_client.py +30 -0
  3. fountain_life_service_clients/account_service.py +116 -0
  4. fountain_life_service_clients/account_service_policy_attributes.py +46 -0
  5. fountain_life_service_clients/agents_api_service.py +197 -0
  6. fountain_life_service_clients/claimed_domains_service.py +70 -0
  7. fountain_life_service_clients/cohorts_service.py +184 -0
  8. fountain_life_service_clients/ehr_ingestion_wearables_api.py +169 -0
  9. fountain_life_service_clients/ehr_service.py +334 -0
  10. fountain_life_service_clients/email_service_email.py +81 -0
  11. fountain_life_service_clients/email_service_sms.py +33 -0
  12. fountain_life_service_clients/fhir_post_processor_service.py +55 -0
  13. fountain_life_service_clients/fhir_search_service.py +262 -0
  14. fountain_life_service_clients/file_service.py +124 -0
  15. fountain_life_service_clients/invitation_service.py +94 -0
  16. fountain_life_service_clients/medical_results_service_results.py +228 -0
  17. fountain_life_service_clients/member_notification_service.py +69 -0
  18. fountain_life_service_clients/member_operations_service_members.py +40 -0
  19. fountain_life_service_clients/member_scheduling_service_scheduling_prompts.py +62 -0
  20. fountain_life_service_clients/oauth_apps_service.py +253 -0
  21. fountain_life_service_clients/patient_service.py +157 -0
  22. fountain_life_service_clients/rules_service.py +249 -0
  23. fountain_life_service_clients/scheduler_service.py +146 -0
  24. fountain_life_service_clients/survey_service.py +404 -0
  25. fountain_life_service_clients/user_service.py +152 -0
  26. fountain_life_service_clients-3.28.2.dist-info/METADATA +53 -0
  27. fountain_life_service_clients-3.28.2.dist-info/RECORD +28 -0
  28. fountain_life_service_clients-3.28.2.dist-info/WHEEL +4 -0
File without changes
@@ -0,0 +1,30 @@
1
+ from typing import NotRequired, Unpack, cast
2
+
3
+ from lifeomic_chatbot_tools.aws.alpha import (
4
+ Alpha,
5
+ )
6
+ from lifeomic_chatbot_tools.aws.alpha import (
7
+ AlphaConfig as BaseAlphaConfig,
8
+ )
9
+ from lifeomic_chatbot_tools.aws.alpha import (
10
+ AlphaResponse as BaseAlphaResponse,
11
+ )
12
+
13
+
14
+ class AlphaConfig(BaseAlphaConfig):
15
+ # Pull target out as another keyword arg instead of a positional
16
+ # arg, to make it easier to work with.
17
+ target: NotRequired[str]
18
+
19
+
20
+ class BaseClient:
21
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
22
+ self.client = Alpha(**cfg)
23
+
24
+
25
+ # A typed version of AlphaResponse that allows us to access the
26
+ # response body as a typed object.
27
+ class AlphaResponse[T](BaseAlphaResponse):
28
+ @property
29
+ def body(self):
30
+ return cast(T, super().body)
@@ -0,0 +1,116 @@
1
+ # This file was generated automatically. Do not edit it directly.
2
+ # generated by datamodel-codegen:
3
+ # filename: account-service.json
4
+ from typing import List, Literal, NotRequired, Optional, TypedDict, Unpack, cast
5
+ from urllib.parse import quote
6
+
7
+ from fountain_life_service_clients._base_client import (
8
+ AlphaConfig,
9
+ AlphaResponse,
10
+ BaseClient,
11
+ )
12
+
13
+
14
+ class Account(TypedDict):
15
+ id: str
16
+ name: str
17
+ owner: str
18
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
19
+
20
+
21
+ class ListAllAccountsResponse(TypedDict):
22
+ accounts: List[Account]
23
+
24
+
25
+ class CreateAnAccountRequest(TypedDict):
26
+ id: str
27
+ name: str
28
+ owner: str
29
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
30
+
31
+
32
+ class CreateAnAccountResponse(TypedDict):
33
+ id: str
34
+ name: str
35
+ owner: str
36
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
37
+
38
+
39
+ class RetrieveAnAccountParams(TypedDict):
40
+ include: NotRequired[Literal["groups"]]
41
+
42
+
43
+ class RetrieveAnAccountResponse(TypedDict):
44
+ id: str
45
+ name: str
46
+ owner: str
47
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
48
+
49
+
50
+ class UpdateAnAccountRequest(TypedDict):
51
+ name: NotRequired[str]
52
+ deletionDate: NotRequired[Optional[str]]
53
+
54
+
55
+ class UpdateAnAccountResponse(TypedDict):
56
+ id: str
57
+ name: str
58
+ owner: str
59
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
60
+
61
+
62
+ class DeleteAnAccountParams(TypedDict):
63
+ force: NotRequired[bool]
64
+
65
+
66
+ class DeleteAnAccountResponse1(TypedDict):
67
+ """
68
+ The account object, or null if the account was not found/already deleted.
69
+ """
70
+
71
+ id: str
72
+ name: str
73
+ owner: str
74
+ type: Literal["FREE", "PAID", "ENTERPRISE"]
75
+
76
+
77
+ DeleteAnAccountResponse = Optional[DeleteAnAccountResponse1]
78
+
79
+
80
+ class AccountServiceClient(BaseClient):
81
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
82
+ kwargs = {"target": "lambda://account-service:deployed", **(cfg or {})}
83
+ super().__init__(**kwargs)
84
+
85
+ async def list_all_accounts(self):
86
+ """Returns a list of accounts that the user has access to."""
87
+ res = await self.client.request(path="/v1/accounts", method="GET")
88
+ return cast(AlphaResponse[ListAllAccountsResponse], res)
89
+
90
+ async def create_an_account(self, body: CreateAnAccountRequest):
91
+ """Creates an account, returning the account object."""
92
+ res = await self.client.request(
93
+ path="/v1/accounts", method="POST", body=cast(dict, body)
94
+ )
95
+ return cast(AlphaResponse[CreateAnAccountResponse], res)
96
+
97
+ async def retrieve_an_account(self, id: str, params: RetrieveAnAccountParams):
98
+ """Retrieves details about an account. Returns the account object."""
99
+ res = await self.client.request(
100
+ path=f"/v1/accounts/{quote(id)}", method="GET", params=cast(dict, params)
101
+ )
102
+ return cast(AlphaResponse[RetrieveAnAccountResponse], res)
103
+
104
+ async def update_an_account(self, id: str, body: UpdateAnAccountRequest):
105
+ """Update an account by changing the name or clearing out a pending deletion date. Returns the account object."""
106
+ res = await self.client.request(
107
+ path=f"/v1/accounts/{quote(id)}", method="PATCH", body=cast(dict, body)
108
+ )
109
+ return cast(AlphaResponse[UpdateAnAccountResponse], res)
110
+
111
+ async def delete_an_account(self, id: str, params: DeleteAnAccountParams):
112
+ """Deletes an account. By default, the account will not be deleted for 14 days. During this time, the pending deletion can be cancelled by using the `PATCH` method. After the 14 day grace period, the account and all of its data will be removed."""
113
+ res = await self.client.request(
114
+ path=f"/v1/accounts/{quote(id)}", method="DELETE", params=cast(dict, params)
115
+ )
116
+ return cast(AlphaResponse[DeleteAnAccountResponse], res)
@@ -0,0 +1,46 @@
1
+ # This file was generated automatically. Do not edit it directly.
2
+ # generated by datamodel-codegen:
3
+ # filename: account-service-policy-attributes.json
4
+ from typing import Any, Dict, TypedDict, Unpack, cast
5
+ from urllib.parse import quote
6
+
7
+ from fountain_life_service_clients._base_client import (
8
+ AlphaConfig,
9
+ AlphaResponse,
10
+ BaseClient,
11
+ )
12
+
13
+
14
+ class PolicyAttributesObject(TypedDict):
15
+ attributes: Dict[str, Any]
16
+
17
+
18
+ class AccountServicePolicyAttributesClient(BaseClient):
19
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
20
+ kwargs = {"target": "lambda://account-service:deployed", **(cfg or {})}
21
+ super().__init__(**kwargs)
22
+
23
+ async def update_policy_attributes_for_user(
24
+ self, username: str, body: PolicyAttributesObject
25
+ ):
26
+ """Updates the policy attributes for the specified user, returning the updated
27
+ attributes.
28
+
29
+ Using this API requires access to the `accessAdmin` operation.
30
+ """
31
+ res = await self.client.request(
32
+ path=f"/v1/policy-attributes/users/{quote(username)}",
33
+ method="PUT",
34
+ body=cast(dict, body),
35
+ )
36
+ return cast(AlphaResponse[PolicyAttributesObject], res)
37
+
38
+ async def get_policy_attributes_for_user(self, username: str):
39
+ """Fetches the policy attributes for the specified user.
40
+
41
+ Using this API requires access to the `accessAdmin` operation.
42
+ """
43
+ res = await self.client.request(
44
+ path=f"/v1/policy-attributes/users/{quote(username)}", method="GET"
45
+ )
46
+ return cast(AlphaResponse[PolicyAttributesObject], res)
@@ -0,0 +1,197 @@
1
+ # This file was generated automatically. Do not edit it directly.
2
+ # generated by datamodel-codegen:
3
+ # filename: agents-api-service.json
4
+ from typing import Any, Dict, List, Literal, NotRequired, TypedDict, Unpack, cast
5
+ from urllib.parse import quote
6
+
7
+ from fountain_life_service_clients._base_client import (
8
+ AlphaConfig,
9
+ AlphaResponse,
10
+ BaseClient,
11
+ )
12
+
13
+
14
+ class InvokeBasicAgentRequest(TypedDict):
15
+ input: str
16
+
17
+
18
+ class InvokeBasicAgentResponse(TypedDict):
19
+ output: str
20
+
21
+
22
+ class InvokeHealthSummaryAgentRequest(TypedDict):
23
+ subject_id: str
24
+ project_id: str
25
+ mutate: NotRequired[bool]
26
+ should_extract_data: NotRequired[bool]
27
+ should_include_synopsis_layout: NotRequired[bool]
28
+
29
+
30
+ class InvokeHealthSummaryAgentResponse(TypedDict):
31
+ task_id: str
32
+
33
+
34
+ class GetHealthSummaryInvocationsParams(TypedDict):
35
+ subject_id: str
36
+
37
+
38
+ class GetHealthSummaryInvocationsResponseItem(TypedDict):
39
+ created: float
40
+ expires: NotRequired[float]
41
+ id: str
42
+ scheduled: NotRequired[float]
43
+ status: Literal[
44
+ "scheduled", "pending", "processing", "failed", "completed", "expired"
45
+ ]
46
+ accountId: str
47
+ agent: str
48
+ agentInput: Dict[str, Any]
49
+ subjectId: str
50
+
51
+
52
+ GetHealthSummaryInvocationsResponse = List[GetHealthSummaryInvocationsResponseItem]
53
+
54
+
55
+ class GetHealthSummaryScheduledTaskResponse(TypedDict):
56
+ created: float
57
+ expires: NotRequired[float]
58
+ id: str
59
+ scheduled: NotRequired[float]
60
+ status: Literal[
61
+ "scheduled", "pending", "processing", "failed", "completed", "expired"
62
+ ]
63
+ accountId: str
64
+ agent: str
65
+ agentInput: Dict[str, Any]
66
+ subjectId: str
67
+
68
+
69
+ class FlushHealthSummaryScheduledTaskRequest(TypedDict):
70
+ pass
71
+
72
+
73
+ class ProvideMessageFeedbackRequest(TypedDict):
74
+ agent_name: str
75
+ trace_id: str
76
+ feedback: NotRequired[str]
77
+ score: NotRequired[float]
78
+ emoji: NotRequired[str]
79
+
80
+
81
+ class InvokeActionPlanNudgeRequest(TypedDict):
82
+ account_id: str
83
+ project_id: str
84
+ subject_id: str
85
+ user_id: str
86
+ correlation_id: NotRequired[str]
87
+
88
+
89
+ class InvokeActionPlanNudgeResponse(TypedDict):
90
+ subject_id: str
91
+ nudge: Dict[str, Any]
92
+
93
+
94
+ class GetAgentTokenResponse(TypedDict):
95
+ AccessKeyId: str
96
+ SecretAccessKey: str
97
+ SessionToken: str
98
+ Expiration: str
99
+
100
+
101
+ class ValidateFileOwnershipRequest(TypedDict):
102
+ subject_id: str
103
+ file_id: str
104
+ project_id: str
105
+ document_reference_id: str
106
+
107
+
108
+ class Result(TypedDict):
109
+ status: Literal["valid", "invalid", "inconclusive"]
110
+ reasoning: str
111
+
112
+
113
+ class ValidateFileOwnershipResponse(TypedDict):
114
+ subject_id: str
115
+ file_id: str
116
+ document_reference_id: str
117
+ result: Result
118
+
119
+
120
+ class AgentsApiServiceClient(BaseClient):
121
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
122
+ kwargs = {"target": "lambda://agents-api-service-v2:deployed", **(cfg or {})}
123
+ super().__init__(**kwargs)
124
+
125
+ async def invoke_basic_agent(self, body: InvokeBasicAgentRequest):
126
+ """Invoke the basic agent"""
127
+ res = await self.client.request(
128
+ path="/v1/agents-v2/basic/invoke", method="POST", body=cast(dict, body)
129
+ )
130
+ return cast(AlphaResponse[InvokeBasicAgentResponse], res)
131
+
132
+ async def invoke_health_summary_agent(self, body: InvokeHealthSummaryAgentRequest):
133
+ """Invoke the health summary agent"""
134
+ res = await self.client.request(
135
+ path="/v1/agents-v2/health-summary/invoke",
136
+ method="POST",
137
+ body=cast(dict, body),
138
+ )
139
+ return cast(AlphaResponse[InvokeHealthSummaryAgentResponse], res)
140
+
141
+ async def get_health_summary_invocations(
142
+ self, params: GetHealthSummaryInvocationsParams
143
+ ):
144
+ """Get the health summary invocations"""
145
+ res = await self.client.request(
146
+ path="/v1/agents-v2/health-summary/invocations",
147
+ method="GET",
148
+ params=cast(dict, params),
149
+ )
150
+ return cast(AlphaResponse[GetHealthSummaryInvocationsResponse], res)
151
+
152
+ async def get_health_summary_scheduled_task(self, task_id: str):
153
+ """Get a health summary scheduled task"""
154
+ res = await self.client.request(
155
+ path=f"/v1/agents-v2/health-summary/invocations/{quote(task_id)}",
156
+ method="GET",
157
+ )
158
+ return cast(AlphaResponse[GetHealthSummaryScheduledTaskResponse], res)
159
+
160
+ async def flush_health_summary_scheduled_task(
161
+ self, task_id: str, body: FlushHealthSummaryScheduledTaskRequest
162
+ ):
163
+ """Flush the health summary scheduled task so it is run immediately"""
164
+ await self.client.request(
165
+ path=f"/v1/agents-v2/health-summary/scheduled/{quote(task_id)}",
166
+ method="PATCH",
167
+ body=cast(dict, body),
168
+ )
169
+
170
+ async def provide_message_feedback(self, body: ProvideMessageFeedbackRequest):
171
+ """Provide feedback on a message"""
172
+ await self.client.request(
173
+ path="/v1/agents-v2/feedback", method="POST", body=cast(dict, body)
174
+ )
175
+
176
+ async def invoke_action_plan_nudge(self, body: InvokeActionPlanNudgeRequest):
177
+ """Invoke the action plan nudge agent"""
178
+ res = await self.client.request(
179
+ path="/v1/private/agents-v2/action-plan-nudge/invoke",
180
+ method="POST",
181
+ body=cast(dict, body),
182
+ )
183
+ return cast(AlphaResponse[InvokeActionPlanNudgeResponse], res)
184
+
185
+ async def get_agent_token(self):
186
+ """Get an agent token for the current user"""
187
+ res = await self.client.request(path="/v1/agents-v2/token", method="GET")
188
+ return cast(AlphaResponse[GetAgentTokenResponse], res)
189
+
190
+ async def validate_file_ownership(self, body: ValidateFileOwnershipRequest):
191
+ """Validate file ownership"""
192
+ res = await self.client.request(
193
+ path="/v1/private/agents-v2/validate-ownership/invoke",
194
+ method="POST",
195
+ body=cast(dict, body),
196
+ )
197
+ return cast(AlphaResponse[ValidateFileOwnershipResponse], res)
@@ -0,0 +1,70 @@
1
+ # This file was generated automatically. Do not edit it directly.
2
+ # generated by datamodel-codegen:
3
+ # filename: claimed-domains-service.json
4
+ from typing import List, Literal, NotRequired, TypedDict, Unpack, cast
5
+
6
+ from fountain_life_service_clients._base_client import (
7
+ AlphaConfig,
8
+ AlphaResponse,
9
+ BaseClient,
10
+ )
11
+
12
+
13
+ class PrivateListDomainsParams(TypedDict):
14
+ domain: str
15
+ pageSize: NotRequired[str]
16
+ nextPageToken: NotRequired[str]
17
+
18
+
19
+ class Basic(TypedDict):
20
+ """
21
+ State of basic functionality of a claimed domain such as SSO login suggestions.
22
+ """
23
+
24
+ status: Literal["verified", "unverified"]
25
+
26
+
27
+ class Email(TypedDict):
28
+ """
29
+ State of being able to send messages from an email address of the domain.
30
+ """
31
+
32
+ status: Literal["verified", "unverified"]
33
+
34
+
35
+ class Verifications(TypedDict):
36
+ """
37
+ Describes the current state of the claimed domain's verifications.
38
+ """
39
+
40
+ basic: Basic
41
+ email: Email
42
+
43
+
44
+ class Item(TypedDict):
45
+ account: str
46
+ domain: str
47
+ eligibleForLoginMethods: bool
48
+ verifications: Verifications
49
+
50
+
51
+ class Links(TypedDict):
52
+ self: str
53
+ next: NotRequired[str]
54
+
55
+
56
+ class PrivateListDomainsResponse(TypedDict):
57
+ items: List[Item]
58
+ links: Links
59
+
60
+
61
+ class ClaimedDomainsServiceClient(BaseClient):
62
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
63
+ kwargs = {"target": "lambda://claimed-domains-service:deployed", **(cfg or {})}
64
+ super().__init__(**kwargs)
65
+
66
+ async def private_list_domains(self, params: PrivateListDomainsParams):
67
+ res = await self.client.request(
68
+ path="/v1/private/claimed-domains", method="GET", params=cast(dict, params)
69
+ )
70
+ return cast(AlphaResponse[PrivateListDomainsResponse], res)
@@ -0,0 +1,184 @@
1
+ # This file was generated automatically. Do not edit it directly.
2
+ # generated by datamodel-codegen:
3
+ # filename: cohorts-service.json
4
+ from typing import Any, List, Literal, NotRequired, TypedDict, Unpack, cast
5
+ from urllib.parse import quote
6
+
7
+ from fountain_life_service_clients._base_client import (
8
+ AlphaConfig,
9
+ AlphaResponse,
10
+ BaseClient,
11
+ )
12
+
13
+
14
+ class GetCohortsParams(TypedDict):
15
+ projectId: str
16
+ name: NotRequired[str]
17
+ pageSize: NotRequired[float]
18
+ nextPageToken: NotRequired[str]
19
+
20
+
21
+ class Query(TypedDict):
22
+ """
23
+ A query used to define a cohort
24
+ """
25
+
26
+ project: str
27
+ queryType: str
28
+ query: NotRequired[Any]
29
+
30
+
31
+ class Item(TypedDict):
32
+ """
33
+ Response body for a cohort
34
+ """
35
+
36
+ id: str
37
+ name: str
38
+ description: NotRequired[str]
39
+ ownerProject: str
40
+ resultCount: NotRequired[float]
41
+ creatorUser: NotRequired[str]
42
+ creationTime: NotRequired[str]
43
+ queries: List[Query]
44
+ subjectIds: List[str]
45
+
46
+
47
+ class Links(TypedDict):
48
+ self: str
49
+ next: NotRequired[str]
50
+
51
+
52
+ class GetCohortsResponse(TypedDict):
53
+ """
54
+ Response body for listing cohorts
55
+ """
56
+
57
+ items: List[Item]
58
+ links: Links
59
+
60
+
61
+ class CreateCohortRequest(TypedDict):
62
+ """
63
+ Request body for creating or updating a cohort
64
+ """
65
+
66
+ name: str
67
+ description: NotRequired[str]
68
+ ownerProject: str
69
+ queries: List[Query]
70
+
71
+
72
+ class CreateCohortResponse(TypedDict):
73
+ """
74
+ Response body for a cohort
75
+ """
76
+
77
+ id: str
78
+ name: str
79
+ description: NotRequired[str]
80
+ ownerProject: str
81
+ resultCount: NotRequired[float]
82
+ creatorUser: NotRequired[str]
83
+ creationTime: NotRequired[str]
84
+ queries: List[Query]
85
+ subjectIds: List[str]
86
+
87
+
88
+ class GetCohortResponse(TypedDict):
89
+ """
90
+ Response body for a cohort
91
+ """
92
+
93
+ id: str
94
+ name: str
95
+ description: NotRequired[str]
96
+ ownerProject: str
97
+ resultCount: NotRequired[float]
98
+ creatorUser: NotRequired[str]
99
+ creationTime: NotRequired[str]
100
+ queries: List[Query]
101
+ subjectIds: List[str]
102
+
103
+
104
+ class UpdateCohortRequest(TypedDict):
105
+ """
106
+ Request body for creating or updating a cohort
107
+ """
108
+
109
+ name: str
110
+ description: NotRequired[str]
111
+ ownerProject: str
112
+ queries: List[Query]
113
+
114
+
115
+ class UpdateCohortResponse(TypedDict):
116
+ """
117
+ Response body for a cohort
118
+ """
119
+
120
+ id: str
121
+ name: str
122
+ description: NotRequired[str]
123
+ ownerProject: str
124
+ resultCount: NotRequired[float]
125
+ creatorUser: NotRequired[str]
126
+ creationTime: NotRequired[str]
127
+ queries: List[Query]
128
+ subjectIds: List[str]
129
+
130
+
131
+ class UpdateCohortPatientsRequest(TypedDict):
132
+ subjectIds: List[str]
133
+ action: Literal["ADD", "REMOVE"]
134
+
135
+
136
+ class UpdateCohortPatientsResponse(TypedDict):
137
+ pass
138
+
139
+
140
+ class CohortsServiceClient(BaseClient):
141
+ def __init__(self, **cfg: Unpack[AlphaConfig]):
142
+ kwargs = {"target": "lambda://cohorts-service:deployed", **(cfg or {})}
143
+ super().__init__(**kwargs)
144
+
145
+ async def get_cohorts(self, params: GetCohortsParams):
146
+ """Returns a list of cohorts that the user has access to."""
147
+ res = await self.client.request(
148
+ path="/v1/cohorts", method="GET", params=cast(dict, params)
149
+ )
150
+ return cast(AlphaResponse[GetCohortsResponse], res)
151
+
152
+ async def create_cohort(self, body: CreateCohortRequest):
153
+ """Create a cohort, representing a subset of a project based on one or more queries"""
154
+ res = await self.client.request(
155
+ path="/v1/cohorts", method="POST", body=cast(dict, body)
156
+ )
157
+ return cast(AlphaResponse[CreateCohortResponse], res)
158
+
159
+ async def get_cohort(self, cohort_id: str):
160
+ """Returns a cohort."""
161
+ res = await self.client.request(
162
+ path=f"/v1/cohorts/{quote(cohort_id)}", method="GET"
163
+ )
164
+ return cast(AlphaResponse[GetCohortResponse], res)
165
+
166
+ async def update_cohort(self, cohort_id: str, body: UpdateCohortRequest):
167
+ """Returns the updated cohort."""
168
+ res = await self.client.request(
169
+ path=f"/v1/cohorts/{quote(cohort_id)}",
170
+ method="PATCH",
171
+ body=cast(dict, body),
172
+ )
173
+ return cast(AlphaResponse[UpdateCohortResponse], res)
174
+
175
+ async def update_cohort_patients(
176
+ self, project_id: str, cohort_id: str, body: UpdateCohortPatientsRequest
177
+ ):
178
+ """Adds or removes a patient from a cohort. Only works in the Fountain Life account + project."""
179
+ res = await self.client.request(
180
+ path=f"/v1/private/cohorts/projects/{quote(project_id)}/cohorts/{quote(cohort_id)}/patients",
181
+ method="PATCH",
182
+ body=cast(dict, body),
183
+ )
184
+ return cast(AlphaResponse[UpdateCohortPatientsResponse], res)