samplehc 0.14.0__py3-none-any.whl → 0.16.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. samplehc/_base_client.py +140 -11
  2. samplehc/_client.py +107 -35
  3. samplehc/_models.py +53 -16
  4. samplehc/_streaming.py +12 -12
  5. samplehc/_types.py +12 -2
  6. samplehc/_utils/_sync.py +3 -31
  7. samplehc/_utils/_utils.py +1 -1
  8. samplehc/_version.py +1 -1
  9. samplehc/resources/v2/__init__.py +0 -42
  10. samplehc/resources/v2/communication.py +5 -4
  11. samplehc/resources/v2/documents/documents.py +8 -0
  12. samplehc/resources/v2/tasks/tasks.py +12 -3
  13. samplehc/resources/v2/v2.py +0 -96
  14. samplehc/types/v1_query_audit_logs_response.py +4 -0
  15. samplehc/types/v2/__init__.py +1 -2
  16. samplehc/types/v2/clearinghouse/claim_submit_response.py +5 -0
  17. samplehc/types/v2/clearinghouse/payer_list_response.py +2 -0
  18. samplehc/types/v2/clearinghouse/payer_search_response.py +2 -0
  19. samplehc/types/v2/clearinghouse_check_eligibility_response.py +4 -0
  20. samplehc/types/v2/clearinghouse_run_discovery_response.py +2 -0
  21. samplehc/types/v2/communication_send_email_response.py +27 -0
  22. samplehc/types/v2/communication_send_fax_params.py +2 -0
  23. samplehc/types/v2/communication_send_fax_response.py +2 -0
  24. samplehc/types/v2/communication_send_letter_params.py +8 -0
  25. samplehc/types/v2/communication_send_letter_response.py +2 -0
  26. samplehc/types/v2/database_execute_sql_response.py +2 -0
  27. samplehc/types/v2/document_classify_params.py +2 -0
  28. samplehc/types/v2/document_classify_response.py +2 -0
  29. samplehc/types/v2/document_combine_response.py +4 -0
  30. samplehc/types/v2/document_create_from_splits_params.py +2 -0
  31. samplehc/types/v2/document_create_from_splits_response.py +2 -0
  32. samplehc/types/v2/document_extract_params.py +40 -3
  33. samplehc/types/v2/document_extract_response.py +2 -0
  34. samplehc/types/v2/document_generate_csv_response.py +4 -0
  35. samplehc/types/v2/document_presigned_upload_url_response.py +2 -0
  36. samplehc/types/v2/document_retrieve_csv_content_response.py +2 -0
  37. samplehc/types/v2/document_retrieve_metadata_response.py +2 -0
  38. samplehc/types/v2/document_search_response.py +2 -0
  39. samplehc/types/v2/document_split_params.py +2 -0
  40. samplehc/types/v2/document_split_response.py +2 -0
  41. samplehc/types/v2/documents/format_create_pdf_response.py +2 -0
  42. samplehc/types/v2/documents/legacy_extract_response.py +2 -0
  43. samplehc/types/v2/documents/legacy_reason_response.py +2 -0
  44. samplehc/types/v2/documents/legacy_split_params.py +2 -0
  45. samplehc/types/v2/documents/legacy_split_response.py +2 -0
  46. samplehc/types/v2/documents/pdf_template_retrieve_metadata_response.py +2 -0
  47. samplehc/types/v2/documents/template_render_document_response.py +2 -0
  48. samplehc/types/v2/hie/document_upload_params.py +2 -0
  49. samplehc/types/v2/integrations/glidian/prior_authorization_create_draft_response.py +2 -0
  50. samplehc/types/v2/integrations/glidian/prior_authorization_retrieve_record_response.py +2 -0
  51. samplehc/types/v2/integrations/glidian/prior_authorization_submit_response.py +2 -0
  52. samplehc/types/v2/integrations/glidian/prior_authorization_update_record_response.py +2 -0
  53. samplehc/types/v2/integrations/glidian/prior_authorizations/clinical_question_list_response.py +2 -0
  54. samplehc/types/v2/integrations/glidian/prior_authorizations/clinical_question_update_response.py +2 -0
  55. samplehc/types/v2/integrations/kno2/message_get_attachment_response.py +2 -0
  56. samplehc/types/v2/integrations/kno2/message_retrieve_response.py +2 -0
  57. samplehc/types/v2/ledger/__init__.py +0 -7
  58. samplehc/types/v2/policy_list_companies_response.py +2 -0
  59. samplehc/types/v2/policy_list_plans_response.py +2 -0
  60. samplehc/types/v2/policy_list_response.py +2 -0
  61. samplehc/types/v2/policy_retrieve_presigned_url_response.py +2 -0
  62. samplehc/types/v2/policy_retrieve_text_response.py +2 -0
  63. samplehc/types/v2/task_cancel_response.py +2 -0
  64. samplehc/types/v2/task_complete_response.py +2 -0
  65. samplehc/types/v2/task_update_column_params.py +6 -3
  66. samplehc/types/v2/workflow_run_resume_when_complete_response.py +2 -0
  67. samplehc/types/v2/workflow_run_retrieve_response.py +2 -0
  68. samplehc/types/v2/workflow_runs/step_get_output_response.py +2 -0
  69. samplehc/types/v2/workflow_start_response.py +2 -0
  70. {samplehc-0.14.0.dist-info → samplehc-0.16.0.dist-info}/METADATA +7 -6
  71. {samplehc-0.14.0.dist-info → samplehc-0.16.0.dist-info}/RECORD +73 -101
  72. {samplehc-0.14.0.dist-info → samplehc-0.16.0.dist-info}/licenses/LICENSE +1 -1
  73. samplehc/resources/v2/browser_agents/__init__.py +0 -33
  74. samplehc/resources/v2/browser_agents/browser_agents.py +0 -209
  75. samplehc/resources/v2/browser_agents/runs/__init__.py +0 -33
  76. samplehc/resources/v2/browser_agents/runs/help_requests.py +0 -191
  77. samplehc/resources/v2/browser_agents/runs/runs.py +0 -233
  78. samplehc/resources/v2/browser_automation/__init__.py +0 -33
  79. samplehc/resources/v2/browser_automation/availity.py +0 -249
  80. samplehc/resources/v2/browser_automation/browser_automation.py +0 -102
  81. samplehc/resources/v2/ledger/__init__.py +0 -47
  82. samplehc/resources/v2/ledger/account.py +0 -297
  83. samplehc/resources/v2/ledger/entry.py +0 -381
  84. samplehc/resources/v2/ledger/ledger.py +0 -134
  85. samplehc/types/v2/browser_agent_invoke_params.py +0 -13
  86. samplehc/types/v2/browser_agent_invoke_response.py +0 -15
  87. samplehc/types/v2/browser_agents/__init__.py +0 -6
  88. samplehc/types/v2/browser_agents/run_list_events_params.py +0 -15
  89. samplehc/types/v2/browser_agents/run_list_events_response.py +0 -30
  90. samplehc/types/v2/browser_agents/runs/__init__.py +0 -6
  91. samplehc/types/v2/browser_agents/runs/help_request_resolve_params.py +0 -18
  92. samplehc/types/v2/browser_agents/runs/help_request_resolve_response.py +0 -28
  93. samplehc/types/v2/browser_automation/__init__.py +0 -6
  94. samplehc/types/v2/browser_automation/availity_submit_appeal_params.py +0 -59
  95. samplehc/types/v2/browser_automation/availity_submit_appeal_response.py +0 -12
  96. samplehc/types/v2/ledger/account_writeoff_params.py +0 -23
  97. samplehc/types/v2/ledger/account_writeoff_response.py +0 -12
  98. samplehc/types/v2/ledger/entry_post_params.py +0 -60
  99. samplehc/types/v2/ledger/entry_post_response.py +0 -10
  100. samplehc/types/v2/ledger/entry_reverse_params.py +0 -18
  101. samplehc/types/v2/ledger/entry_reverse_response.py +0 -10
  102. {samplehc-0.14.0.dist-info → samplehc-0.16.0.dist-info}/WHEEL +0 -0
