phenoml 0.0.2__py3-none-any.whl → 0.0.17__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 (149) hide show
  1. phenoml/agent/__init__.py +6 -8
  2. phenoml/agent/client.py +85 -67
  3. phenoml/agent/raw_client.py +61 -77
  4. phenoml/agent/types/__init__.py +6 -8
  5. phenoml/agent/types/agent_create_request.py +53 -0
  6. phenoml/agent/types/agent_create_request_provider.py +5 -0
  7. phenoml/agent/types/agent_template.py +3 -6
  8. phenoml/agent/types/agent_template_provider.py +5 -0
  9. phenoml/agent/types/json_patch_operation.py +5 -1
  10. phenoml/client.py +12 -0
  11. phenoml/construe/__init__.py +2 -16
  12. phenoml/construe/client.py +0 -90
  13. phenoml/construe/raw_client.py +0 -180
  14. phenoml/construe/types/__init__.py +2 -20
  15. phenoml/construe/types/extract_request_config.py +33 -4
  16. phenoml/construe/types/extract_request_config_chunking_method.py +3 -1
  17. phenoml/construe/types/extract_request_config_validation_method.py +5 -0
  18. phenoml/construe/types/extract_request_system.py +2 -0
  19. phenoml/core/client_wrapper.py +2 -2
  20. phenoml/fhir/__init__.py +36 -0
  21. phenoml/fhir/client.py +1072 -0
  22. phenoml/fhir/errors/__init__.py +10 -0
  23. phenoml/fhir/errors/bad_request_error.py +10 -0
  24. phenoml/fhir/errors/internal_server_error.py +10 -0
  25. phenoml/fhir/errors/not_found_error.py +10 -0
  26. phenoml/fhir/errors/unauthorized_error.py +10 -0
  27. phenoml/fhir/raw_client.py +1469 -0
  28. phenoml/fhir/types/__init__.py +29 -0
  29. phenoml/{agent/types/chat_fhir_client_config.py → fhir/types/error_response.py} +11 -6
  30. phenoml/fhir/types/fhir_bundle.py +43 -0
  31. phenoml/fhir/types/fhir_bundle_entry_item.py +34 -0
  32. phenoml/fhir/types/fhir_bundle_entry_item_request.py +25 -0
  33. phenoml/fhir/types/fhir_bundle_entry_item_request_method.py +5 -0
  34. phenoml/{construe/types/bad_request_error_body.py → fhir/types/fhir_bundle_entry_item_response.py} +4 -7
  35. phenoml/fhir/types/fhir_patch_request_body_item.py +40 -0
  36. phenoml/fhir/types/fhir_patch_request_body_item_op.py +7 -0
  37. phenoml/fhir/types/fhir_resource.py +40 -0
  38. phenoml/fhir/types/fhir_resource_meta.py +28 -0
  39. phenoml/fhir/types/fhir_search_response.py +8 -0
  40. phenoml/fhir_provider/__init__.py +45 -0
  41. phenoml/fhir_provider/client.py +748 -0
  42. phenoml/fhir_provider/errors/__init__.py +11 -0
  43. phenoml/fhir_provider/errors/bad_request_error.py +10 -0
  44. phenoml/fhir_provider/errors/forbidden_error.py +10 -0
  45. phenoml/fhir_provider/errors/internal_server_error.py +10 -0
  46. phenoml/fhir_provider/errors/not_found_error.py +10 -0
  47. phenoml/fhir_provider/errors/unauthorized_error.py +10 -0
  48. phenoml/fhir_provider/raw_client.py +1462 -0
  49. phenoml/fhir_provider/types/__init__.py +37 -0
  50. phenoml/fhir_provider/types/auth_method.py +7 -0
  51. phenoml/fhir_provider/types/fhir_provider_auth_config.py +53 -0
  52. phenoml/fhir_provider/types/fhir_provider_delete_response.py +20 -0
  53. phenoml/fhir_provider/types/fhir_provider_list_response.py +22 -0
  54. phenoml/fhir_provider/types/fhir_provider_remove_auth_config_response.py +22 -0
  55. phenoml/fhir_provider/types/fhir_provider_response.py +22 -0
  56. phenoml/fhir_provider/types/fhir_provider_set_active_auth_config_response.py +22 -0
  57. phenoml/fhir_provider/types/fhir_provider_template.py +66 -0
  58. phenoml/fhir_provider/types/fhir_query_response.py +27 -0
  59. phenoml/fhir_provider/types/fhir_query_response_data.py +5 -0
  60. phenoml/fhir_provider/types/json_web_key.py +51 -0
  61. phenoml/fhir_provider/types/provider.py +8 -0
  62. phenoml/fhir_provider/types/role.py +27 -0
  63. phenoml/fhir_provider/types/service_account_key.py +35 -0
  64. phenoml/fhir_provider/types/smart_configuration.py +46 -0
  65. phenoml/lang2fhir/__init__.py +10 -0
  66. phenoml/lang2fhir/client.py +111 -6
  67. phenoml/lang2fhir/raw_client.py +189 -0
  68. phenoml/lang2fhir/types/__init__.py +10 -0
  69. phenoml/lang2fhir/types/create_multi_response.py +39 -0
  70. phenoml/lang2fhir/types/create_multi_response_bundle.py +28 -0
  71. phenoml/lang2fhir/types/create_multi_response_bundle_entry_item.py +24 -0
  72. phenoml/lang2fhir/types/create_multi_response_bundle_entry_item_request.py +20 -0
  73. phenoml/{construe/types/construe_cohort_response_queries_item_code_extract_results_item_codes_item.py → lang2fhir/types/create_multi_response_resources_item.py} +13 -7
  74. phenoml/summary/__init__.py +41 -0
  75. phenoml/summary/client.py +668 -0
  76. phenoml/summary/errors/__init__.py +11 -0
  77. phenoml/summary/errors/bad_request_error.py +10 -0
  78. phenoml/summary/errors/forbidden_error.py +10 -0
  79. phenoml/summary/errors/internal_server_error.py +10 -0
  80. phenoml/summary/errors/not_found_error.py +10 -0
  81. phenoml/summary/errors/unauthorized_error.py +10 -0
  82. phenoml/summary/raw_client.py +1202 -0
  83. phenoml/summary/types/__init__.py +33 -0
  84. phenoml/summary/types/create_summary_request_fhir_resources.py +8 -0
  85. phenoml/summary/types/create_summary_request_mode.py +5 -0
  86. phenoml/{agent/types/agent_fhir_config.py → summary/types/create_summary_response.py} +7 -9
  87. phenoml/summary/types/create_summary_template_response.py +23 -0
  88. phenoml/{construe/types/unauthorized_error_body.py → summary/types/error_response.py} +4 -8
  89. phenoml/summary/types/fhir_bundle.py +23 -0
  90. phenoml/summary/types/fhir_bundle_entry_item.py +20 -0
  91. phenoml/summary/types/fhir_resource.py +24 -0
  92. phenoml/summary/types/summary_delete_template_response.py +20 -0
  93. phenoml/summary/types/summary_get_template_response.py +21 -0
  94. phenoml/summary/types/summary_list_templates_response.py +21 -0
  95. phenoml/summary/types/summary_template.py +41 -0
  96. phenoml/summary/types/summary_update_template_response.py +22 -0
  97. phenoml/tools/__init__.py +6 -8
  98. phenoml/tools/client.py +259 -44
  99. phenoml/tools/raw_client.py +347 -55
  100. phenoml/tools/types/__init__.py +6 -8
  101. phenoml/tools/types/lang2fhir_and_create_multi_response.py +41 -0
  102. phenoml/{construe/types/construe_cohort_response_queries_item_code_extract_results_item.py → tools/types/lang2fhir_and_create_multi_response_resource_info_item.py} +14 -7
  103. phenoml/tools/types/lang2fhir_and_create_multi_response_response_bundle.py +27 -0
  104. phenoml/workflows/__init__.py +61 -0
  105. phenoml/workflows/client.py +694 -0
  106. phenoml/workflows/errors/__init__.py +11 -0
  107. phenoml/workflows/errors/bad_request_error.py +10 -0
  108. phenoml/workflows/errors/forbidden_error.py +10 -0
  109. phenoml/workflows/errors/internal_server_error.py +10 -0
  110. phenoml/workflows/errors/not_found_error.py +10 -0
  111. phenoml/workflows/errors/unauthorized_error.py +10 -0
  112. phenoml/workflows/raw_client.py +1266 -0
  113. phenoml/workflows/types/__init__.py +53 -0
  114. phenoml/workflows/types/create_workflow_request_fhir_provider_id.py +5 -0
  115. phenoml/workflows/types/create_workflow_response.py +44 -0
  116. phenoml/{tools/types/fhir_client_config.py → workflows/types/decision_node_definition.py} +7 -6
  117. phenoml/workflows/types/execute_workflow_response.py +30 -0
  118. phenoml/{construe/types/internal_server_error_body.py → workflows/types/execute_workflow_response_results.py} +3 -8
  119. phenoml/workflows/types/lang2fhir_create_definition.py +37 -0
  120. phenoml/workflows/types/lang2fhir_search_definition.py +42 -0
  121. phenoml/workflows/types/list_workflows_response.py +39 -0
  122. phenoml/workflows/types/step_operation.py +26 -0
  123. phenoml/workflows/types/sub_workflow_definition.py +32 -0
  124. phenoml/workflows/types/update_workflow_request_fhir_provider_id.py +5 -0
  125. phenoml/workflows/types/workflow_config.py +27 -0
  126. phenoml/workflows/types/workflow_definition.py +57 -0
  127. phenoml/workflows/types/workflow_graph.py +23 -0
  128. phenoml/workflows/types/workflow_response.py +61 -0
  129. phenoml/workflows/types/workflow_response_graph.py +23 -0
  130. phenoml/workflows/types/workflow_step.py +55 -0
  131. phenoml/workflows/types/workflow_step_summary.py +47 -0
  132. phenoml/workflows/types/workflow_step_summary_type.py +5 -0
  133. phenoml/workflows/types/workflow_step_type.py +5 -0
  134. phenoml/workflows/types/workflows_delete_response.py +20 -0
  135. phenoml/workflows/types/workflows_get_response.py +26 -0
  136. phenoml/workflows/types/workflows_update_response.py +31 -0
  137. phenoml-0.0.17.dist-info/LICENSE +21 -0
  138. {phenoml-0.0.2.dist-info → phenoml-0.0.17.dist-info}/METADATA +1 -1
  139. phenoml-0.0.17.dist-info/RECORD +251 -0
  140. phenoml/agent/types/agent_provider.py +0 -7
  141. phenoml/agent/types/provider_type.py +0 -5
  142. phenoml/construe/types/construe_cohort_request_config.py +0 -37
  143. phenoml/construe/types/construe_cohort_response.py +0 -33
  144. phenoml/construe/types/construe_cohort_response_queries_item.py +0 -49
  145. phenoml/tools/types/cohort_request_provider.py +0 -5
  146. phenoml/tools/types/lang2fhir_and_create_request_provider.py +0 -7
  147. phenoml/tools/types/lang2fhir_and_search_request_provider.py +0 -7
  148. phenoml-0.0.2.dist-info/RECORD +0 -153
  149. {phenoml-0.0.2.dist-info → phenoml-0.0.17.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1202 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.jsonable_encoder import jsonable_encoder
10
+ from ..core.pydantic_utilities import parse_obj_as
11
+ from ..core.request_options import RequestOptions
12
+ from ..core.serialization import convert_and_respect_annotation_metadata
13
+ from .errors.bad_request_error import BadRequestError
14
+ from .errors.forbidden_error import ForbiddenError
15
+ from .errors.internal_server_error import InternalServerError
16
+ from .errors.not_found_error import NotFoundError
17
+ from .errors.unauthorized_error import UnauthorizedError
18
+ from .types.create_summary_request_fhir_resources import CreateSummaryRequestFhirResources
19
+ from .types.create_summary_request_mode import CreateSummaryRequestMode
20
+ from .types.create_summary_response import CreateSummaryResponse
21
+ from .types.create_summary_template_response import CreateSummaryTemplateResponse
22
+ from .types.summary_delete_template_response import SummaryDeleteTemplateResponse
23
+ from .types.summary_get_template_response import SummaryGetTemplateResponse
24
+ from .types.summary_list_templates_response import SummaryListTemplatesResponse
25
+ from .types.summary_update_template_response import SummaryUpdateTemplateResponse
26
+
27
+ # this is used as the default value for optional parameters
28
+ OMIT = typing.cast(typing.Any, ...)
29
+
30
+
31
+ class RawSummaryClient:
32
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
33
+ self._client_wrapper = client_wrapper
34
+
35
+ def list_templates(
36
+ self, *, request_options: typing.Optional[RequestOptions] = None
37
+ ) -> HttpResponse[SummaryListTemplatesResponse]:
38
+ """
39
+ Retrieves all summary templates for the authenticated user
40
+
41
+ Parameters
42
+ ----------
43
+ request_options : typing.Optional[RequestOptions]
44
+ Request-specific configuration.
45
+
46
+ Returns
47
+ -------
48
+ HttpResponse[SummaryListTemplatesResponse]
49
+ Templates retrieved successfully
50
+ """
51
+ _response = self._client_wrapper.httpx_client.request(
52
+ "fhir2summary/templates",
53
+ method="GET",
54
+ request_options=request_options,
55
+ )
56
+ try:
57
+ if 200 <= _response.status_code < 300:
58
+ _data = typing.cast(
59
+ SummaryListTemplatesResponse,
60
+ parse_obj_as(
61
+ type_=SummaryListTemplatesResponse, # type: ignore
62
+ object_=_response.json(),
63
+ ),
64
+ )
65
+ return HttpResponse(response=_response, data=_data)
66
+ if _response.status_code == 401:
67
+ raise UnauthorizedError(
68
+ headers=dict(_response.headers),
69
+ body=typing.cast(
70
+ typing.Optional[typing.Any],
71
+ parse_obj_as(
72
+ type_=typing.Optional[typing.Any], # type: ignore
73
+ object_=_response.json(),
74
+ ),
75
+ ),
76
+ )
77
+ if _response.status_code == 500:
78
+ raise InternalServerError(
79
+ headers=dict(_response.headers),
80
+ body=typing.cast(
81
+ typing.Optional[typing.Any],
82
+ parse_obj_as(
83
+ type_=typing.Optional[typing.Any], # type: ignore
84
+ object_=_response.json(),
85
+ ),
86
+ ),
87
+ )
88
+ _response_json = _response.json()
89
+ except JSONDecodeError:
90
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
91
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
92
+
93
+ def create_template(
94
+ self,
95
+ *,
96
+ name: str,
97
+ example_summary: str,
98
+ target_resources: typing.Sequence[str],
99
+ mode: str,
100
+ description: typing.Optional[str] = OMIT,
101
+ example_fhir_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
102
+ request_options: typing.Optional[RequestOptions] = None,
103
+ ) -> HttpResponse[CreateSummaryTemplateResponse]:
104
+ """
105
+ Creates a summary template from an example using LLM function calling
106
+
107
+ Parameters
108
+ ----------
109
+ name : str
110
+ Name of the template
111
+
112
+ example_summary : str
113
+ Example summary note to generate template from
114
+
115
+ target_resources : typing.Sequence[str]
116
+ List of target FHIR resources
117
+
118
+ mode : str
119
+ Template mode (stored with the template)
120
+
121
+ description : typing.Optional[str]
122
+ Description of the template
123
+
124
+ example_fhir_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
125
+ Optional example FHIR data that corresponds to the example summary
126
+
127
+ request_options : typing.Optional[RequestOptions]
128
+ Request-specific configuration.
129
+
130
+ Returns
131
+ -------
132
+ HttpResponse[CreateSummaryTemplateResponse]
133
+ Template created successfully
134
+ """
135
+ _response = self._client_wrapper.httpx_client.request(
136
+ "fhir2summary/template",
137
+ method="POST",
138
+ json={
139
+ "name": name,
140
+ "description": description,
141
+ "example_summary": example_summary,
142
+ "target_resources": target_resources,
143
+ "example_fhir_data": example_fhir_data,
144
+ "mode": mode,
145
+ },
146
+ headers={
147
+ "content-type": "application/json",
148
+ },
149
+ request_options=request_options,
150
+ omit=OMIT,
151
+ )
152
+ try:
153
+ if 200 <= _response.status_code < 300:
154
+ _data = typing.cast(
155
+ CreateSummaryTemplateResponse,
156
+ parse_obj_as(
157
+ type_=CreateSummaryTemplateResponse, # type: ignore
158
+ object_=_response.json(),
159
+ ),
160
+ )
161
+ return HttpResponse(response=_response, data=_data)
162
+ if _response.status_code == 400:
163
+ raise BadRequestError(
164
+ headers=dict(_response.headers),
165
+ body=typing.cast(
166
+ typing.Optional[typing.Any],
167
+ parse_obj_as(
168
+ type_=typing.Optional[typing.Any], # type: ignore
169
+ object_=_response.json(),
170
+ ),
171
+ ),
172
+ )
173
+ if _response.status_code == 401:
174
+ raise UnauthorizedError(
175
+ headers=dict(_response.headers),
176
+ body=typing.cast(
177
+ typing.Optional[typing.Any],
178
+ parse_obj_as(
179
+ type_=typing.Optional[typing.Any], # type: ignore
180
+ object_=_response.json(),
181
+ ),
182
+ ),
183
+ )
184
+ if _response.status_code == 500:
185
+ raise InternalServerError(
186
+ headers=dict(_response.headers),
187
+ body=typing.cast(
188
+ typing.Optional[typing.Any],
189
+ parse_obj_as(
190
+ type_=typing.Optional[typing.Any], # type: ignore
191
+ object_=_response.json(),
192
+ ),
193
+ ),
194
+ )
195
+ _response_json = _response.json()
196
+ except JSONDecodeError:
197
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
198
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
199
+
200
+ def get_template(
201
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
202
+ ) -> HttpResponse[SummaryGetTemplateResponse]:
203
+ """
204
+ Retrieves a specific summary template
205
+
206
+ Parameters
207
+ ----------
208
+ id : str
209
+ Template ID
210
+
211
+ request_options : typing.Optional[RequestOptions]
212
+ Request-specific configuration.
213
+
214
+ Returns
215
+ -------
216
+ HttpResponse[SummaryGetTemplateResponse]
217
+ Template retrieved successfully
218
+ """
219
+ _response = self._client_wrapper.httpx_client.request(
220
+ f"fhir2summary/template/{jsonable_encoder(id)}",
221
+ method="GET",
222
+ request_options=request_options,
223
+ )
224
+ try:
225
+ if 200 <= _response.status_code < 300:
226
+ _data = typing.cast(
227
+ SummaryGetTemplateResponse,
228
+ parse_obj_as(
229
+ type_=SummaryGetTemplateResponse, # type: ignore
230
+ object_=_response.json(),
231
+ ),
232
+ )
233
+ return HttpResponse(response=_response, data=_data)
234
+ if _response.status_code == 401:
235
+ raise UnauthorizedError(
236
+ headers=dict(_response.headers),
237
+ body=typing.cast(
238
+ typing.Optional[typing.Any],
239
+ parse_obj_as(
240
+ type_=typing.Optional[typing.Any], # type: ignore
241
+ object_=_response.json(),
242
+ ),
243
+ ),
244
+ )
245
+ if _response.status_code == 403:
246
+ raise ForbiddenError(
247
+ headers=dict(_response.headers),
248
+ body=typing.cast(
249
+ typing.Optional[typing.Any],
250
+ parse_obj_as(
251
+ type_=typing.Optional[typing.Any], # type: ignore
252
+ object_=_response.json(),
253
+ ),
254
+ ),
255
+ )
256
+ if _response.status_code == 404:
257
+ raise NotFoundError(
258
+ headers=dict(_response.headers),
259
+ body=typing.cast(
260
+ typing.Optional[typing.Any],
261
+ parse_obj_as(
262
+ type_=typing.Optional[typing.Any], # type: ignore
263
+ object_=_response.json(),
264
+ ),
265
+ ),
266
+ )
267
+ if _response.status_code == 500:
268
+ raise InternalServerError(
269
+ headers=dict(_response.headers),
270
+ body=typing.cast(
271
+ typing.Optional[typing.Any],
272
+ parse_obj_as(
273
+ type_=typing.Optional[typing.Any], # type: ignore
274
+ object_=_response.json(),
275
+ ),
276
+ ),
277
+ )
278
+ _response_json = _response.json()
279
+ except JSONDecodeError:
280
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
281
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
282
+
283
+ def update_template(
284
+ self,
285
+ id: str,
286
+ *,
287
+ name: str,
288
+ template: str,
289
+ target_resources: typing.Sequence[str],
290
+ mode: str,
291
+ description: typing.Optional[str] = OMIT,
292
+ request_options: typing.Optional[RequestOptions] = None,
293
+ ) -> HttpResponse[SummaryUpdateTemplateResponse]:
294
+ """
295
+ Updates an existing summary template
296
+
297
+ Parameters
298
+ ----------
299
+ id : str
300
+ Template ID
301
+
302
+ name : str
303
+
304
+ template : str
305
+ Updated template with placeholders
306
+
307
+ target_resources : typing.Sequence[str]
308
+
309
+ mode : str
310
+ Template mode
311
+
312
+ description : typing.Optional[str]
313
+
314
+ request_options : typing.Optional[RequestOptions]
315
+ Request-specific configuration.
316
+
317
+ Returns
318
+ -------
319
+ HttpResponse[SummaryUpdateTemplateResponse]
320
+ Template updated successfully
321
+ """
322
+ _response = self._client_wrapper.httpx_client.request(
323
+ f"fhir2summary/template/{jsonable_encoder(id)}",
324
+ method="PUT",
325
+ json={
326
+ "name": name,
327
+ "description": description,
328
+ "template": template,
329
+ "target_resources": target_resources,
330
+ "mode": mode,
331
+ },
332
+ headers={
333
+ "content-type": "application/json",
334
+ },
335
+ request_options=request_options,
336
+ omit=OMIT,
337
+ )
338
+ try:
339
+ if 200 <= _response.status_code < 300:
340
+ _data = typing.cast(
341
+ SummaryUpdateTemplateResponse,
342
+ parse_obj_as(
343
+ type_=SummaryUpdateTemplateResponse, # type: ignore
344
+ object_=_response.json(),
345
+ ),
346
+ )
347
+ return HttpResponse(response=_response, data=_data)
348
+ if _response.status_code == 400:
349
+ raise BadRequestError(
350
+ headers=dict(_response.headers),
351
+ body=typing.cast(
352
+ typing.Optional[typing.Any],
353
+ parse_obj_as(
354
+ type_=typing.Optional[typing.Any], # type: ignore
355
+ object_=_response.json(),
356
+ ),
357
+ ),
358
+ )
359
+ if _response.status_code == 401:
360
+ raise UnauthorizedError(
361
+ headers=dict(_response.headers),
362
+ body=typing.cast(
363
+ typing.Optional[typing.Any],
364
+ parse_obj_as(
365
+ type_=typing.Optional[typing.Any], # type: ignore
366
+ object_=_response.json(),
367
+ ),
368
+ ),
369
+ )
370
+ if _response.status_code == 403:
371
+ raise ForbiddenError(
372
+ headers=dict(_response.headers),
373
+ body=typing.cast(
374
+ typing.Optional[typing.Any],
375
+ parse_obj_as(
376
+ type_=typing.Optional[typing.Any], # type: ignore
377
+ object_=_response.json(),
378
+ ),
379
+ ),
380
+ )
381
+ if _response.status_code == 404:
382
+ raise NotFoundError(
383
+ headers=dict(_response.headers),
384
+ body=typing.cast(
385
+ typing.Optional[typing.Any],
386
+ parse_obj_as(
387
+ type_=typing.Optional[typing.Any], # type: ignore
388
+ object_=_response.json(),
389
+ ),
390
+ ),
391
+ )
392
+ if _response.status_code == 500:
393
+ raise InternalServerError(
394
+ headers=dict(_response.headers),
395
+ body=typing.cast(
396
+ typing.Optional[typing.Any],
397
+ parse_obj_as(
398
+ type_=typing.Optional[typing.Any], # type: ignore
399
+ object_=_response.json(),
400
+ ),
401
+ ),
402
+ )
403
+ _response_json = _response.json()
404
+ except JSONDecodeError:
405
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
406
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
407
+
408
+ def delete_template(
409
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
410
+ ) -> HttpResponse[SummaryDeleteTemplateResponse]:
411
+ """
412
+ Deletes a summary template
413
+
414
+ Parameters
415
+ ----------
416
+ id : str
417
+ Template ID
418
+
419
+ request_options : typing.Optional[RequestOptions]
420
+ Request-specific configuration.
421
+
422
+ Returns
423
+ -------
424
+ HttpResponse[SummaryDeleteTemplateResponse]
425
+ Template deleted successfully
426
+ """
427
+ _response = self._client_wrapper.httpx_client.request(
428
+ f"fhir2summary/template/{jsonable_encoder(id)}",
429
+ method="DELETE",
430
+ request_options=request_options,
431
+ )
432
+ try:
433
+ if 200 <= _response.status_code < 300:
434
+ _data = typing.cast(
435
+ SummaryDeleteTemplateResponse,
436
+ parse_obj_as(
437
+ type_=SummaryDeleteTemplateResponse, # type: ignore
438
+ object_=_response.json(),
439
+ ),
440
+ )
441
+ return HttpResponse(response=_response, data=_data)
442
+ if _response.status_code == 401:
443
+ raise UnauthorizedError(
444
+ headers=dict(_response.headers),
445
+ body=typing.cast(
446
+ typing.Optional[typing.Any],
447
+ parse_obj_as(
448
+ type_=typing.Optional[typing.Any], # type: ignore
449
+ object_=_response.json(),
450
+ ),
451
+ ),
452
+ )
453
+ if _response.status_code == 403:
454
+ raise ForbiddenError(
455
+ headers=dict(_response.headers),
456
+ body=typing.cast(
457
+ typing.Optional[typing.Any],
458
+ parse_obj_as(
459
+ type_=typing.Optional[typing.Any], # type: ignore
460
+ object_=_response.json(),
461
+ ),
462
+ ),
463
+ )
464
+ if _response.status_code == 404:
465
+ raise NotFoundError(
466
+ headers=dict(_response.headers),
467
+ body=typing.cast(
468
+ typing.Optional[typing.Any],
469
+ parse_obj_as(
470
+ type_=typing.Optional[typing.Any], # type: ignore
471
+ object_=_response.json(),
472
+ ),
473
+ ),
474
+ )
475
+ if _response.status_code == 500:
476
+ raise InternalServerError(
477
+ headers=dict(_response.headers),
478
+ body=typing.cast(
479
+ typing.Optional[typing.Any],
480
+ parse_obj_as(
481
+ type_=typing.Optional[typing.Any], # type: ignore
482
+ object_=_response.json(),
483
+ ),
484
+ ),
485
+ )
486
+ _response_json = _response.json()
487
+ except JSONDecodeError:
488
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
489
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
490
+
491
+ def create(
492
+ self,
493
+ *,
494
+ fhir_resources: CreateSummaryRequestFhirResources,
495
+ mode: typing.Optional[CreateSummaryRequestMode] = OMIT,
496
+ template_id: typing.Optional[str] = OMIT,
497
+ request_options: typing.Optional[RequestOptions] = None,
498
+ ) -> HttpResponse[CreateSummaryResponse]:
499
+ """
500
+ Creates a summary from FHIR resources using one of three modes:
501
+ - **narrative**: Uses a template to substitute FHIR data into placeholders (requires template_id)
502
+ - **flatten**: Flattens FHIR resources into a searchable format for RAG/search (no template needed)
503
+ - **ips**: Generates an International Patient Summary (IPS) narrative per ISO 27269/HL7 FHIR IPS IG. Requires a Bundle with exactly one Patient resource (returns 400 error if no Patient or multiple Patients are present). Automatically filters resources to those referencing the patient and generates sections for allergies, medications, problems, immunizations, procedures, and vital signs.
504
+
505
+ Parameters
506
+ ----------
507
+ fhir_resources : CreateSummaryRequestFhirResources
508
+ FHIR resources (single resource or Bundle).
509
+ For IPS mode, must be a Bundle containing exactly one Patient resource with at least one
510
+ identifier (id, fullUrl, or identifier field). Returns an error if no Patient is found,
511
+ if multiple Patients are present, or if the Patient has no identifiers. Resources are
512
+ automatically filtered to only include those referencing the patient.
513
+
514
+ mode : typing.Optional[CreateSummaryRequestMode]
515
+ Summary generation mode:
516
+ - narrative: Substitute FHIR data into a template (requires template_id)
517
+ - flatten: Flatten FHIR resources for RAG/search (no template needed)
518
+ - ips: Generate International Patient Summary (IPS) narrative per ISO 27269/HL7 FHIR IPS IG
519
+
520
+ template_id : typing.Optional[str]
521
+ ID of the template to use (required for narrative mode)
522
+
523
+ request_options : typing.Optional[RequestOptions]
524
+ Request-specific configuration.
525
+
526
+ Returns
527
+ -------
528
+ HttpResponse[CreateSummaryResponse]
529
+ Summary generated successfully
530
+ """
531
+ _response = self._client_wrapper.httpx_client.request(
532
+ "fhir2summary/create",
533
+ method="POST",
534
+ json={
535
+ "mode": mode,
536
+ "template_id": template_id,
537
+ "fhir_resources": convert_and_respect_annotation_metadata(
538
+ object_=fhir_resources, annotation=CreateSummaryRequestFhirResources, direction="write"
539
+ ),
540
+ },
541
+ headers={
542
+ "content-type": "application/json",
543
+ },
544
+ request_options=request_options,
545
+ omit=OMIT,
546
+ )
547
+ try:
548
+ if 200 <= _response.status_code < 300:
549
+ _data = typing.cast(
550
+ CreateSummaryResponse,
551
+ parse_obj_as(
552
+ type_=CreateSummaryResponse, # type: ignore
553
+ object_=_response.json(),
554
+ ),
555
+ )
556
+ return HttpResponse(response=_response, data=_data)
557
+ if _response.status_code == 400:
558
+ raise BadRequestError(
559
+ headers=dict(_response.headers),
560
+ body=typing.cast(
561
+ typing.Optional[typing.Any],
562
+ parse_obj_as(
563
+ type_=typing.Optional[typing.Any], # type: ignore
564
+ object_=_response.json(),
565
+ ),
566
+ ),
567
+ )
568
+ if _response.status_code == 401:
569
+ raise UnauthorizedError(
570
+ headers=dict(_response.headers),
571
+ body=typing.cast(
572
+ typing.Optional[typing.Any],
573
+ parse_obj_as(
574
+ type_=typing.Optional[typing.Any], # type: ignore
575
+ object_=_response.json(),
576
+ ),
577
+ ),
578
+ )
579
+ if _response.status_code == 403:
580
+ raise ForbiddenError(
581
+ headers=dict(_response.headers),
582
+ body=typing.cast(
583
+ typing.Optional[typing.Any],
584
+ parse_obj_as(
585
+ type_=typing.Optional[typing.Any], # type: ignore
586
+ object_=_response.json(),
587
+ ),
588
+ ),
589
+ )
590
+ if _response.status_code == 404:
591
+ raise NotFoundError(
592
+ headers=dict(_response.headers),
593
+ body=typing.cast(
594
+ typing.Optional[typing.Any],
595
+ parse_obj_as(
596
+ type_=typing.Optional[typing.Any], # type: ignore
597
+ object_=_response.json(),
598
+ ),
599
+ ),
600
+ )
601
+ if _response.status_code == 500:
602
+ raise InternalServerError(
603
+ headers=dict(_response.headers),
604
+ body=typing.cast(
605
+ typing.Optional[typing.Any],
606
+ parse_obj_as(
607
+ type_=typing.Optional[typing.Any], # type: ignore
608
+ object_=_response.json(),
609
+ ),
610
+ ),
611
+ )
612
+ _response_json = _response.json()
613
+ except JSONDecodeError:
614
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
615
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
616
+
617
+
618
+ class AsyncRawSummaryClient:
619
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
620
+ self._client_wrapper = client_wrapper
621
+
622
+ async def list_templates(
623
+ self, *, request_options: typing.Optional[RequestOptions] = None
624
+ ) -> AsyncHttpResponse[SummaryListTemplatesResponse]:
625
+ """
626
+ Retrieves all summary templates for the authenticated user
627
+
628
+ Parameters
629
+ ----------
630
+ request_options : typing.Optional[RequestOptions]
631
+ Request-specific configuration.
632
+
633
+ Returns
634
+ -------
635
+ AsyncHttpResponse[SummaryListTemplatesResponse]
636
+ Templates retrieved successfully
637
+ """
638
+ _response = await self._client_wrapper.httpx_client.request(
639
+ "fhir2summary/templates",
640
+ method="GET",
641
+ request_options=request_options,
642
+ )
643
+ try:
644
+ if 200 <= _response.status_code < 300:
645
+ _data = typing.cast(
646
+ SummaryListTemplatesResponse,
647
+ parse_obj_as(
648
+ type_=SummaryListTemplatesResponse, # type: ignore
649
+ object_=_response.json(),
650
+ ),
651
+ )
652
+ return AsyncHttpResponse(response=_response, data=_data)
653
+ if _response.status_code == 401:
654
+ raise UnauthorizedError(
655
+ headers=dict(_response.headers),
656
+ body=typing.cast(
657
+ typing.Optional[typing.Any],
658
+ parse_obj_as(
659
+ type_=typing.Optional[typing.Any], # type: ignore
660
+ object_=_response.json(),
661
+ ),
662
+ ),
663
+ )
664
+ if _response.status_code == 500:
665
+ raise InternalServerError(
666
+ headers=dict(_response.headers),
667
+ body=typing.cast(
668
+ typing.Optional[typing.Any],
669
+ parse_obj_as(
670
+ type_=typing.Optional[typing.Any], # type: ignore
671
+ object_=_response.json(),
672
+ ),
673
+ ),
674
+ )
675
+ _response_json = _response.json()
676
+ except JSONDecodeError:
677
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
678
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
679
+
680
+ async def create_template(
681
+ self,
682
+ *,
683
+ name: str,
684
+ example_summary: str,
685
+ target_resources: typing.Sequence[str],
686
+ mode: str,
687
+ description: typing.Optional[str] = OMIT,
688
+ example_fhir_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
689
+ request_options: typing.Optional[RequestOptions] = None,
690
+ ) -> AsyncHttpResponse[CreateSummaryTemplateResponse]:
691
+ """
692
+ Creates a summary template from an example using LLM function calling
693
+
694
+ Parameters
695
+ ----------
696
+ name : str
697
+ Name of the template
698
+
699
+ example_summary : str
700
+ Example summary note to generate template from
701
+
702
+ target_resources : typing.Sequence[str]
703
+ List of target FHIR resources
704
+
705
+ mode : str
706
+ Template mode (stored with the template)
707
+
708
+ description : typing.Optional[str]
709
+ Description of the template
710
+
711
+ example_fhir_data : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
712
+ Optional example FHIR data that corresponds to the example summary
713
+
714
+ request_options : typing.Optional[RequestOptions]
715
+ Request-specific configuration.
716
+
717
+ Returns
718
+ -------
719
+ AsyncHttpResponse[CreateSummaryTemplateResponse]
720
+ Template created successfully
721
+ """
722
+ _response = await self._client_wrapper.httpx_client.request(
723
+ "fhir2summary/template",
724
+ method="POST",
725
+ json={
726
+ "name": name,
727
+ "description": description,
728
+ "example_summary": example_summary,
729
+ "target_resources": target_resources,
730
+ "example_fhir_data": example_fhir_data,
731
+ "mode": mode,
732
+ },
733
+ headers={
734
+ "content-type": "application/json",
735
+ },
736
+ request_options=request_options,
737
+ omit=OMIT,
738
+ )
739
+ try:
740
+ if 200 <= _response.status_code < 300:
741
+ _data = typing.cast(
742
+ CreateSummaryTemplateResponse,
743
+ parse_obj_as(
744
+ type_=CreateSummaryTemplateResponse, # type: ignore
745
+ object_=_response.json(),
746
+ ),
747
+ )
748
+ return AsyncHttpResponse(response=_response, data=_data)
749
+ if _response.status_code == 400:
750
+ raise BadRequestError(
751
+ headers=dict(_response.headers),
752
+ body=typing.cast(
753
+ typing.Optional[typing.Any],
754
+ parse_obj_as(
755
+ type_=typing.Optional[typing.Any], # type: ignore
756
+ object_=_response.json(),
757
+ ),
758
+ ),
759
+ )
760
+ if _response.status_code == 401:
761
+ raise UnauthorizedError(
762
+ headers=dict(_response.headers),
763
+ body=typing.cast(
764
+ typing.Optional[typing.Any],
765
+ parse_obj_as(
766
+ type_=typing.Optional[typing.Any], # type: ignore
767
+ object_=_response.json(),
768
+ ),
769
+ ),
770
+ )
771
+ if _response.status_code == 500:
772
+ raise InternalServerError(
773
+ headers=dict(_response.headers),
774
+ body=typing.cast(
775
+ typing.Optional[typing.Any],
776
+ parse_obj_as(
777
+ type_=typing.Optional[typing.Any], # type: ignore
778
+ object_=_response.json(),
779
+ ),
780
+ ),
781
+ )
782
+ _response_json = _response.json()
783
+ except JSONDecodeError:
784
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
785
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
786
+
787
+ async def get_template(
788
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
789
+ ) -> AsyncHttpResponse[SummaryGetTemplateResponse]:
790
+ """
791
+ Retrieves a specific summary template
792
+
793
+ Parameters
794
+ ----------
795
+ id : str
796
+ Template ID
797
+
798
+ request_options : typing.Optional[RequestOptions]
799
+ Request-specific configuration.
800
+
801
+ Returns
802
+ -------
803
+ AsyncHttpResponse[SummaryGetTemplateResponse]
804
+ Template retrieved successfully
805
+ """
806
+ _response = await self._client_wrapper.httpx_client.request(
807
+ f"fhir2summary/template/{jsonable_encoder(id)}",
808
+ method="GET",
809
+ request_options=request_options,
810
+ )
811
+ try:
812
+ if 200 <= _response.status_code < 300:
813
+ _data = typing.cast(
814
+ SummaryGetTemplateResponse,
815
+ parse_obj_as(
816
+ type_=SummaryGetTemplateResponse, # type: ignore
817
+ object_=_response.json(),
818
+ ),
819
+ )
820
+ return AsyncHttpResponse(response=_response, data=_data)
821
+ if _response.status_code == 401:
822
+ raise UnauthorizedError(
823
+ headers=dict(_response.headers),
824
+ body=typing.cast(
825
+ typing.Optional[typing.Any],
826
+ parse_obj_as(
827
+ type_=typing.Optional[typing.Any], # type: ignore
828
+ object_=_response.json(),
829
+ ),
830
+ ),
831
+ )
832
+ if _response.status_code == 403:
833
+ raise ForbiddenError(
834
+ headers=dict(_response.headers),
835
+ body=typing.cast(
836
+ typing.Optional[typing.Any],
837
+ parse_obj_as(
838
+ type_=typing.Optional[typing.Any], # type: ignore
839
+ object_=_response.json(),
840
+ ),
841
+ ),
842
+ )
843
+ if _response.status_code == 404:
844
+ raise NotFoundError(
845
+ headers=dict(_response.headers),
846
+ body=typing.cast(
847
+ typing.Optional[typing.Any],
848
+ parse_obj_as(
849
+ type_=typing.Optional[typing.Any], # type: ignore
850
+ object_=_response.json(),
851
+ ),
852
+ ),
853
+ )
854
+ if _response.status_code == 500:
855
+ raise InternalServerError(
856
+ headers=dict(_response.headers),
857
+ body=typing.cast(
858
+ typing.Optional[typing.Any],
859
+ parse_obj_as(
860
+ type_=typing.Optional[typing.Any], # type: ignore
861
+ object_=_response.json(),
862
+ ),
863
+ ),
864
+ )
865
+ _response_json = _response.json()
866
+ except JSONDecodeError:
867
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
868
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
869
+
870
+ async def update_template(
871
+ self,
872
+ id: str,
873
+ *,
874
+ name: str,
875
+ template: str,
876
+ target_resources: typing.Sequence[str],
877
+ mode: str,
878
+ description: typing.Optional[str] = OMIT,
879
+ request_options: typing.Optional[RequestOptions] = None,
880
+ ) -> AsyncHttpResponse[SummaryUpdateTemplateResponse]:
881
+ """
882
+ Updates an existing summary template
883
+
884
+ Parameters
885
+ ----------
886
+ id : str
887
+ Template ID
888
+
889
+ name : str
890
+
891
+ template : str
892
+ Updated template with placeholders
893
+
894
+ target_resources : typing.Sequence[str]
895
+
896
+ mode : str
897
+ Template mode
898
+
899
+ description : typing.Optional[str]
900
+
901
+ request_options : typing.Optional[RequestOptions]
902
+ Request-specific configuration.
903
+
904
+ Returns
905
+ -------
906
+ AsyncHttpResponse[SummaryUpdateTemplateResponse]
907
+ Template updated successfully
908
+ """
909
+ _response = await self._client_wrapper.httpx_client.request(
910
+ f"fhir2summary/template/{jsonable_encoder(id)}",
911
+ method="PUT",
912
+ json={
913
+ "name": name,
914
+ "description": description,
915
+ "template": template,
916
+ "target_resources": target_resources,
917
+ "mode": mode,
918
+ },
919
+ headers={
920
+ "content-type": "application/json",
921
+ },
922
+ request_options=request_options,
923
+ omit=OMIT,
924
+ )
925
+ try:
926
+ if 200 <= _response.status_code < 300:
927
+ _data = typing.cast(
928
+ SummaryUpdateTemplateResponse,
929
+ parse_obj_as(
930
+ type_=SummaryUpdateTemplateResponse, # type: ignore
931
+ object_=_response.json(),
932
+ ),
933
+ )
934
+ return AsyncHttpResponse(response=_response, data=_data)
935
+ if _response.status_code == 400:
936
+ raise BadRequestError(
937
+ headers=dict(_response.headers),
938
+ body=typing.cast(
939
+ typing.Optional[typing.Any],
940
+ parse_obj_as(
941
+ type_=typing.Optional[typing.Any], # type: ignore
942
+ object_=_response.json(),
943
+ ),
944
+ ),
945
+ )
946
+ if _response.status_code == 401:
947
+ raise UnauthorizedError(
948
+ headers=dict(_response.headers),
949
+ body=typing.cast(
950
+ typing.Optional[typing.Any],
951
+ parse_obj_as(
952
+ type_=typing.Optional[typing.Any], # type: ignore
953
+ object_=_response.json(),
954
+ ),
955
+ ),
956
+ )
957
+ if _response.status_code == 403:
958
+ raise ForbiddenError(
959
+ headers=dict(_response.headers),
960
+ body=typing.cast(
961
+ typing.Optional[typing.Any],
962
+ parse_obj_as(
963
+ type_=typing.Optional[typing.Any], # type: ignore
964
+ object_=_response.json(),
965
+ ),
966
+ ),
967
+ )
968
+ if _response.status_code == 404:
969
+ raise NotFoundError(
970
+ headers=dict(_response.headers),
971
+ body=typing.cast(
972
+ typing.Optional[typing.Any],
973
+ parse_obj_as(
974
+ type_=typing.Optional[typing.Any], # type: ignore
975
+ object_=_response.json(),
976
+ ),
977
+ ),
978
+ )
979
+ if _response.status_code == 500:
980
+ raise InternalServerError(
981
+ headers=dict(_response.headers),
982
+ body=typing.cast(
983
+ typing.Optional[typing.Any],
984
+ parse_obj_as(
985
+ type_=typing.Optional[typing.Any], # type: ignore
986
+ object_=_response.json(),
987
+ ),
988
+ ),
989
+ )
990
+ _response_json = _response.json()
991
+ except JSONDecodeError:
992
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
993
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
994
+
995
+ async def delete_template(
996
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
997
+ ) -> AsyncHttpResponse[SummaryDeleteTemplateResponse]:
998
+ """
999
+ Deletes a summary template
1000
+
1001
+ Parameters
1002
+ ----------
1003
+ id : str
1004
+ Template ID
1005
+
1006
+ request_options : typing.Optional[RequestOptions]
1007
+ Request-specific configuration.
1008
+
1009
+ Returns
1010
+ -------
1011
+ AsyncHttpResponse[SummaryDeleteTemplateResponse]
1012
+ Template deleted successfully
1013
+ """
1014
+ _response = await self._client_wrapper.httpx_client.request(
1015
+ f"fhir2summary/template/{jsonable_encoder(id)}",
1016
+ method="DELETE",
1017
+ request_options=request_options,
1018
+ )
1019
+ try:
1020
+ if 200 <= _response.status_code < 300:
1021
+ _data = typing.cast(
1022
+ SummaryDeleteTemplateResponse,
1023
+ parse_obj_as(
1024
+ type_=SummaryDeleteTemplateResponse, # type: ignore
1025
+ object_=_response.json(),
1026
+ ),
1027
+ )
1028
+ return AsyncHttpResponse(response=_response, data=_data)
1029
+ if _response.status_code == 401:
1030
+ raise UnauthorizedError(
1031
+ headers=dict(_response.headers),
1032
+ body=typing.cast(
1033
+ typing.Optional[typing.Any],
1034
+ parse_obj_as(
1035
+ type_=typing.Optional[typing.Any], # type: ignore
1036
+ object_=_response.json(),
1037
+ ),
1038
+ ),
1039
+ )
1040
+ if _response.status_code == 403:
1041
+ raise ForbiddenError(
1042
+ headers=dict(_response.headers),
1043
+ body=typing.cast(
1044
+ typing.Optional[typing.Any],
1045
+ parse_obj_as(
1046
+ type_=typing.Optional[typing.Any], # type: ignore
1047
+ object_=_response.json(),
1048
+ ),
1049
+ ),
1050
+ )
1051
+ if _response.status_code == 404:
1052
+ raise NotFoundError(
1053
+ headers=dict(_response.headers),
1054
+ body=typing.cast(
1055
+ typing.Optional[typing.Any],
1056
+ parse_obj_as(
1057
+ type_=typing.Optional[typing.Any], # type: ignore
1058
+ object_=_response.json(),
1059
+ ),
1060
+ ),
1061
+ )
1062
+ if _response.status_code == 500:
1063
+ raise InternalServerError(
1064
+ headers=dict(_response.headers),
1065
+ body=typing.cast(
1066
+ typing.Optional[typing.Any],
1067
+ parse_obj_as(
1068
+ type_=typing.Optional[typing.Any], # type: ignore
1069
+ object_=_response.json(),
1070
+ ),
1071
+ ),
1072
+ )
1073
+ _response_json = _response.json()
1074
+ except JSONDecodeError:
1075
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1076
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1077
+
1078
+ async def create(
1079
+ self,
1080
+ *,
1081
+ fhir_resources: CreateSummaryRequestFhirResources,
1082
+ mode: typing.Optional[CreateSummaryRequestMode] = OMIT,
1083
+ template_id: typing.Optional[str] = OMIT,
1084
+ request_options: typing.Optional[RequestOptions] = None,
1085
+ ) -> AsyncHttpResponse[CreateSummaryResponse]:
1086
+ """
1087
+ Creates a summary from FHIR resources using one of three modes:
1088
+ - **narrative**: Uses a template to substitute FHIR data into placeholders (requires template_id)
1089
+ - **flatten**: Flattens FHIR resources into a searchable format for RAG/search (no template needed)
1090
+ - **ips**: Generates an International Patient Summary (IPS) narrative per ISO 27269/HL7 FHIR IPS IG. Requires a Bundle with exactly one Patient resource (returns 400 error if no Patient or multiple Patients are present). Automatically filters resources to those referencing the patient and generates sections for allergies, medications, problems, immunizations, procedures, and vital signs.
1091
+
1092
+ Parameters
1093
+ ----------
1094
+ fhir_resources : CreateSummaryRequestFhirResources
1095
+ FHIR resources (single resource or Bundle).
1096
+ For IPS mode, must be a Bundle containing exactly one Patient resource with at least one
1097
+ identifier (id, fullUrl, or identifier field). Returns an error if no Patient is found,
1098
+ if multiple Patients are present, or if the Patient has no identifiers. Resources are
1099
+ automatically filtered to only include those referencing the patient.
1100
+
1101
+ mode : typing.Optional[CreateSummaryRequestMode]
1102
+ Summary generation mode:
1103
+ - narrative: Substitute FHIR data into a template (requires template_id)
1104
+ - flatten: Flatten FHIR resources for RAG/search (no template needed)
1105
+ - ips: Generate International Patient Summary (IPS) narrative per ISO 27269/HL7 FHIR IPS IG
1106
+
1107
+ template_id : typing.Optional[str]
1108
+ ID of the template to use (required for narrative mode)
1109
+
1110
+ request_options : typing.Optional[RequestOptions]
1111
+ Request-specific configuration.
1112
+
1113
+ Returns
1114
+ -------
1115
+ AsyncHttpResponse[CreateSummaryResponse]
1116
+ Summary generated successfully
1117
+ """
1118
+ _response = await self._client_wrapper.httpx_client.request(
1119
+ "fhir2summary/create",
1120
+ method="POST",
1121
+ json={
1122
+ "mode": mode,
1123
+ "template_id": template_id,
1124
+ "fhir_resources": convert_and_respect_annotation_metadata(
1125
+ object_=fhir_resources, annotation=CreateSummaryRequestFhirResources, direction="write"
1126
+ ),
1127
+ },
1128
+ headers={
1129
+ "content-type": "application/json",
1130
+ },
1131
+ request_options=request_options,
1132
+ omit=OMIT,
1133
+ )
1134
+ try:
1135
+ if 200 <= _response.status_code < 300:
1136
+ _data = typing.cast(
1137
+ CreateSummaryResponse,
1138
+ parse_obj_as(
1139
+ type_=CreateSummaryResponse, # type: ignore
1140
+ object_=_response.json(),
1141
+ ),
1142
+ )
1143
+ return AsyncHttpResponse(response=_response, data=_data)
1144
+ if _response.status_code == 400:
1145
+ raise BadRequestError(
1146
+ headers=dict(_response.headers),
1147
+ body=typing.cast(
1148
+ typing.Optional[typing.Any],
1149
+ parse_obj_as(
1150
+ type_=typing.Optional[typing.Any], # type: ignore
1151
+ object_=_response.json(),
1152
+ ),
1153
+ ),
1154
+ )
1155
+ if _response.status_code == 401:
1156
+ raise UnauthorizedError(
1157
+ headers=dict(_response.headers),
1158
+ body=typing.cast(
1159
+ typing.Optional[typing.Any],
1160
+ parse_obj_as(
1161
+ type_=typing.Optional[typing.Any], # type: ignore
1162
+ object_=_response.json(),
1163
+ ),
1164
+ ),
1165
+ )
1166
+ if _response.status_code == 403:
1167
+ raise ForbiddenError(
1168
+ headers=dict(_response.headers),
1169
+ body=typing.cast(
1170
+ typing.Optional[typing.Any],
1171
+ parse_obj_as(
1172
+ type_=typing.Optional[typing.Any], # type: ignore
1173
+ object_=_response.json(),
1174
+ ),
1175
+ ),
1176
+ )
1177
+ if _response.status_code == 404:
1178
+ raise NotFoundError(
1179
+ headers=dict(_response.headers),
1180
+ body=typing.cast(
1181
+ typing.Optional[typing.Any],
1182
+ parse_obj_as(
1183
+ type_=typing.Optional[typing.Any], # type: ignore
1184
+ object_=_response.json(),
1185
+ ),
1186
+ ),
1187
+ )
1188
+ if _response.status_code == 500:
1189
+ raise InternalServerError(
1190
+ headers=dict(_response.headers),
1191
+ body=typing.cast(
1192
+ typing.Optional[typing.Any],
1193
+ parse_obj_as(
1194
+ type_=typing.Optional[typing.Any], # type: ignore
1195
+ object_=_response.json(),
1196
+ ),
1197
+ ),
1198
+ )
1199
+ _response_json = _response.json()
1200
+ except JSONDecodeError:
1201
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1202
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)