phenoml 0.0.8__py3-none-any.whl → 0.0.9__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 (34) hide show
  1. phenoml/agent/client.py +38 -2
  2. phenoml/agent/raw_client.py +24 -0
  3. phenoml/client.py +4 -4
  4. phenoml/construe/__init__.py +2 -16
  5. phenoml/construe/client.py +0 -90
  6. phenoml/construe/raw_client.py +0 -180
  7. phenoml/construe/types/__init__.py +2 -20
  8. phenoml/construe/types/extract_request_config.py +33 -4
  9. phenoml/construe/types/extract_request_config_chunking_method.py +3 -1
  10. phenoml/construe/types/extract_request_config_validation_method.py +5 -0
  11. phenoml/construe/types/extract_request_system.py +2 -0
  12. phenoml/core/client_wrapper.py +8 -10
  13. phenoml/fhir/client.py +116 -14
  14. phenoml/fhir/raw_client.py +84 -0
  15. phenoml/fhir_provider/__init__.py +2 -0
  16. phenoml/fhir_provider/client.py +21 -4
  17. phenoml/fhir_provider/raw_client.py +23 -6
  18. phenoml/fhir_provider/types/__init__.py +2 -0
  19. phenoml/fhir_provider/types/auth_method.py +1 -1
  20. phenoml/fhir_provider/types/role.py +27 -0
  21. phenoml/tools/client.py +112 -6
  22. phenoml/tools/raw_client.py +82 -2
  23. {phenoml-0.0.8.dist-info → phenoml-0.0.9.dist-info}/METADATA +1 -1
  24. {phenoml-0.0.8.dist-info → phenoml-0.0.9.dist-info}/RECORD +26 -32
  25. phenoml/construe/types/bad_request_error_body.py +0 -27
  26. phenoml/construe/types/construe_cohort_request_config.py +0 -37
  27. phenoml/construe/types/construe_cohort_response.py +0 -33
  28. phenoml/construe/types/construe_cohort_response_queries_item.py +0 -49
  29. phenoml/construe/types/construe_cohort_response_queries_item_code_extract_results_item.py +0 -31
  30. phenoml/construe/types/construe_cohort_response_queries_item_code_extract_results_item_codes_item.py +0 -32
  31. phenoml/construe/types/internal_server_error_body.py +0 -27
  32. phenoml/construe/types/unauthorized_error_body.py +0 -27
  33. {phenoml-0.0.8.dist-info → phenoml-0.0.9.dist-info}/LICENSE +0 -0
  34. {phenoml-0.0.8.dist-info → phenoml-0.0.9.dist-info}/WHEEL +0 -0
phenoml/agent/client.py CHANGED
@@ -343,6 +343,8 @@ class AgentClient:
343
343
  *,
344
344
  message: str,
345
345
  agent_id: str,
346
+ phenoml_on_behalf_of: typing.Optional[str] = None,
347
+ phenoml_fhir_provider: typing.Optional[str] = None,
346
348
  context: typing.Optional[str] = OMIT,
347
349
  session_id: typing.Optional[str] = OMIT,
348
350
  request_options: typing.Optional[RequestOptions] = None,
@@ -358,6 +360,14 @@ class AgentClient:
358
360
  agent_id : str
359
361
  The ID of the agent to chat with
360
362
 
363
+ phenoml_on_behalf_of : typing.Optional[str]
364
+ Optional header for on-behalf-of authentication. Used when making requests on behalf of another user or entity.
365
+ Must be in the format: Patient/{uuid} or Practitioner/{uuid}
366
+
367
+ phenoml_fhir_provider : typing.Optional[str]
368
+ Optional header for FHIR provider authentication. Contains credentials in the format {fhir_provider_id}:{oauth2_token}.
369
+ Multiple FHIR provider integrations can be provided as comma-separated values.
370
+
361
371
  context : typing.Optional[str]
362
372
  Optional context for the conversation
363
373
 
@@ -380,12 +390,20 @@ class AgentClient:
380
390
  token="YOUR_TOKEN",
381
391
  )
382
392
  client.agent.chat(
393
+ phenoml_on_behalf_of="Patient/550e8400-e29b-41d4-a716-446655440000",
394
+ phenoml_fhir_provider="550e8400-e29b-41d4-a716-446655440000:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c...",
383
395
  message="What is the patient's current condition?",
384
396
  agent_id="agent-123",
385
397
  )