samplehc/_base_client.py CHANGED
@@ -9,6 +9,7 @@ import asyncio
9
9
  import inspect
10
10
  import logging
11
11
  import platform
12
+ import warnings
12
13
  import email.utils
13
14
  from types import TracebackType
14
15
  from random import random
@@ -51,9 +52,11 @@ from ._types import (
51
52
  ResponseT,
52
53
  AnyMapping,
53
54
  PostParser,
55
+ BinaryTypes,
54
56
  RequestFiles,
55
57
  HttpxSendArgs,
56
58
  RequestOptions,
59
+ AsyncBinaryTypes,
57
60
  HttpxRequestFiles,
58
61
  ModelBuilderProtocol,
59
62
  not_given,
@@ -477,8 +480,19 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
477
480
  retries_taken: int = 0,
478
481
  ) -> httpx.Request:
479
482
  if log.isEnabledFor(logging.DEBUG):
480
- log.debug("Request options: %s", model_dump(options, exclude_unset=True))
481
-
483
+ log.debug(
484
+ "Request options: %s",
485
+ model_dump(
486
+ options,
487
+ exclude_unset=True,
488
+ # Pydantic v1 can't dump every type we support in content, so we exclude it for now.
489
+ exclude={
490
+ "content",
491
+ }
492
+ if PYDANTIC_V1
493
+ else {},
494
+ ),
495
+ )
482
496
  kwargs: dict[str, Any] = {}
483
497
 
484
498
  json_data = options.json_data
@@ -532,7 +546,13 @@ class BaseClient(Generic[_HttpxClientT, _DefaultStreamT]):
532
546
  is_body_allowed = options.method.lower() != "get"
