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.
- fountain_life_service_clients/__init__.py +0 -0
- fountain_life_service_clients/_base_client.py +30 -0
- fountain_life_service_clients/account_service.py +116 -0
- fountain_life_service_clients/account_service_policy_attributes.py +46 -0
- fountain_life_service_clients/agents_api_service.py +197 -0
- fountain_life_service_clients/claimed_domains_service.py +70 -0
- fountain_life_service_clients/cohorts_service.py +184 -0
- fountain_life_service_clients/ehr_ingestion_wearables_api.py +169 -0
- fountain_life_service_clients/ehr_service.py +334 -0
- fountain_life_service_clients/email_service_email.py +81 -0
- fountain_life_service_clients/email_service_sms.py +33 -0
- fountain_life_service_clients/fhir_post_processor_service.py +55 -0
- fountain_life_service_clients/fhir_search_service.py +262 -0
- fountain_life_service_clients/file_service.py +124 -0
- fountain_life_service_clients/invitation_service.py +94 -0
- fountain_life_service_clients/medical_results_service_results.py +228 -0
- fountain_life_service_clients/member_notification_service.py +69 -0
- fountain_life_service_clients/member_operations_service_members.py +40 -0
- fountain_life_service_clients/member_scheduling_service_scheduling_prompts.py +62 -0
- fountain_life_service_clients/oauth_apps_service.py +253 -0
- fountain_life_service_clients/patient_service.py +157 -0
- fountain_life_service_clients/rules_service.py +249 -0
- fountain_life_service_clients/scheduler_service.py +146 -0
- fountain_life_service_clients/survey_service.py +404 -0
- fountain_life_service_clients/user_service.py +152 -0
- fountain_life_service_clients-3.28.2.dist-info/METADATA +53 -0
- fountain_life_service_clients-3.28.2.dist-info/RECORD +28 -0
- fountain_life_service_clients-3.28.2.dist-info/WHEEL +4 -0
@@ -0,0 +1,262 @@
|
|
1
|
+
# This file was generated automatically. Do not edit it directly.
|
2
|
+
# generated by datamodel-codegen:
|
3
|
+
# filename: fhir-search-service.json
|
4
|
+
from typing import Any, Dict, List, Literal, NotRequired, TypedDict, Union, 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 Expr(TypedDict):
|
15
|
+
type: NotRequired[str]
|
16
|
+
column: str
|
17
|
+
table: NotRequired[str]
|
18
|
+
|
19
|
+
|
20
|
+
class Columns(TypedDict):
|
21
|
+
expr: Expr
|
22
|
+
|
23
|
+
|
24
|
+
class columns(TypedDict):
|
25
|
+
type: NotRequired[str]
|
26
|
+
aggregations: Dict[str, Any]
|
27
|
+
|
28
|
+
|
29
|
+
class FromItem(TypedDict):
|
30
|
+
table: str
|
31
|
+
|
32
|
+
|
33
|
+
class Where(TypedDict):
|
34
|
+
type: NotRequired[str]
|
35
|
+
query: Dict[str, Any]
|
36
|
+
highlight: NotRequired[Dict[str, Any]]
|
37
|
+
|
38
|
+
|
39
|
+
class Limit(TypedDict):
|
40
|
+
"""
|
41
|
+
A Response Offset
|
42
|
+
"""
|
43
|
+
|
44
|
+
type: NotRequired[str]
|
45
|
+
value: float
|
46
|
+
|
47
|
+
|
48
|
+
class limit(TypedDict):
|
49
|
+
"""
|
50
|
+
An Elasticsearch Search-After Clause
|
51
|
+
"""
|
52
|
+
|
53
|
+
type: NotRequired[str]
|
54
|
+
search_after: List
|
55
|
+
|
56
|
+
|
57
|
+
class LimitItem(TypedDict):
|
58
|
+
"""
|
59
|
+
A Response Limit
|
60
|
+
"""
|
61
|
+
|
62
|
+
type: NotRequired[str]
|
63
|
+
value: float
|
64
|
+
|
65
|
+
|
66
|
+
class OrderbyItem(TypedDict):
|
67
|
+
type: Literal["ASC", "DESC"]
|
68
|
+
expr: Expr
|
69
|
+
|
70
|
+
|
71
|
+
SearchProjectRequest = TypedDict(
|
72
|
+
"SearchProjectRequest",
|
73
|
+
{
|
74
|
+
"type": NotRequired[str],
|
75
|
+
"columns": Union[str, List[Union[Columns, columns]]],
|
76
|
+
"from": List[FromItem],
|
77
|
+
"where": NotRequired[Where],
|
78
|
+
"limit": NotRequired[List[Union[Union[Limit, limit], LimitItem]]],
|
79
|
+
"orderby": NotRequired[List[OrderbyItem]],
|
80
|
+
"scroll": NotRequired[str],
|
81
|
+
},
|
82
|
+
)
|
83
|
+
|
84
|
+
|
85
|
+
class Hit(TypedDict):
|
86
|
+
_source: NotRequired[Any]
|
87
|
+
sort: NotRequired[List]
|
88
|
+
|
89
|
+
|
90
|
+
class Hits(TypedDict):
|
91
|
+
hits: List[Hit]
|
92
|
+
|
93
|
+
|
94
|
+
class SearchProjectResponse(TypedDict):
|
95
|
+
hits: Hits
|
96
|
+
_scroll_id: NotRequired[str]
|
97
|
+
took: float
|
98
|
+
timed_out: bool
|
99
|
+
|
100
|
+
|
101
|
+
class Columns2(TypedDict):
|
102
|
+
expr: Expr
|
103
|
+
|
104
|
+
|
105
|
+
class Columns3(TypedDict):
|
106
|
+
type: NotRequired[str]
|
107
|
+
aggregations: Dict[str, Any]
|
108
|
+
|
109
|
+
|
110
|
+
class Limit2(TypedDict):
|
111
|
+
"""
|
112
|
+
A Response Offset
|
113
|
+
"""
|
114
|
+
|
115
|
+
type: NotRequired[str]
|
116
|
+
value: float
|
117
|
+
|
118
|
+
|
119
|
+
class Limit3(TypedDict):
|
120
|
+
"""
|
121
|
+
An Elasticsearch Search-After Clause
|
122
|
+
"""
|
123
|
+
|
124
|
+
type: NotRequired[str]
|
125
|
+
search_after: List
|
126
|
+
|
127
|
+
|
128
|
+
class orderbyItem(TypedDict):
|
129
|
+
type: Literal["ASC", "DESC"]
|
130
|
+
expr: Expr
|
131
|
+
|
132
|
+
|
133
|
+
SearchPatientRequest = TypedDict(
|
134
|
+
"SearchPatientRequest",
|
135
|
+
{
|
136
|
+
"type": NotRequired[str],
|
137
|
+
"columns": Union[str, List[Union[Columns2, Columns3]]],
|
138
|
+
"from": List[FromItem],
|
139
|
+
"where": NotRequired[Where],
|
140
|
+
"limit": NotRequired[List[Union[Union[Limit2, Limit3], LimitItem]]],
|
141
|
+
"orderby": NotRequired[List[orderbyItem]],
|
142
|
+
},
|
143
|
+
)
|
144
|
+
|
145
|
+
|
146
|
+
class hits(TypedDict):
|
147
|
+
hits: List[Hit]
|
148
|
+
|
149
|
+
|
150
|
+
class SearchPatientResponse(TypedDict):
|
151
|
+
hits: hits
|
152
|
+
_scroll_id: NotRequired[str]
|
153
|
+
took: float
|
154
|
+
timed_out: bool
|
155
|
+
|
156
|
+
|
157
|
+
class Columns4(TypedDict):
|
158
|
+
expr: Expr
|
159
|
+
|
160
|
+
|
161
|
+
class Columns5(TypedDict):
|
162
|
+
type: NotRequired[str]
|
163
|
+
aggregations: Dict[str, Any]
|
164
|
+
|
165
|
+
|
166
|
+
class Limit4(TypedDict):
|
167
|
+
"""
|
168
|
+
A Response Offset
|
169
|
+
"""
|
170
|
+
|
171
|
+
type: NotRequired[str]
|
172
|
+
value: float
|
173
|
+
|
174
|
+
|
175
|
+
class Limit5(TypedDict):
|
176
|
+
"""
|
177
|
+
An Elasticsearch Search-After Clause
|
178
|
+
"""
|
179
|
+
|
180
|
+
type: NotRequired[str]
|
181
|
+
search_after: List
|
182
|
+
|
183
|
+
|
184
|
+
class OrderbyItem2(TypedDict):
|
185
|
+
type: Literal["ASC", "DESC"]
|
186
|
+
expr: Expr
|
187
|
+
|
188
|
+
|
189
|
+
SearchCohortRequest = TypedDict(
|
190
|
+
"SearchCohortRequest",
|
191
|
+
{
|
192
|
+
"type": NotRequired[str],
|
193
|
+
"columns": Union[str, List[Union[Columns4, Columns5]]],
|
194
|
+
"from": List[FromItem],
|
195
|
+
"where": NotRequired[Where],
|
196
|
+
"limit": NotRequired[List[Union[Union[Limit4, Limit5], LimitItem]]],
|
197
|
+
"orderby": NotRequired[List[OrderbyItem2]],
|
198
|
+
},
|
199
|
+
)
|
200
|
+
|
201
|
+
|
202
|
+
class Hits2(TypedDict):
|
203
|
+
hits: List[Hit]
|
204
|
+
|
205
|
+
|
206
|
+
class SearchCohortResponse(TypedDict):
|
207
|
+
hits: Hits2
|
208
|
+
_scroll_id: NotRequired[str]
|
209
|
+
took: float
|
210
|
+
timed_out: bool
|
211
|
+
|
212
|
+
|
213
|
+
class SearchDistinctRequest(TypedDict):
|
214
|
+
field: str
|
215
|
+
resource: str
|
216
|
+
where: NotRequired[Dict[str, Any]]
|
217
|
+
size: NotRequired[float]
|
218
|
+
after: NotRequired[Dict[str, Any]]
|
219
|
+
|
220
|
+
|
221
|
+
class FhirSearchServiceClient(BaseClient):
|
222
|
+
def __init__(self, **cfg: Unpack[AlphaConfig]):
|
223
|
+
kwargs = {"target": "lambda://fhir-search-service:deployed", **(cfg or {})}
|
224
|
+
super().__init__(**kwargs)
|
225
|
+
|
226
|
+
async def search_project(self, project: str, body: SearchProjectRequest):
|
227
|
+
"""Search a project's FHIR resources using an expressive DSL"""
|
228
|
+
res = await self.client.request(
|
229
|
+
path=f"/v1/fhir-search/projects/{quote(project)}",
|
230
|
+
method="POST",
|
231
|
+
body=cast(dict, body),
|
232
|
+
)
|
233
|
+
return cast(AlphaResponse[SearchProjectResponse], res)
|
234
|
+
|
235
|
+
async def search_patient(
|
236
|
+
self, project: str, patient: str, body: SearchPatientRequest
|
237
|
+
):
|
238
|
+
"""Search a patient's FHIR resources using an expressive DSL"""
|
239
|
+
res = await self.client.request(
|
240
|
+
path=f"/v1/fhir-search/projects/{quote(project)}/patients/{quote(patient)}",
|
241
|
+
method="POST",
|
242
|
+
body=cast(dict, body),
|
243
|
+
)
|
244
|
+
return cast(AlphaResponse[SearchPatientResponse], res)
|
245
|
+
|
246
|
+
async def search_cohort(self, project: str, cohort: str, body: SearchCohortRequest):
|
247
|
+
"""Search a cohort's FHIR resources using an expressive DSL"""
|
248
|
+
res = await self.client.request(
|
249
|
+
path=f"/v1/fhir-search/projects/{quote(project)}/cohorts/{quote(cohort)}",
|
250
|
+
method="POST",
|
251
|
+
body=cast(dict, body),
|
252
|
+
)
|
253
|
+
return cast(AlphaResponse[SearchCohortResponse], res)
|
254
|
+
|
255
|
+
async def search_distinct(self, project: str, body: SearchDistinctRequest):
|
256
|
+
"""Fetch a distinct set of values for a given field belonging to a project's FHIR resources. Endpoint will programmatically optimize the search query"""
|
257
|
+
res = await self.client.request(
|
258
|
+
path=f"/v1/fhir-search/projects/{quote(project)}/distinct",
|
259
|
+
method="POST",
|
260
|
+
body=cast(dict, body),
|
261
|
+
)
|
262
|
+
return cast(AlphaResponse[Any], res)
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# This file was generated automatically. Do not edit it directly.
|
2
|
+
# generated by datamodel-codegen:
|
3
|
+
# filename: file-service.json
|
4
|
+
from typing import 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 ListFilesParams(TypedDict):
|
15
|
+
name: NotRequired[str]
|
16
|
+
orderBy: NotRequired[Literal["name", "size"]]
|
17
|
+
pageSize: NotRequired[float]
|
18
|
+
nextPageToken: NotRequired[str]
|
19
|
+
datasetId: NotRequired[str]
|
20
|
+
|
21
|
+
|
22
|
+
class Item(TypedDict):
|
23
|
+
id: str
|
24
|
+
name: str
|
25
|
+
datasetId: str
|
26
|
+
contentType: str
|
27
|
+
|
28
|
+
|
29
|
+
class Links(TypedDict):
|
30
|
+
self: str
|
31
|
+
next: NotRequired[str]
|
32
|
+
|
33
|
+
|
34
|
+
class ListFilesResponse(TypedDict):
|
35
|
+
items: List[Item]
|
36
|
+
links: Links
|
37
|
+
|
38
|
+
|
39
|
+
class CreateFileRequest(TypedDict):
|
40
|
+
id: str
|
41
|
+
name: str
|
42
|
+
datasetId: str
|
43
|
+
contentType: str
|
44
|
+
|
45
|
+
|
46
|
+
class CreateFileResponse(TypedDict):
|
47
|
+
id: str
|
48
|
+
name: str
|
49
|
+
datasetId: str
|
50
|
+
contentType: str
|
51
|
+
userId: str
|
52
|
+
uploadUrl: str
|
53
|
+
|
54
|
+
|
55
|
+
class CreateFilePrivateRequest(TypedDict):
|
56
|
+
id: str
|
57
|
+
name: str
|
58
|
+
datasetId: str
|
59
|
+
contentType: str
|
60
|
+
requiresMalwareScanning: NotRequired[bool]
|
61
|
+
|
62
|
+
|
63
|
+
class CreateFilePrivateResponse(TypedDict):
|
64
|
+
id: str
|
65
|
+
name: str
|
66
|
+
datasetId: str
|
67
|
+
contentType: str
|
68
|
+
userId: str
|
69
|
+
uploadUrl: str
|
70
|
+
|
71
|
+
|
72
|
+
class RetrieveFileParams(TypedDict):
|
73
|
+
include: NotRequired[Literal["downloadUrl"]]
|
74
|
+
includeContentDisposition: NotRequired[bool]
|
75
|
+
|
76
|
+
|
77
|
+
class RetrieveFileResponse(TypedDict):
|
78
|
+
id: str
|
79
|
+
name: str
|
80
|
+
datasetId: str
|
81
|
+
size: str
|
82
|
+
contentType: str
|
83
|
+
lastModified: str
|
84
|
+
userId: str
|
85
|
+
lrn: str
|
86
|
+
downloadUrl: NotRequired[str]
|
87
|
+
|
88
|
+
|
89
|
+
class FileServiceClient(BaseClient):
|
90
|
+
def __init__(self, **cfg: Unpack[AlphaConfig]):
|
91
|
+
kwargs = {"target": "lambda://file-service:deployed", **(cfg or {})}
|
92
|
+
super().__init__(**kwargs)
|
93
|
+
|
94
|
+
async def list_files(self, params: ListFilesParams):
|
95
|
+
"""Lists the files for your LifeOmic account. Refine your results to a specific project with the *datasetId* query parameter. For more information, see [List Files](https://devcenter.docs.lifeomic.com/development/files#list-files)."""
|
96
|
+
res = await self.client.request(
|
97
|
+
path="/v1/files", method="GET", params=cast(dict, params)
|
98
|
+
)
|
99
|
+
return cast(AlphaResponse[ListFilesResponse], res)
|
100
|
+
|
101
|
+
async def create_file(self, body: CreateFileRequest):
|
102
|
+
"""Creates and uploads a file. Uploading files is a two call operation. The first call is a POST call for a response that contains the presigned URL. The POST call contains JSON data for the file in the body. The second call is a PUT call to upload the file to the presigned URL. For more information, see [Upload Files](https://devcenter.docs.lifeomic.com/development/files#upload-files)."""
|
103
|
+
res = await self.client.request(
|
104
|
+
path="/v1/files", method="POST", body=cast(dict, body)
|
105
|
+
)
|
106
|
+
return cast(AlphaResponse[CreateFileResponse], res)
|
107
|
+
|
108
|
+
async def create_file_private(self, body: CreateFilePrivateRequest):
|
109
|
+
"""Same as POST /files, but for private use, which has some extra capabilities."""
|
110
|
+
res = await self.client.request(
|
111
|
+
path="/v1/private/files", method="POST", body=cast(dict, body)
|
112
|
+
)
|
113
|
+
return cast(AlphaResponse[CreateFilePrivateResponse], res)
|
114
|
+
|
115
|
+
async def retrieve_file(self, id: str, params: RetrieveFileParams):
|
116
|
+
"""Downloads a file. Add the file id from the general GET files response and the include parameter with the downloadUrl value. The response contains the download url. For more information, see [Download Files](https://devcenter.docs.lifeomic.com/development/files#download-files)."""
|
117
|
+
res = await self.client.request(
|
118
|
+
path=f"/v1/files/{quote(id)}", method="GET", params=cast(dict, params)
|
119
|
+
)
|
120
|
+
return cast(AlphaResponse[RetrieveFileResponse], res)
|
121
|
+
|
122
|
+
async def delete_file(self, id: str):
|
123
|
+
"""Deletes the file specified with the file id."""
|
124
|
+
await self.client.request(path=f"/v1/files/{quote(id)}", method="DELETE")
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# This file was generated automatically. Do not edit it directly.
|
2
|
+
# generated by datamodel-codegen:
|
3
|
+
# filename: invitation-service.json
|
4
|
+
from typing import 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 RetrieveInvitationsParams(TypedDict):
|
15
|
+
user: NotRequired[str]
|
16
|
+
account: NotRequired[str]
|
17
|
+
|
18
|
+
|
19
|
+
class Item(TypedDict):
|
20
|
+
id: str
|
21
|
+
account: str
|
22
|
+
accountName: str
|
23
|
+
group: str
|
24
|
+
groupName: str
|
25
|
+
invitorUser: str
|
26
|
+
email: str
|
27
|
+
status: Literal["AWAITING-USER-ACTION", "ACCEPTED", "REJECTED", "REVOKED"]
|
28
|
+
inviteTimestamp: str
|
29
|
+
expirationTimestamp: str
|
30
|
+
|
31
|
+
|
32
|
+
class Links(TypedDict):
|
33
|
+
self: str
|
34
|
+
next: NotRequired[str]
|
35
|
+
|
36
|
+
|
37
|
+
class RetrieveInvitationsResponse(TypedDict):
|
38
|
+
items: List[Item]
|
39
|
+
links: Links
|
40
|
+
|
41
|
+
|
42
|
+
class InviteUserRequest(TypedDict):
|
43
|
+
group: str
|
44
|
+
email: str
|
45
|
+
project: NotRequired[str]
|
46
|
+
patient: NotRequired[str]
|
47
|
+
|
48
|
+
|
49
|
+
class InviteUserResponse(TypedDict):
|
50
|
+
id: str
|
51
|
+
account: str
|
52
|
+
accountName: str
|
53
|
+
group: str
|
54
|
+
groupName: str
|
55
|
+
invitorUser: str
|
56
|
+
email: str
|
57
|
+
status: Literal["AWAITING-USER-ACTION", "ACCEPTED", "REJECTED", "REVOKED"]
|
58
|
+
inviteTimestamp: str
|
59
|
+
expirationTimestamp: str
|
60
|
+
|
61
|
+
|
62
|
+
class UpdateInvitationRequest(TypedDict):
|
63
|
+
status: Literal["ACCEPTED", "REJECTED", "REVOKED"]
|
64
|
+
|
65
|
+
|
66
|
+
class UpdateInvitationResponse(TypedDict):
|
67
|
+
pass
|
68
|
+
|
69
|
+
|
70
|
+
class InvitationServiceClient(BaseClient):
|
71
|
+
def __init__(self, **cfg: Unpack[AlphaConfig]):
|
72
|
+
kwargs = {"target": "lambda://invitation-service:deployed", **(cfg or {})}
|
73
|
+
super().__init__(**kwargs)
|
74
|
+
|
75
|
+
async def retrieve_invitations(self, params: RetrieveInvitationsParams):
|
76
|
+
"""Retrieves the invitations to or from the session user."""
|
77
|
+
res = await self.client.request(
|
78
|
+
path="/v1/invitations", method="GET", params=cast(dict, params)
|
79
|
+
)
|
80
|
+
return cast(AlphaResponse[RetrieveInvitationsResponse], res)
|
81
|
+
|
82
|
+
async def invite_user(self, body: InviteUserRequest):
|
83
|
+
"""Sends an email to a user, inviting them to join a group"""
|
84
|
+
res = await self.client.request(
|
85
|
+
path="/v1/invitations", method="POST", body=cast(dict, body)
|
86
|
+
)
|
87
|
+
return cast(AlphaResponse[InviteUserResponse], res)
|
88
|
+
|
89
|
+
async def update_invitation(self, id: str, body: UpdateInvitationRequest):
|
90
|
+
"""Join, reject, or revoke an invitation."""
|
91
|
+
res = await self.client.request(
|
92
|
+
path=f"/v1/invitations/{quote(id)}", method="PATCH", body=cast(dict, body)
|
93
|
+
)
|
94
|
+
return cast(AlphaResponse[UpdateInvitationResponse], res)
|
@@ -0,0 +1,228 @@
|
|
1
|
+
# This file was generated automatically. Do not edit it directly.
|
2
|
+
# generated by datamodel-codegen:
|
3
|
+
# filename: medical-results-service-results.json
|
4
|
+
from typing import (
|
5
|
+
Any,
|
6
|
+
List,
|
7
|
+
Literal,
|
8
|
+
NotRequired,
|
9
|
+
Optional,
|
10
|
+
TypedDict,
|
11
|
+
Union,
|
12
|
+
Unpack,
|
13
|
+
cast,
|
14
|
+
)
|
15
|
+
from urllib.parse import quote
|
16
|
+
|
17
|
+
from fountain_life_service_clients._base_client import (
|
18
|
+
AlphaConfig,
|
19
|
+
AlphaResponse,
|
20
|
+
BaseClient,
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
class PageSize(TypedDict):
|
25
|
+
pass
|
26
|
+
|
27
|
+
|
28
|
+
class GetResultsV3Params(TypedDict):
|
29
|
+
pageSize: NotRequired[PageSize]
|
30
|
+
nextPageToken: NotRequired[str]
|
31
|
+
project: str
|
32
|
+
resultCount: float
|
33
|
+
cohort: NotRequired[str]
|
34
|
+
includeClinicOnly: NotRequired[bool]
|
35
|
+
source: NotRequired[Literal["mappedLabs", "unmappedLabs", "memberUpload"]]
|
36
|
+
|
37
|
+
|
38
|
+
class Coding(TypedDict):
|
39
|
+
code: str
|
40
|
+
system: str
|
41
|
+
display: str
|
42
|
+
|
43
|
+
|
44
|
+
class System(TypedDict):
|
45
|
+
code: str
|
46
|
+
system: str
|
47
|
+
display: NotRequired[str]
|
48
|
+
|
49
|
+
|
50
|
+
class SubSystem(TypedDict):
|
51
|
+
code: str
|
52
|
+
system: str
|
53
|
+
display: NotRequired[str]
|
54
|
+
|
55
|
+
|
56
|
+
class Results(TypedDict):
|
57
|
+
type: NotRequired[str]
|
58
|
+
status: NotRequired[str]
|
59
|
+
resource: NotRequired[Any]
|
60
|
+
|
61
|
+
|
62
|
+
class InRange(TypedDict):
|
63
|
+
lower: NotRequired[float]
|
64
|
+
upper: NotRequired[float]
|
65
|
+
label: str
|
66
|
+
status: NotRequired[str]
|
67
|
+
|
68
|
+
|
69
|
+
class Optimal(TypedDict):
|
70
|
+
"""
|
71
|
+
Currently this is always undefined. It may be used in the future.
|
72
|
+
"""
|
73
|
+
|
74
|
+
lower: NotRequired[float]
|
75
|
+
upper: NotRequired[float]
|
76
|
+
label: str
|
77
|
+
status: NotRequired[str]
|
78
|
+
|
79
|
+
|
80
|
+
"""
|
81
|
+
Populated from reference ranges on the observation.
|
82
|
+
"""
|
83
|
+
Ranges = TypedDict(
|
84
|
+
"Ranges",
|
85
|
+
{
|
86
|
+
"in-range": InRange,
|
87
|
+
"optimal": NotRequired[Optimal],
|
88
|
+
},
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
class results(TypedDict):
|
93
|
+
type: NotRequired[str]
|
94
|
+
status: Literal["in-range", "attention", "optimal"]
|
95
|
+
resource: NotRequired[Any]
|
96
|
+
ranges: Ranges
|
97
|
+
|
98
|
+
|
99
|
+
class Results2(TypedDict):
|
100
|
+
type: NotRequired[str]
|
101
|
+
status: NotRequired[str]
|
102
|
+
resource: NotRequired[Any]
|
103
|
+
|
104
|
+
|
105
|
+
class Item(TypedDict):
|
106
|
+
coding: Coding
|
107
|
+
systems: List[System]
|
108
|
+
subSystems: List[SubSystem]
|
109
|
+
results: List[Union[Union[Results, results], Results2]]
|
110
|
+
|
111
|
+
|
112
|
+
class Links(TypedDict):
|
113
|
+
self: str
|
114
|
+
next: NotRequired[Optional[Union[Any, str]]]
|
115
|
+
|
116
|
+
|
117
|
+
class GetResultsV3Response(TypedDict):
|
118
|
+
items: List[Item]
|
119
|
+
links: Links
|
120
|
+
|
121
|
+
|
122
|
+
class GetHistoryParams(TypedDict):
|
123
|
+
pageSize: NotRequired[PageSize]
|
124
|
+
nextPageToken: NotRequired[str]
|
125
|
+
project: str
|
126
|
+
code: str
|
127
|
+
system: str
|
128
|
+
cohort: NotRequired[str]
|
129
|
+
includeClinicOnly: NotRequired[bool]
|
130
|
+
source: NotRequired[Literal["mappedLabs", "memberUpload", "unmappedLabs"]]
|
131
|
+
|
132
|
+
|
133
|
+
class Attention(TypedDict):
|
134
|
+
lower: NotRequired[float]
|
135
|
+
upper: NotRequired[float]
|
136
|
+
label: str
|
137
|
+
status: NotRequired[str]
|
138
|
+
|
139
|
+
|
140
|
+
class optimal(TypedDict):
|
141
|
+
lower: NotRequired[float]
|
142
|
+
upper: NotRequired[float]
|
143
|
+
label: str
|
144
|
+
status: NotRequired[str]
|
145
|
+
|
146
|
+
|
147
|
+
ranges = TypedDict(
|
148
|
+
"ranges",
|
149
|
+
{
|
150
|
+
"in-range": InRange,
|
151
|
+
"attention": NotRequired[Attention],
|
152
|
+
"optimal": NotRequired[optimal],
|
153
|
+
},
|
154
|
+
)
|
155
|
+
|
156
|
+
|
157
|
+
class Result(TypedDict):
|
158
|
+
status: Literal["in-range", "attention", "optimal"]
|
159
|
+
text: str
|
160
|
+
interpretationText: str
|
161
|
+
|
162
|
+
|
163
|
+
class Items(TypedDict):
|
164
|
+
type: NotRequired[str]
|
165
|
+
ranges: ranges
|
166
|
+
result: Result
|
167
|
+
coding: Coding
|
168
|
+
resource: NotRequired[Any]
|
169
|
+
systems: List[System]
|
170
|
+
subSystems: List[SubSystem]
|
171
|
+
aboutText: str
|
172
|
+
|
173
|
+
|
174
|
+
class result(TypedDict):
|
175
|
+
status: NotRequired[str]
|
176
|
+
text: str
|
177
|
+
interpretationText: str
|
178
|
+
|
179
|
+
|
180
|
+
class items(TypedDict):
|
181
|
+
type: NotRequired[str]
|
182
|
+
result: result
|
183
|
+
coding: Coding
|
184
|
+
resource: NotRequired[Any]
|
185
|
+
systems: List[System]
|
186
|
+
subSystems: List[SubSystem]
|
187
|
+
aboutText: str
|
188
|
+
|
189
|
+
|
190
|
+
class Result2(TypedDict):
|
191
|
+
status: NotRequired[str]
|
192
|
+
|
193
|
+
|
194
|
+
class Items2(TypedDict):
|
195
|
+
type: NotRequired[str]
|
196
|
+
result: Result2
|
197
|
+
coding: Coding
|
198
|
+
resource: NotRequired[Any]
|
199
|
+
systems: List[System]
|
200
|
+
subSystems: List[SubSystem]
|
201
|
+
aboutText: str
|
202
|
+
|
203
|
+
|
204
|
+
class GetHistoryResponse(TypedDict):
|
205
|
+
items: List[Union[Union[Items, items], Items2]]
|
206
|
+
links: Links
|
207
|
+
|
208
|
+
|
209
|
+
class MedicalResultsServiceResultsClient(BaseClient):
|
210
|
+
def __init__(self, **cfg: Unpack[AlphaConfig]):
|
211
|
+
kwargs = {"target": "lambda://medical-results-service:deployed", **(cfg or {})}
|
212
|
+
super().__init__(**kwargs)
|
213
|
+
|
214
|
+
async def get_results_v3(self, patient_id: str, params: GetResultsV3Params):
|
215
|
+
res = await self.client.request(
|
216
|
+
path=f"/v1/medical-results/v3/patient/{quote(patient_id)}/results",
|
217
|
+
method="GET",
|
218
|
+
params=cast(dict, params),
|
219
|
+
)
|
220
|
+
return cast(AlphaResponse[GetResultsV3Response], res)
|
221
|
+
|
222
|
+
async def get_history(self, patient_id: str, params: GetHistoryParams):
|
223
|
+
res = await self.client.request(
|
224
|
+
path=f"/v1/medical-results/patient/{quote(patient_id)}/history",
|
225
|
+
method="GET",
|
226
|
+
params=cast(dict, params),
|
227
|
+
)
|
228
|
+
return cast(AlphaResponse[GetHistoryResponse], res)
|