386
398
  """
387
399
  _response = self._raw_client.chat(
388
- message=message, agent_id=agent_id, context=context, session_id=session_id, request_options=request_options
400
+ message=message,
401
+ agent_id=agent_id,
402
+ phenoml_on_behalf_of=phenoml_on_behalf_of,
403
+ phenoml_fhir_provider=phenoml_fhir_provider,
404
+ context=context,
405
+ session_id=session_id,
406
+ request_options=request_options,
389
407
  )
390
408
  return _response.data
391
409
 
@@ -819,6 +837,8 @@ class AsyncAgentClient:
819
837
  *,
820
838
  message: str,
821
839
  agent_id: str,
840
+ phenoml_on_behalf_of: typing.Optional[str] = None,
841
+ phenoml_fhir_provider: typing.Optional[str] = None,
822
842
  context: typing.Optional[str] = OMIT,
823
843
  session_id: typing.Optional[str] = OMIT,
824
844
  request_options: typing.Optional[RequestOptions] = None,
@@ -834,6 +854,14 @@ class AsyncAgentClient:
834
854
  agent_id : str
835
855
  The ID of the agent to chat with
836
856
 
857
+ phenoml_on_behalf_of : typing.Optional[str]
858
+ Optional header for on-behalf-of authentication. Used when making requests on behalf of another user or entity.
859
+ Must be in the format: Patient/{uuid} or Practitioner/{uuid}
860
+
861
+ phenoml_fhir_provider : typing.Optional[str]
862
+ Optional header for FHIR provider authentication. Contains credentials in the format {fhir_provider_id}:{oauth2_token}.
863
+ Multiple FHIR provider integrations can be provided as comma-separated values.
864
+
837
865
  context : typing.Optional[str]
838
866
  Optional context for the conversation
839
867
 
@@ -861,6 +889,8 @@ class AsyncAgentClient:
861
889
 
862
890
  async def main() -> None:
863
891
  await client.agent.chat(
892
+ phenoml_on_behalf_of="Patient/550e8400-e29b-41d4-a716-446655440000",
893
+ phenoml_fhir_provider="550e8400-e29b-41d4-a716-446655440000:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c...",
864
894
  message="What is the patient's current condition?",
865
895
  agent_id="agent-123",
866
896
  )
@@ -869,7 +899,13 @@ class AsyncAgentClient:
869
899
  asyncio.run(main())
870
900
  """
871
901
  _response = await self._raw_client.chat(
872
- message=message, agent_id=agent_id, context=context, session_id=session_id, request_options=request_options
902
+ message=message,
903
+ agent_id=agent_id,
904
+ phenoml_on_behalf_of=phenoml_on_behalf_of,
905
+ phenoml_fhir_provider=phenoml_fhir_provider,
906
+ context=context,
907
+ session_id=session_id,
908
+ request_options=request_options,
873
909
  )
874
910
  return _response.data
875
911
 
@@ -650,6 +650,8 @@ class RawAgentClient:
650
650
  *,
651
651
  message: str,
652
652
  agent_id: str,
653
+ phenoml_on_behalf_of: typing.Optional[str] = None,
654
+ phenoml_fhir_provider: typing.Optional[str] = None,
653
655
  context: typing.Optional[str] = OMIT,
654
656
  session_id: typing.Optional[str] = OMIT,
655
657
  request_options: typing.Optional[RequestOptions] = None,
@@ -665,6 +667,14 @@ class RawAgentClient:
665
667
  agent_id : str
666
668
  The ID of the agent to chat with
667
669
 
670
+ phenoml_on_behalf_of : typing.Optional[str]
671
+ Optional header for on-behalf-of authentication. Used when making requests on behalf of another user or entity.
672
+ Must be in the format: Patient/{uuid} or Practitioner/{uuid}
673
+
674
+ phenoml_fhir_provider : typing.Optional[str]
675
+ Optional header for FHIR provider authentication. Contains credentials in the format {fhir_provider_id}:{oauth2_token}.
676
+ Multiple FHIR provider integrations can be provided as comma-separated values.
677
+
668
678
  context : typing.Optional[str]
669
679
  Optional context for the conversation
670
680
 
@@ -690,6 +700,8 @@ class RawAgentClient:
690
700
  },