533
547
 
534
548
  if is_body_allowed:
535
- if isinstance(json_data, bytes):
549
+ if options.content is not None and json_data is not None:
550
+ raise TypeError("Passing both `content` and `json_data` is not supported")
551
+ if options.content is not None and files is not None:
552
+ raise TypeError("Passing both `content` and `files` is not supported")
553
+ if options.content is not None:
554
+ kwargs["content"] = options.content
555
+ elif isinstance(json_data, bytes):
536
556
  kwargs["content"] = json_data
537
557
  else:
538
558
  kwargs["json"] = json_data if is_given(json_data) else None
@@ -1194,6 +1214,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1194
1214
  *,
1195
1215
  cast_to: Type[ResponseT],
1196
1216
  body: Body | None = None,
1217
+ content: BinaryTypes | None = None,
1197
1218
  options: RequestOptions = {},
1198
1219
  files: RequestFiles | None = None,
1199
1220
  stream: Literal[False] = False,
@@ -1206,6 +1227,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1206
1227
  *,
1207
1228
  cast_to: Type[ResponseT],
1208
1229
  body: Body | None = None,
1230
+ content: BinaryTypes | None = None,
1209
1231
  options: RequestOptions = {},
1210
1232
  files: RequestFiles | None = None,
1211
1233
  stream: Literal[True],
@@ -1219,6 +1241,7 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1219
1241
  *,
1220
1242
  cast_to: Type[ResponseT],
1221
1243
  body: Body | None = None,
1244
+ content: BinaryTypes | None = None,
1222
1245
  options: RequestOptions = {},
1223
1246
  files: RequestFiles | None = None,
1224
1247
  stream: bool,
@@ -1231,13 +1254,25 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1231
1254
  *,
1232
1255
  cast_to: Type[ResponseT],
1233
1256
  body: Body | None = None,
1257
+ content: BinaryTypes | None = None,
1234
1258
  options: RequestOptions = {},
1235
1259
  files: RequestFiles | None = None,
1236
1260
  stream: bool = False,
1237
1261
  stream_cls: type[_StreamT] | None = None,
1238
1262
  ) -> ResponseT | _StreamT:
1263
+ if body is not None and content is not None:
1264
+ raise TypeError("Passing both `body` and `content` is not supported")
1265
+ if files is not None and content is not None:
1266
+ raise TypeError("Passing both `files` and `content` is not supported")
1267
+ if isinstance(body, bytes):
1268
+ warnings.warn(
1269
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1270
+ "Please pass raw bytes via the `content` parameter instead.",
1271
+ DeprecationWarning,
1272
+ stacklevel=2,
1273
+ )
1239
1274
  opts = FinalRequestOptions.construct(
1240
- method="post", url=path, json_data=body, files=to_httpx_files(files), **options
1275
+ method="post", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
1241
1276
  )
1242
1277
  return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
1243
1278
 
@@ -1247,9 +1282,24 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1247
1282
  *,
1248
1283
  cast_to: Type[ResponseT],
1249
1284
  body: Body | None = None,
1285
+ content: BinaryTypes | None = None,
1286
+ files: RequestFiles | None = None,
1250
1287
  options: RequestOptions = {},
1251
1288
  ) -> ResponseT:
1252
- opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options)
1289
+ if body is not None and content is not None:
1290
+ raise TypeError("Passing both `body` and `content` is not supported")
1291
+ if files is not None and content is not None:
1292
+ raise TypeError("Passing both `files` and `content` is not supported")
1293
+ if isinstance(body, bytes):
1294
+ warnings.warn(
1295
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1296
+ "Please pass raw bytes via the `content` parameter instead.",
1297
+ DeprecationWarning,
1298
+ stacklevel=2,
1299
+ )
1300
+ opts = FinalRequestOptions.construct(
1301
+ method="patch", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
1302
+ )
1253
1303
  return self.request(cast_to, opts)
1254
1304
 
1255
1305
  def put(
@@ -1258,11 +1308,23 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1258
1308
  *,
1259
1309
  cast_to: Type[ResponseT],
1260
1310
  body: Body | None = None,
1311
+ content: BinaryTypes | None = None,
1261
1312
  files: RequestFiles | None = None,
1262
1313
  options: RequestOptions = {},
1263
1314
  ) -> ResponseT:
1315
+ if body is not None and content is not None:
1316
+ raise TypeError("Passing both `body` and `content` is not supported")
1317
+ if files is not None and content is not None:
1318
+ raise TypeError("Passing both `files` and `content` is not supported")
1319
+ if isinstance(body, bytes):
1320
+ warnings.warn(
1321
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1322
+ "Please pass raw bytes via the `content` parameter instead.",
1323
+ DeprecationWarning,
1324
+ stacklevel=2,
1325
+ )
1264
1326
  opts = FinalRequestOptions.construct(
1265
- method="put", url=path, json_data=body, files=to_httpx_files(files), **options
1327
+ method="put", url=path, json_data=body, content=content, files=to_httpx_files(files), **options
1266
1328
  )