691
701
  headers={
692
702
  "content-type": "application/json",
703
+ "X-Phenoml-On-Behalf-Of": str(phenoml_on_behalf_of) if phenoml_on_behalf_of is not None else None,
704
+ "X-Phenoml-Fhir-Provider": str(phenoml_fhir_provider) if phenoml_fhir_provider is not None else None,
693
705
  },
694
706
  request_options=request_options,
695
707
  omit=OMIT,
@@ -1471,6 +1483,8 @@ class AsyncRawAgentClient:
1471
1483
  *,
1472
1484
  message: str,
1473
1485
  agent_id: str,
1486
+ phenoml_on_behalf_of: typing.Optional[str] = None,
1487
+ phenoml_fhir_provider: typing.Optional[str] = None,
1474
1488
  context: typing.Optional[str] = OMIT,
1475
1489
  session_id: typing.Optional[str] = OMIT,
1476
1490
  request_options: typing.Optional[RequestOptions] = None,
@@ -1486,6 +1500,14 @@ class AsyncRawAgentClient:
1486
1500
  agent_id : str
1487
1501
  The ID of the agent to chat with
1488
1502
 
1503
+ phenoml_on_behalf_of : typing.Optional[str]
1504
+ Optional header for on-behalf-of authentication. Used when making requests on behalf of another user or entity.
1505
+ Must be in the format: Patient/{uuid} or Practitioner/{uuid}
1506
+
1507
+ phenoml_fhir_provider : typing.Optional[str]
1508
+ Optional header for FHIR provider authentication. Contains credentials in the format {fhir_provider_id}:{oauth2_token}.
1509
+ Multiple FHIR provider integrations can be provided as comma-separated values.
1510
+
1489
1511
  context : typing.Optional[str]
1490
1512
  Optional context for the conversation
1491
1513
 
@@ -1511,6 +1533,8 @@ class AsyncRawAgentClient:
1511
1533
  },
1512
1534
  headers={
1513
1535
  "content-type": "application/json",
1536
+ "X-Phenoml-On-Behalf-Of": str(phenoml_on_behalf_of) if phenoml_on_behalf_of is not None else None,
1537
+ "X-Phenoml-Fhir-Provider": str(phenoml_fhir_provider) if phenoml_fhir_provider is not None else None,
1514
1538
  },
1515
1539
  request_options=request_options,
1516
1540
  omit=OMIT,
phenoml/client.py CHANGED
@@ -35,7 +35,7 @@ class phenoml:
35
35
 
36
36
 
37
37
 
38
- token : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
38
+ token : typing.Union[str, typing.Callable[[], str]]
39
39
  headers : typing.Optional[typing.Dict[str, str]]
40
40
  Additional headers to send with every request.
41
41
 
@@ -62,7 +62,7 @@ class phenoml:
62
62
  *,
63
63
  base_url: typing.Optional[str] = None,
64
64
  environment: phenomlEnvironment = phenomlEnvironment.DEFAULT,
65
- token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
65
+ token: typing.Union[str, typing.Callable[[], str]],
66
66
  headers: typing.Optional[typing.Dict[str, str]] = None,
67
67
  timeout: typing.Optional[float] = None,
68
68
  follow_redirects: typing.Optional[bool] = True,
@@ -112,7 +112,7 @@ class Asyncphenoml:
112
112
 
113
113
 
114
114
 
115
- token : typing.Optional[typing.Union[str, typing.Callable[[], str]]]
115
+ token : typing.Union[str, typing.Callable[[], str]]
116
116
  headers : typing.Optional[typing.Dict[str, str]]
117
117
  Additional headers to send with every request.
118
118
 
@@ -139,7 +139,7 @@ class Asyncphenoml:
139
139
  *,
140
140
  base_url: typing.Optional[str] = None,
141
141
  environment: phenomlEnvironment = phenomlEnvironment.DEFAULT,
142
- token: typing.Optional[typing.Union[str, typing.Callable[[], str]]] = None,
142
+ token: typing.Union[str, typing.Callable[[], str]],
143
143
  headers: typing.Optional[typing.Dict[str, str]] = None,
144
144
  timeout: typing.Optional[float] = None,
145
145
  follow_redirects: typing.Optional[bool] = True,
@@ -3,43 +3,29 @@
3
3
  # isort: skip_file
4
4
 