1267
1329
  return self.request(cast_to, opts)
1268
1330
 
@@ -1272,9 +1334,19 @@ class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
1272
1334
  *,
1273
1335
  cast_to: Type[ResponseT],
1274
1336
  body: Body | None = None,
1337
+ content: BinaryTypes | None = None,
1275
1338
  options: RequestOptions = {},
1276
1339
  ) -> ResponseT:
1277
- opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
1340
+ if body is not None and content is not None:
1341
+ raise TypeError("Passing both `body` and `content` is not supported")
1342
+ if isinstance(body, bytes):
1343
+ warnings.warn(
1344
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1345
+ "Please pass raw bytes via the `content` parameter instead.",
1346
+ DeprecationWarning,
1347
+ stacklevel=2,
1348
+ )
1349
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
1278
1350
  return self.request(cast_to, opts)
1279
1351
 
1280
1352
  def get_api_list(
@@ -1714,6 +1786,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1714
1786
  *,
1715
1787
  cast_to: Type[ResponseT],
1716
1788
  body: Body | None = None,
1789
+ content: AsyncBinaryTypes | None = None,
1717
1790
  files: RequestFiles | None = None,
1718
1791
  options: RequestOptions = {},
1719
1792
  stream: Literal[False] = False,
@@ -1726,6 +1799,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1726
1799
  *,
1727
1800
  cast_to: Type[ResponseT],
1728
1801
  body: Body | None = None,
1802
+ content: AsyncBinaryTypes | None = None,
1729
1803
  files: RequestFiles | None = None,
1730
1804
  options: RequestOptions = {},
1731
1805
  stream: Literal[True],
@@ -1739,6 +1813,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1739
1813
  *,
1740
1814
  cast_to: Type[ResponseT],
1741
1815
  body: Body | None = None,
1816
+ content: AsyncBinaryTypes | None = None,
1742
1817
  files: RequestFiles | None = None,
1743
1818
  options: RequestOptions = {},
1744
1819
  stream: bool,
@@ -1751,13 +1826,25 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1751
1826
  *,
1752
1827
  cast_to: Type[ResponseT],
1753
1828
  body: Body | None = None,
1829
+ content: AsyncBinaryTypes | None = None,
1754
1830
  files: RequestFiles | None = None,
1755
1831
  options: RequestOptions = {},
1756
1832
  stream: bool = False,
1757
1833
  stream_cls: type[_AsyncStreamT] | None = None,
1758
1834
  ) -> ResponseT | _AsyncStreamT:
1835
+ if body is not None and content is not None:
1836
+ raise TypeError("Passing both `body` and `content` is not supported")
1837
+ if files is not None and content is not None:
1838
+ raise TypeError("Passing both `files` and `content` is not supported")
1839
+ if isinstance(body, bytes):
1840
+ warnings.warn(
1841
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1842
+ "Please pass raw bytes via the `content` parameter instead.",
1843
+ DeprecationWarning,
1844
+ stacklevel=2,
1845
+ )
1759
1846
  opts = FinalRequestOptions.construct(
1760
- method="post", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1847
+ method="post", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
1761
1848
  )
1762
1849
  return await self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)
1763
1850
 
@@ -1767,9 +1854,29 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1767
1854
  *,
1768
1855
  cast_to: Type[ResponseT],
1769
1856
  body: Body | None = None,
1857
+ content: AsyncBinaryTypes | None = None,
1858
+ files: RequestFiles | None = None,
1770
1859
  options: RequestOptions = {},
1771
1860
  ) -> ResponseT:
1772
- opts = FinalRequestOptions.construct(method="patch", url=path, json_data=body, **options)
1861
+ if body is not None and content is not None:
1862
+ raise TypeError("Passing both `body` and `content` is not supported")
1863
+ if files is not None and content is not None:
1864
+ raise TypeError("Passing both `files` and `content` is not supported")
1865
+ if isinstance(body, bytes):
1866
+ warnings.warn(
1867
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1868
+ "Please pass raw bytes via the `content` parameter instead.",
1869
+ DeprecationWarning,
1870
+ stacklevel=2,
1871
+ )
1872
+ opts = FinalRequestOptions.construct(
1873
+ method="patch",
1874
+ url=path,
1875
+ json_data=body,
1876
+ content=content,
1877
+ files=await async_to_httpx_files(files),
1878
+ **options,
1879
+ )
1773
1880
  return await self.request(cast_to, opts)
1774
1881
 
1775
1882
  async def put(
@@ -1778,11 +1885,23 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1778
1885
  *,
1779
1886
  cast_to: Type[ResponseT],
1780
1887
  body: Body | None = None,
1888
+ content: AsyncBinaryTypes | None = None,
1781
1889
  files: RequestFiles | None = None,
1782
1890
  options: RequestOptions = {},
1783
1891
  ) -> ResponseT:
1892
+ if body is not None and content is not None:
1893
+ raise TypeError("Passing both `body` and `content` is not supported")
1894
+ if files is not None and content is not None:
1895
+ raise TypeError("Passing both `files` and `content` is not supported")
1896
+ if isinstance(body, bytes):
1897
+ warnings.warn(
1898
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1899
+ "Please pass raw bytes via the `content` parameter instead.",
1900
+ DeprecationWarning,
1901
+ stacklevel=2,
1902
+ )
1784
1903
  opts = FinalRequestOptions.construct(
1785
- method="put", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1904
+ method="put", url=path, json_data=body, content=content, files=await async_to_httpx_files(files), **options
1786
1905
  )
1787
1906
  return await self.request(cast_to, opts)
1788
1907
 
@@ -1792,9 +1911,19 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1792
1911
  *,
1793
1912
  cast_to: Type[ResponseT],
1794
1913
  body: Body | None = None,
1914
+ content: AsyncBinaryTypes | None = None,
1795
1915
  options: RequestOptions = {},
1796
1916
  ) -> ResponseT:
1797
- opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, **options)
1917
+ if body is not None and content is not None:
1918
+ raise TypeError("Passing both `body` and `content` is not supported")
1919
+ if isinstance(body, bytes):
1920
+ warnings.warn(
1921
+ "Passing raw bytes as `body` is deprecated and will be removed in a future version. "
1922
+ "Please pass raw bytes via the `content` parameter instead.",
1923
+ DeprecationWarning,
1924
+ stacklevel=2,
1925
+ )
1926
+ opts = FinalRequestOptions.construct(method="delete", url=path, json_data=body, content=content, **options)
1798
1927
  return await self.request(cast_to, opts)
1799
1928
 