5
5
  from .types import (
6
- BadRequestErrorBody,
7
- ConstrueCohortRequestConfig,
8
- ConstrueCohortResponse,
9
- ConstrueCohortResponseQueriesItem,
10
- ConstrueCohortResponseQueriesItemCodeExtractResultsItem,
11
- ConstrueCohortResponseQueriesItemCodeExtractResultsItemCodesItem,
12
6
  ConstrueUploadCodeSystemResponse,
13
7
  ExtractCodesResult,
14
8
  ExtractRequestConfig,
15
9
  ExtractRequestConfigChunkingMethod,
10
+ ExtractRequestConfigValidationMethod,
16
11
  ExtractRequestSystem,
17
12
  ExtractedCodeResult,
18
- InternalServerErrorBody,
19
- UnauthorizedErrorBody,
20
13
  UploadRequestFormat,
21
14
  )
22
15
  from .errors import BadRequestError, ConflictError, FailedDependencyError, InternalServerError, UnauthorizedError
23
16
 
24
17
  __all__ = [
25
18
  "BadRequestError",
26
- "BadRequestErrorBody",
27
19
  "ConflictError",
28
- "ConstrueCohortRequestConfig",
29
- "ConstrueCohortResponse",
30
- "ConstrueCohortResponseQueriesItem",
31
- "ConstrueCohortResponseQueriesItemCodeExtractResultsItem",
32
- "ConstrueCohortResponseQueriesItemCodeExtractResultsItemCodesItem",
33
20
  "ConstrueUploadCodeSystemResponse",
34
21
  "ExtractCodesResult",
35
22
  "ExtractRequestConfig",
36
23
  "ExtractRequestConfigChunkingMethod",
24
+ "ExtractRequestConfigValidationMethod",
37
25
  "ExtractRequestSystem",
38
26
  "ExtractedCodeResult",
39
27
  "FailedDependencyError",
40
28
  "InternalServerError",
41
- "InternalServerErrorBody",
42
29
  "UnauthorizedError",
43
- "UnauthorizedErrorBody",
44
30
  "UploadRequestFormat",
45
31
  ]
@@ -5,8 +5,6 @@ import typing
5
5
  from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
6
6
  from ..core.request_options import RequestOptions
7
7
  from .raw_client import AsyncRawConstrueClient, RawConstrueClient
8
- from .types.construe_cohort_request_config import ConstrueCohortRequestConfig
9
- from .types.construe_cohort_response import ConstrueCohortResponse
10
8
  from .types.construe_upload_code_system_response import ConstrueUploadCodeSystemResponse
11
9
  from .types.extract_codes_result import ExtractCodesResult
12
10
  from .types.extract_request_config import ExtractRequestConfig
@@ -155,46 +153,6 @@ class ConstrueClient:
155
153
  )
156
154
  return _response.data
157
155
 
158
- def cohort(
159
- self,
160
- *,
161
- text: str,
162
- config: typing.Optional[ConstrueCohortRequestConfig] = OMIT,
163
- request_options: typing.Optional[RequestOptions] = None,
164
- ) -> ConstrueCohortResponse:
165
- """
166
- Creates a patient cohort based on a natural language description.
167
- Translates the description into FHIR search queries and optional SQL queries.
168
-
169
- Parameters
170
- ----------
171
- text : str
172
- Natural language description of the desired patient cohort.
173
-
174
- config : typing.Optional[ConstrueCohortRequestConfig]
175
-
176
- request_options : typing.Optional[RequestOptions]
177
- Request-specific configuration.
178
-
179
- Returns
180
- -------
181
- ConstrueCohortResponse
182
- Cohort creation successful
183
-
184
- Examples
185
- --------
186
- from phenoml import phenoml
187
-
188
- client = phenoml(
189
- token="YOUR_TOKEN",
190
- )
191
- client.construe.cohort(
192
- text="Between 20 and 40 years old with hyperlipidemia",
193
- )
194
- """
195
- _response = self._raw_client.cohort(text=text, config=config, request_options=request_options)
196
- return _response.data
197
-
198
156
 
199
157
  class AsyncConstrueClient:
200
158
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -349,51 +307,3 @@ class AsyncConstrueClient:
349
307
  text=text, system=system, config=config, request_options=request_options
350
308
  )
351
309
  return _response.data
352
-
353
- async def cohort(
354
- self,
355
- *,
356
- text: str,
357
- config: typing.Optional[ConstrueCohortRequestConfig] = OMIT,
358
- request_options: typing.Optional[RequestOptions] = None,
359
- ) -> ConstrueCohortResponse:
360
- """
361
- Creates a patient cohort based on a natural language description.
362
- Translates the description into FHIR search queries and optional SQL queries.
363
-
364
- Parameters
365
- ----------
366
- text : str
367
- Natural language description of the desired patient cohort.
368
-
369
- config : typing.Optional[ConstrueCohortRequestConfig]
370
-
371
- request_options : typing.Optional[RequestOptions]
372
- Request-specific configuration.
373
-
374
- Returns
375
- -------
376
- ConstrueCohortResponse
377
- Cohort creation successful
378
-
379
- Examples
380
- --------
381
- import asyncio
382
-
383
- from phenoml import Asyncphenoml
384
-
385
- client = Asyncphenoml(
386
- token="YOUR_TOKEN",
387
- )
388
-
389
-
390
- async def main() -> None:
391
- await client.construe.cohort(
392
- text="Between 20 and 40 years old with hyperlipidemia",
393
- )
394
-
395
-
396
- asyncio.run(main())
397
- """
398
- _response = await self._raw_client.cohort(text=text, config=config, request_options=request_options)
399
- return _response.data
@@ -14,8 +14,6 @@ from .errors.conflict_error import ConflictError
14
14
  from .errors.failed_dependency_error import FailedDependencyError
15
15
  from .errors.internal_server_error import InternalServerError
16
16
  from .errors.unauthorized_error import UnauthorizedError
17
- from .types.construe_cohort_request_config import ConstrueCohortRequestConfig
18
- from .types.construe_cohort_response import ConstrueCohortResponse
19
17
  from .types.construe_upload_code_system_response import ConstrueUploadCodeSystemResponse
20
18
  from .types.extract_codes_result import ExtractCodesResult
21
19
  from .types.extract_request_config import ExtractRequestConfig
@@ -276,95 +274,6 @@ class RawConstrueClient:
276
274
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
277
275
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
278
276
 
279
- def cohort(
280
- self,
281
- *,
282
- text: str,
283
- config: typing.Optional[ConstrueCohortRequestConfig] = OMIT,
284
- request_options: typing.Optional[RequestOptions] = None,
285
- ) -> HttpResponse[ConstrueCohortResponse]:
286
- """
287
- Creates a patient cohort based on a natural language description.
288
- Translates the description into FHIR search queries and optional SQL queries.
289
-
290
- Parameters
291
- ----------
292
- text : str
293
- Natural language description of the desired patient cohort.
294
-
295
- config : typing.Optional[ConstrueCohortRequestConfig]
296
-
297
- request_options : typing.Optional[RequestOptions]
298
- Request-specific configuration.
299
-
300
- Returns
301
- -------
302
- HttpResponse[ConstrueCohortResponse]
303
- Cohort creation successful
304
- """
305
- _response = self._client_wrapper.httpx_client.request(
306
- "construe/cohort",
307
- method="POST",
308
- json={
309
- "config": convert_and_respect_annotation_metadata(
310
- object_=config, annotation=ConstrueCohortRequestConfig, direction="write"
311
- ),
312
- "text": text,
313
- },
314
- headers={
315
- "content-type": "application/json",
316
- },
317
- request_options=request_options,
318
- omit=OMIT,
319
- )
320
- try:
321
- if 200 <= _response.status_code < 300:
322
- _data = typing.cast(
323
- ConstrueCohortResponse,
324
- parse_obj_as(
325
- type_=ConstrueCohortResponse, # type: ignore
326
- object_=_response.json(),
327
- ),
328
- )
329
- return HttpResponse(response=_response, data=_data)
330
- if _response.status_code == 400:
331
- raise BadRequestError(
332
- headers=dict(_response.headers),
333
- body=typing.cast(
334
- typing.Optional[typing.Any],
335
- parse_obj_as(
336
- type_=typing.Optional[typing.Any], # type: ignore
337
- object_=_response.json(),
338
- ),
339
- ),
340
- )
341
- if _response.status_code == 401:
342
- raise UnauthorizedError(
343
- headers=dict(_response.headers),
344
- body=typing.cast(
345
- typing.Optional[typing.Any],
346
- parse_obj_as(
347
- type_=typing.Optional[typing.Any], # type: ignore
348
- object_=_response.json(),
349
- ),
350
- ),
351
- )
352
- if _response.status_code == 500:
353
- raise InternalServerError(
354
- headers=dict(_response.headers),
355
- body=typing.cast(
356
- typing.Optional[typing.Any],
357
- parse_obj_as(
358
- type_=typing.Optional[typing.Any], # type: ignore
359
- object_=_response.json(),
360
- ),
361
- ),
362
- )
363
- _response_json = _response.json()
364
- except JSONDecodeError:
365
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
366
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
367
-
368
277
 