1800
1929
  def get_api_list(
samplehc/_client.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from typing import Any, Mapping
6
+ from typing import TYPE_CHECKING, Any, Mapping
7
7
  from typing_extensions import Self, override
8
8
 
9
9
  import httpx
@@ -21,6 +21,7 @@ from ._types import (
21
21
  not_given,
22
22
  )
23
23
  from ._utils import is_given, get_async_library
24
+ from ._compat import cached_property
24
25
  from ._version import __version__
25
26
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
26
27
  from ._exceptions import APIStatusError
@@ -29,8 +30,11 @@ from ._base_client import (
29
30
  SyncAPIClient,
30
31
  AsyncAPIClient,
31
32
  )
32
- from .resources.v1 import v1
33
- from .resources.v2 import v2
33
+
34
+ if TYPE_CHECKING:
35
+ from .resources import v1, v2
36
+ from .resources.v1.v1 import V1Resource, AsyncV1Resource
37
+ from .resources.v2.v2 import V2Resource, AsyncV2Resource
34
38
 
35
39
  __all__ = [
36
40
  "Timeout",
@@ -45,11 +49,6 @@ __all__ = [
45
49
 
46
50
 
47
51
  class SampleHealthcare(SyncAPIClient):
48
- v1: v1.V1Resource
49
- v2: v2.V2Resource
50
- with_raw_response: SampleHealthcareWithRawResponse
51
- with_streaming_response: SampleHealthcareWithStreamedResponse
52
-
53
52
  # client options
54
53
  api_key: str | None
55
54
 
@@ -100,10 +99,25 @@ class SampleHealthcare(SyncAPIClient):
100
99
  _strict_response_validation=_strict_response_validation,
101
100
  )
102
101
 
103
- self.v1 = v1.V1Resource(self)
104
- self.v2 = v2.V2Resource(self)
105
- self.with_raw_response = SampleHealthcareWithRawResponse(self)
106
- self.with_streaming_response = SampleHealthcareWithStreamedResponse(self)
102
+ @cached_property
103
+ def v1(self) -> V1Resource:
104
+ from .resources.v1 import V1Resource
105
+
106
+ return V1Resource(self)
107
+
108
+ @cached_property
109
+ def v2(self) -> V2Resource:
110
+ from .resources.v2 import V2Resource
111
+
112
+ return V2Resource(self)
113
+
114
+ @cached_property
115
+ def with_raw_response(self) -> SampleHealthcareWithRawResponse:
116
+ return SampleHealthcareWithRawResponse(self)
117
+
118
+ @cached_property
119
+ def with_streaming_response(self) -> SampleHealthcareWithStreamedResponse:
120
+ return SampleHealthcareWithStreamedResponse(self)
107
121
 
108
122
  @property
109
123
  @override
@@ -129,9 +143,7 @@ class SampleHealthcare(SyncAPIClient):
129
143
 
130
144
  @override
131
145
  def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
132
- if self.api_key and headers.get("Authorization"):
133
- return
134
- if isinstance(custom_headers.get("Authorization"), Omit):
146
+ if headers.get("Authorization") or isinstance(custom_headers.get("Authorization"), Omit):
135
147
  return
136
148
 
137
149
  raise TypeError(
@@ -224,11 +236,6 @@ class SampleHealthcare(SyncAPIClient):
224
236
 
225
237
 
226
238
  class AsyncSampleHealthcare(AsyncAPIClient):
227
- v1: v1.AsyncV1Resource
228
- v2: v2.AsyncV2Resource
229
- with_raw_response: AsyncSampleHealthcareWithRawResponse
230
- with_streaming_response: AsyncSampleHealthcareWithStreamedResponse
231
-
232
239
  # client options
233
240
  api_key: str | None
234
241
 
@@ -279,10 +286,25 @@ class AsyncSampleHealthcare(AsyncAPIClient):
279
286
  _strict_response_validation=_strict_response_validation,
280
287
  )
281
288
 
282
- self.v1 = v1.AsyncV1Resource(self)
283
- self.v2 = v2.AsyncV2Resource(self)
284
- self.with_raw_response = AsyncSampleHealthcareWithRawResponse(self)
285
- self.with_streaming_response = AsyncSampleHealthcareWithStreamedResponse(self)
289
+ @cached_property
290
+ def v1(self) -> AsyncV1Resource:
291
+ from .resources.v1 import AsyncV1Resource
292
+
293
+ return AsyncV1Resource(self)
294
+
295
+ @cached_property
296
+ def v2(self) -> AsyncV2Resource:
297
+ from .resources.v2 import AsyncV2Resource
298
+
299
+ return AsyncV2Resource(self)
300
+
301
+ @cached_property
302
+ def with_raw_response(self) -> AsyncSampleHealthcareWithRawResponse:
303
+ return AsyncSampleHealthcareWithRawResponse(self)
304
+
305
+ @cached_property
306
+ def with_streaming_response(self) -> AsyncSampleHealthcareWithStreamedResponse:
307
+ return AsyncSampleHealthcareWithStreamedResponse(self)
286
308
 
287
309
  @property
288
310
  @override
@@ -308,9 +330,7 @@ class AsyncSampleHealthcare(AsyncAPIClient):
308
330
 
309
331
  @override
310
332
  def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
311
- if self.api_key and headers.get("Authorization"):
312
- return
313
- if isinstance(custom_headers.get("Authorization"), Omit):
333
+ if headers.get("Authorization") or isinstance(custom_headers.get("Authorization"), Omit):
314
334
  return
315
335
 
316
336
  raise TypeError(
@@ -403,27 +423,79 @@ class AsyncSampleHealthcare(AsyncAPIClient):
403
423
 
404
424
 
405
425
  class SampleHealthcareWithRawResponse:
426
+ _client: SampleHealthcare
427
+
406
428
  def __init__(self, client: SampleHealthcare) -> None:
407
- self.v1 = v1.V1ResourceWithRawResponse(client.v1)
408
- self.v2 = v2.V2ResourceWithRawResponse(client.v2)
429
+ self._client = client
430
+
431
+ @cached_property
432
+ def v1(self) -> v1.V1ResourceWithRawResponse:
433
+ from .resources.v1 import V1ResourceWithRawResponse
434
+
435
+ return V1ResourceWithRawResponse(self._client.v1)
436
+
437
+ @cached_property
438
+ def v2(self) -> v2.V2ResourceWithRawResponse:
439
+ from .resources.v2 import V2ResourceWithRawResponse
440
+
441
+ return V2ResourceWithRawResponse(self._client.v2)
409
442
 
410
443
 
411
444
  class AsyncSampleHealthcareWithRawResponse:
445
+ _client: AsyncSampleHealthcare
446
+
412
447
  def __init__(self, client: AsyncSampleHealthcare) -> None:
413
- self.v1 = v1.AsyncV1ResourceWithRawResponse(client.v1)
414
- self.v2 = v2.AsyncV2ResourceWithRawResponse(client.v2)
448
+ self._client = client
449
+
450
+ @cached_property
451
+ def v1(self) -> v1.AsyncV1ResourceWithRawResponse:
452
+ from .resources.v1 import AsyncV1ResourceWithRawResponse
453
+
454
+ return AsyncV1ResourceWithRawResponse(self._client.v1)
455
+
456
+ @cached_property
457
+ def v2(self) -> v2.AsyncV2ResourceWithRawResponse:
458
+ from .resources.v2 import AsyncV2ResourceWithRawResponse
459
+
460
+ return AsyncV2ResourceWithRawResponse(self._client.v2)
415
461
 
416
462
 
417
463
  class SampleHealthcareWithStreamedResponse:
464
+ _client: SampleHealthcare
465
+
418
466
  def __init__(self, client: SampleHealthcare) -> None:
419
- self.v1 = v1.V1ResourceWithStreamingResponse(client.v1)
420
- self.v2 = v2.V2ResourceWithStreamingResponse(client.v2)
467
+ self._client = client
468
+
469
+ @cached_property
470
+ def v1(self) -> v1.V1ResourceWithStreamingResponse:
471
+ from .resources.v1 import V1ResourceWithStreamingResponse
472
+
473
+ return V1ResourceWithStreamingResponse(self._client.v1)
474
+
475
+ @cached_property
476
+ def v2(self) -> v2.V2ResourceWithStreamingResponse:
477
+ from .resources.v2 import V2ResourceWithStreamingResponse
478
+
479
+ return V2ResourceWithStreamingResponse(self._client.v2)
421
480
 
422
481
 
423
482
  class AsyncSampleHealthcareWithStreamedResponse:
483
+ _client: AsyncSampleHealthcare
484
+
424
485
  def __init__(self, client: AsyncSampleHealthcare) -> None:
425
- self.v1 = v1.AsyncV1ResourceWithStreamingResponse(client.v1)
426
- self.v2 = v2.AsyncV2ResourceWithStreamingResponse(client.v2)
486
+ self._client = client
487
+
488
+ @cached_property
489
+ def v1(self) -> v1.AsyncV1ResourceWithStreamingResponse:
490
+ from .resources.v1 import AsyncV1ResourceWithStreamingResponse
491
+
492
+ return AsyncV1ResourceWithStreamingResponse(self._client.v1)
493
+
494
+ @cached_property
495
+ def v2(self) -> v2.AsyncV2ResourceWithStreamingResponse:
496
+ from .resources.v2 import AsyncV2ResourceWithStreamingResponse
497
+
498
+ return AsyncV2ResourceWithStreamingResponse(self._client.v2)
427
499
 
428
500
 
429
501
  Client = SampleHealthcare
samplehc/_models.py CHANGED
@@ -2,7 +2,21 @@ from __future__ import annotations
2
2
 
3
3
  import os
4
4
  import inspect
5
- from typing import TYPE_CHECKING, Any, Type, Union, Generic, TypeVar, Callable, Optional, cast
5
+ import weakref
6
+ from typing import (
7
+ IO,
8
+ TYPE_CHECKING,
9
+ Any,
10
+ Type,
11
+ Union,
12
+ Generic,
13
+ TypeVar,
14
+ Callable,
15
+ Iterable,
16
+ Optional,
17
+ AsyncIterable,
18
+ cast,
19
+ )
6
20
  from datetime import date, datetime
7
21
  from typing_extensions import (
8
22
  List,
@@ -256,15 +270,16 @@ class BaseModel(pydantic.BaseModel):
256
270
  mode: Literal["json", "python"] | str = "python",
257
271
  include: IncEx | None = None,
258
272
  exclude: IncEx | None = None,
273
+ context: Any | None = None,
259
274
  by_alias: bool | None = None,
260
275
  exclude_unset: bool = False,
261
276
  exclude_defaults: bool = False,
262
277
  exclude_none: bool = False,
278
+ exclude_computed_fields: bool = False,
263
279
  round_trip: bool = False,
264
280
  warnings: bool | Literal["none", "warn", "error"] = True,
265
- context: dict[str, Any] | None = None,
266
- serialize_as_any: bool = False,
267
281
  fallback: Callable[[Any], Any] | None = None,
282
+ serialize_as_any: bool = False,
268
283
  ) -> dict[str, Any]:
269
284
  """Usage docs: https://docs.pydantic.dev/2.4/concepts/serialization/#modelmodel_dump
270
285
 
@@ -272,16 +287,24 @@ class BaseModel(pydantic.BaseModel):
272
287
 
273
288
  Args:
274
289
  mode: The mode in which `to_python` should run.
275
- If mode is 'json', the dictionary will only contain JSON serializable types.
276
- If mode is 'python', the dictionary may contain any Python objects.
277
- include: A list of fields to include in the output.
278
- exclude: A list of fields to exclude from the output.
290
+ If mode is 'json', the output will only contain JSON serializable types.
291
+ If mode is 'python', the output may contain non-JSON-serializable Python objects.
292
+ include: A set of fields to include in the output.
293
+ exclude: A set of fields to exclude from the output.
294
+ context: Additional context to pass to the serializer.
279
295
  by_alias: Whether to use the field's alias in the dictionary key if defined.
280
- exclude_unset: Whether to exclude fields that are unset or None from the output.
281
- exclude_defaults: Whether to exclude fields that are set to their default value from the output.
282
- exclude_none: Whether to exclude fields that have a value of `None` from the output.
283
- round_trip: Whether to enable serialization and deserialization round-trip support.
284
- warnings: Whether to log warnings when invalid fields are encountered.
296
+ exclude_unset: Whether to exclude fields that have not been explicitly set.
297
+ exclude_defaults: Whether to exclude fields that are set to their default value.
298
+ exclude_none: Whether to exclude fields that have a value of `None`.
299
+ exclude_computed_fields: Whether to exclude computed fields.
300
+ While this can be useful for round-tripping, it is usually recommended to use the dedicated
301
+ `round_trip` parameter instead.
302
+ round_trip: If True, dumped values should be valid as input for non-idempotent types such as Json[T].
303
+ warnings: How to handle serialization errors. False/"none" ignores them, True/"warn" logs errors,
304
+ "error" raises a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError].
305
+ fallback: A function to call when an unknown value is encountered. If not provided,
306
+ a [`PydanticSerializationError`][pydantic_core.PydanticSerializationError] error is raised.
307
+ serialize_as_any: Whether to serialize fields with duck-typing serialization behavior.
285
308
 
286
309
  Returns:
287
310
  A dictionary representation of the model.
@@ -298,6 +321,8 @@ class BaseModel(pydantic.BaseModel):
298
321
  raise ValueError("serialize_as_any is only supported in Pydantic v2")
299
322
  if fallback is not None:
300
323
  raise ValueError("fallback is only supported in Pydantic v2")
324
+ if exclude_computed_fields != False:
325
+ raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
301
326
  dumped = super().dict( # pyright: ignore[reportDeprecated]
302
327
  include=include,
303
328
  exclude=exclude,
@@ -314,15 +339,17 @@ class BaseModel(pydantic.BaseModel):
314
339
  self,
315
340
  *,
316
341
  indent: int | None = None,
342
+ ensure_ascii: bool = False,
317
343
  include: IncEx | None = None,
318
344
  exclude: IncEx | None = None,
345
+ context: Any | None = None,
319
346
  by_alias: bool | None = None,
320
347
  exclude_unset: bool = False,
321
348
  exclude_defaults: bool = False,
322
349
  exclude_none: bool = False,
350
+ exclude_computed_fields: bool = False,
323
351
  round_trip: bool = False,
324
352
  warnings: bool | Literal["none", "warn", "error"] = True,
325
- context: dict[str, Any] | None = None,
326
353
  fallback: Callable[[Any], Any] | None = None,
327
354
  serialize_as_any: bool = False,
328
355
  ) -> str:
@@ -354,6 +381,10 @@ class BaseModel(pydantic.BaseModel):
354
381
  raise ValueError("serialize_as_any is only supported in Pydantic v2")
355
382
  if fallback is not None:
356
383
  raise ValueError("fallback is only supported in Pydantic v2")
384
+ if ensure_ascii != False:
385
+ raise ValueError("ensure_ascii is only supported in Pydantic v2")
386
+ if exclude_computed_fields != False:
387
+ raise ValueError("exclude_computed_fields is only supported in Pydantic v2")
357
388
  return super().json( # type: ignore[reportDeprecated]
358
389
  indent=indent,
359
390
  include=include,
@@ -573,6 +604,9 @@ class CachedDiscriminatorType(Protocol):
573
604
  __discriminator__: DiscriminatorDetails
574
605
 
575
606
 
607
+ DISCRIMINATOR_CACHE: weakref.WeakKeyDictionary[type, DiscriminatorDetails] = weakref.WeakKeyDictionary()
608
+
609
+
576
610
  class DiscriminatorDetails:
577
611
  field_name: str
578
612
  """The name of the discriminator field in the variant class, e.g.
@@ -615,8 +649,9 @@ class DiscriminatorDetails:
615
649
 
616
650
 
617
651
  def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any, ...]) -> DiscriminatorDetails | None:
618
- if isinstance(union, CachedDiscriminatorType):
619
- return union.__discriminator__
652
+ cached = DISCRIMINATOR_CACHE.get(union)
653
+ if cached is not None:
654
+ return cached
620
655
 
621
656
  discriminator_field_name: str | None = None
622
657
 
@@ -669,7 +704,7 @@ def _build_discriminated_union_meta(*, union: type, meta_annotations: tuple[Any,
669
704
  discriminator_field=discriminator_field_name,
670
705
  discriminator_alias=discriminator_alias,
671
706
  )
672
- cast(CachedDiscriminatorType, union).__discriminator__ = details
707
+ DISCRIMINATOR_CACHE.setdefault(union, details)
673
708
  return details
674
709
 
675
710
 
@@ -765,6 +800,7 @@ class FinalRequestOptionsInput(TypedDict, total=False):
765
800
  timeout: float | Timeout | None
766
801
  files: HttpxRequestFiles | None
767
802
  idempotency_key: str
803
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None]
768
804
  json_data: Body
769
805
  extra_json: AnyMapping
770
806
  follow_redirects: bool
@@ -783,6 +819,7 @@ class FinalRequestOptions(pydantic.BaseModel):
783
819
  post_parser: Union[Callable[[Any], Any], NotGiven] = NotGiven()
784
820
  follow_redirects: Union[bool, None] = None
785
821
 
822
+ content: Union[bytes, bytearray, IO[bytes], Iterable[bytes], AsyncIterable[bytes], None] = None
786
823
  # It should be noted that we cannot use `json` here as that would override
787
824
  # a BaseModel method in an incompatible fashion.
788
825
  json_data: Union[Body, None] = None