369
278
  class AsyncRawConstrueClient:
370
279
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -615,92 +524,3 @@ class AsyncRawConstrueClient:
615
524
  except JSONDecodeError:
616
525
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
617
526
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
618
-
619
- async def cohort(
620
- self,
621
- *,
622
- text: str,
623
- config: typing.Optional[ConstrueCohortRequestConfig] = OMIT,
624
- request_options: typing.Optional[RequestOptions] = None,
625
- ) -> AsyncHttpResponse[ConstrueCohortResponse]:
626
- """
627
- Creates a patient cohort based on a natural language description.
628
- Translates the description into FHIR search queries and optional SQL queries.
629
-
630
- Parameters
631
- ----------
632
- text : str
633
- Natural language description of the desired patient cohort.
634
-
635
- config : typing.Optional[ConstrueCohortRequestConfig]
636
-
637
- request_options : typing.Optional[RequestOptions]
638
- Request-specific configuration.
639
-
640
- Returns
641
- -------
642
- AsyncHttpResponse[ConstrueCohortResponse]
643
- Cohort creation successful
644
- """
645
- _response = await self._client_wrapper.httpx_client.request(
646
- "construe/cohort",
647
- method="POST",
648
- json={
649
- "config": convert_and_respect_annotation_metadata(
650
- object_=config, annotation=ConstrueCohortRequestConfig, direction="write"
651
- ),
652
- "text": text,
653
- },
654
- headers={
655
- "content-type": "application/json",
656
- },
657
- request_options=request_options,
658
- omit=OMIT,
659
- )
660
- try:
661
- if 200 <= _response.status_code < 300:
662
- _data = typing.cast(
663
- ConstrueCohortResponse,
664
- parse_obj_as(
665
- type_=ConstrueCohortResponse, # type: ignore
666
- object_=_response.json(),
667
- ),
668
- )
669
- return AsyncHttpResponse(response=_response, data=_data)
670
- if _response.status_code == 400:
671
- raise BadRequestError(
672
- headers=dict(_response.headers),
673
- body=typing.cast(
674
- typing.Optional[typing.Any],
675
- parse_obj_as(
676
- type_=typing.Optional[typing.Any], # type: ignore
677
- object_=_response.json(),
678
- ),
679
- ),
680
- )
681
- if _response.status_code == 401:
682
- raise UnauthorizedError(
683
- headers=dict(_response.headers),
684
- body=typing.cast(
685
- typing.Optional[typing.Any],
686
- parse_obj_as(
687
- type_=typing.Optional[typing.Any], # type: ignore
688
- object_=_response.json(),
689
- ),
690
- ),
691
- )
692
- if _response.status_code == 500:
693
- raise InternalServerError(
694
- headers=dict(_response.headers),
695
- body=typing.cast(
696
- typing.Optional[typing.Any],
697
- parse_obj_as(
698
- type_=typing.Optional[typing.Any], # type: ignore
699
- object_=_response.json(),
700
- ),
701
- ),
702
- )
703
- _response_json = _response.json()
704
- except JSONDecodeError:
705
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
706
- raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -2,40 +2,22 @@
2
2
 
3
3
  # isort: skip_file
4
4
 
5
- from .bad_request_error_body import BadRequestErrorBody
6
- from .construe_cohort_request_config import ConstrueCohortRequestConfig
7
- from .construe_cohort_response import ConstrueCohortResponse
8
- from .construe_cohort_response_queries_item import ConstrueCohortResponseQueriesItem
9
- from .construe_cohort_response_queries_item_code_extract_results_item import (
10
- ConstrueCohortResponseQueriesItemCodeExtractResultsItem,
11
- )
12
- from .construe_cohort_response_queries_item_code_extract_results_item_codes_item import (
13
- ConstrueCohortResponseQueriesItemCodeExtractResultsItemCodesItem,
14
- )
15
5
  from .construe_upload_code_system_response import ConstrueUploadCodeSystemResponse
16
6
  from .extract_codes_result import ExtractCodesResult
17
7
  from .extract_request_config import ExtractRequestConfig
18
8
  from .extract_request_config_chunking_method import ExtractRequestConfigChunkingMethod
9
+ from .extract_request_config_validation_method import ExtractRequestConfigValidationMethod
19
10
  from .extract_request_system import ExtractRequestSystem
20
11
  from .extracted_code_result import ExtractedCodeResult
21
- from .internal_server_error_body import InternalServerErrorBody
22
- from .unauthorized_error_body import UnauthorizedErrorBody
23
12
  from .upload_request_format import UploadRequestFormat
24
13
 
25
14
  __all__ = [
26
- "BadRequestErrorBody",
27
- "ConstrueCohortRequestConfig",
28
- "ConstrueCohortResponse",
29
- "ConstrueCohortResponseQueriesItem",
30
- "ConstrueCohortResponseQueriesItemCodeExtractResultsItem",
31
- "ConstrueCohortResponseQueriesItemCodeExtractResultsItemCodesItem",
32
15
  "ConstrueUploadCodeSystemResponse",
33
16
  "ExtractCodesResult",
34
17
  "ExtractRequestConfig",
35
18
  "ExtractRequestConfigChunkingMethod",
19
+ "ExtractRequestConfigValidationMethod",
36
20
  "ExtractRequestSystem",
37
21
  "ExtractedCodeResult",
38
- "InternalServerErrorBody",
39
- "UnauthorizedErrorBody",
40
22
  "UploadRequestFormat",
41
23
  ]
@@ -5,13 +5,42 @@ import typing
5
5
  import pydantic
6
6
  from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel
7
7
  from .extract_request_config_chunking_method import ExtractRequestConfigChunkingMethod
8
+ from .extract_request_config_validation_method import ExtractRequestConfigValidationMethod
8
9
 
9
10
 
10
11
  class ExtractRequestConfig(UniversalBaseModel):
11
- chunking_method: typing.Optional[ExtractRequestConfigChunkingMethod] = None
12
- max_codes_per_chunk: typing.Optional[int] = None
13
- code_similarity_filter: typing.Optional[float] = None
14
- include_rationale: typing.Optional[bool] = None
12
+ chunking_method: typing.Optional[ExtractRequestConfigChunkingMethod] = pydantic.Field(default=None)
13
+ """
14
+ Method for splitting input text into chunks before code extraction
15
+ """
16
+
17
+ max_codes_per_chunk: typing.Optional[int] = pydantic.Field(default=None)
18
+ """
19
+ Maximum number of codes to extract per chunk
20
+ """
21
+
22
+ code_similarity_filter: typing.Optional[float] = pydantic.Field(default=None)
23
+ """
24
+ Threshold for filtering similar codes (0.0-1.0)
25
+ """
26
+
27
+ validation_method: typing.Optional[ExtractRequestConfigValidationMethod] = pydantic.Field(default=None)
28
+ """
29
+ Method for validating extracted codes:
30
+ * none - No validation, returns all candidate codes
31
+ * simple - LLM-based validation
32
+ * medication_search - LLM-based validation tailored for medication concepts
33
+ """
34
+
35
+ include_rationale: typing.Optional[bool] = pydantic.Field(default=None)
36
+ """
37
+ Whether to include explanations for why each code was extracted
38
+ """
39
+
40
+ include_ancestors: typing.Optional[bool] = pydantic.Field(default=None)
41
+ """
42
+ Whether to include ancestor/parent codes in the results
43
+ """
15
44
 
16
45
  if IS_PYDANTIC_V2:
17
46
  model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
@@ -2,4 +2,6 @@
2
2
 
3
3
  import typing
4
4
 
5
- ExtractRequestConfigChunkingMethod = typing.Union[typing.Literal["none", "sentence", "paragraph", "topics"], typing.Any]
5
+ ExtractRequestConfigChunkingMethod = typing.Union[
6
+ typing.Literal["none", "sentences", "paragraphs", "topics"], typing.Any
7
+ ]
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ ExtractRequestConfigValidationMethod = typing.Union[typing.Literal["none", "simple", "medication_search"], typing.Any]
@@ -17,6 +17,8 @@ class ExtractRequestSystem(UniversalBaseModel):
17
17
  * ICD-10-CM - version 2025
18
18
  * ICD-10-PCS - version 2025
19
19
  * LOINC - version 2.78
20
+ * HPO - version 2025
21
+ * CPT - version 2025
20
22
 
21
23
  Custom systems:
22
24
  * Any valid system name configured in your environment. Must have self-hosted construe module.