pulse-python-sdk 1.0.1__tar.gz → 1.0.4__tar.gz

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 (110) hide show
  1. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/PKG-INFO +1 -1
  2. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/pyproject.toml +1 -1
  3. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/client.py +116 -0
  4. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/client_wrapper.py +2 -2
  5. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/environment.py +1 -1
  6. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/raw_client.py +271 -0
  7. pulse_python_sdk-1.0.4/src/pulse/types/tables_config.py +33 -0
  8. pulse_python_sdk-1.0.4/src/pulse/types/tables_config_table_format.py +5 -0
  9. pulse_python_sdk-1.0.4/src/pulse/types/tables_response.py +33 -0
  10. pulse_python_sdk-1.0.4/src/pulse/types/tables_response_tables_output.py +28 -0
  11. pulse_python_sdk-1.0.4/src/pulse/types/tables_response_tables_output_tables_item.py +33 -0
  12. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/README.md +0 -0
  13. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/__init__.py +0 -0
  14. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/__init__.py +0 -0
  15. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/api_error.py +0 -0
  16. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/datetime_utils.py +0 -0
  17. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/file.py +0 -0
  18. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/force_multipart.py +0 -0
  19. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_client.py +0 -0
  20. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_response.py +0 -0
  21. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_sse/__init__.py +0 -0
  22. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_sse/_api.py +0 -0
  23. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_sse/_decoders.py +0 -0
  24. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_sse/_exceptions.py +0 -0
  25. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/http_sse/_models.py +0 -0
  26. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/jsonable_encoder.py +0 -0
  27. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/pydantic_utilities.py +0 -0
  28. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/query_encoder.py +0 -0
  29. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/remove_none_from_dict.py +0 -0
  30. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/request_options.py +0 -0
  31. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/serialization.py +0 -0
  32. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/core/unchecked_base_model.py +0 -0
  33. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/__init__.py +0 -0
  34. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/bad_request_error.py +0 -0
  35. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/forbidden_error.py +0 -0
  36. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/internal_server_error.py +0 -0
  37. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/not_found_error.py +0 -0
  38. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/too_many_requests_error.py +0 -0
  39. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/errors/unauthorized_error.py +0 -0
  40. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/jobs/__init__.py +0 -0
  41. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/jobs/client.py +0 -0
  42. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/jobs/raw_client.py +0 -0
  43. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/py.typed +0 -0
  44. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/__init__.py +0 -0
  45. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/async_submission_response.py +0 -0
  46. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/async_submission_response_status.py +0 -0
  47. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_extensions.py +0 -0
  48. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_extensions_alt_outputs.py +0 -0
  49. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_extensions_chunking.py +0 -0
  50. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_extensions_chunking_chunk_types_item.py +0 -0
  51. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_figure_processing.py +0 -0
  52. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_schema.py +0 -0
  53. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_storage.py +0 -0
  54. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_request_structured_output.py +0 -0
  55. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_async_submission_response.py +0 -0
  56. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input.py +0 -0
  57. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_extensions.py +0 -0
  58. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_extensions_alt_outputs.py +0 -0
  59. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_extensions_chunking.py +0 -0
  60. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_extensions_chunking_chunk_types_item.py +0 -0
  61. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_figure_processing.py +0 -0
  62. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_schema.py +0 -0
  63. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_storage.py +0 -0
  64. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_input_structured_output.py +0 -0
  65. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options.py +0 -0
  66. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_extensions.py +0 -0
  67. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_extensions_alt_outputs.py +0 -0
  68. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_extensions_chunking.py +0 -0
  69. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_extensions_chunking_chunk_types_item.py +0 -0
  70. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_figure_processing.py +0 -0
  71. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_schema.py +0 -0
  72. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_storage.py +0 -0
  73. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_options_structured_output.py +0 -0
  74. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_extensions.py +0 -0
  75. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_extensions_alt_outputs.py +0 -0
  76. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_extensions_chunking.py +0 -0
  77. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_extensions_chunking_chunk_types_item.py +0 -0
  78. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_figure_processing.py +0 -0
  79. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_schema.py +0 -0
  80. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_storage.py +0 -0
  81. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_request_structured_output.py +0 -0
  82. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response.py +0 -0
  83. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_chunks.py +0 -0
  84. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_extensions.py +0 -0
  85. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_extensions_alt_outputs.py +0 -0
  86. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_extensions_alt_outputs_wlbb.py +0 -0
  87. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_extensions_alt_outputs_wlbb_words_item.py +0 -0
  88. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_extensions_chunking.py +0 -0
  89. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_response_plan_info.py +0 -0
  90. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/extract_source.py +0 -0
  91. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/job_cancellation_response.py +0 -0
  92. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/job_status.py +0 -0
  93. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/job_status_response.py +0 -0
  94. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/schema_config.py +0 -0
  95. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/schema_response.py +0 -0
  96. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/single_schema_response.py +0 -0
  97. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/split_config.py +0 -0
  98. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/split_output.py +0 -0
  99. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/split_response.py +0 -0
  100. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/split_schema_response.py +0 -0
  101. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/structured_output_config.py +0 -0
  102. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/structured_output_result.py +0 -0
  103. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/topic_definition.py +0 -0
  104. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/types/topic_schema_config.py +0 -0
  105. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/version.py +0 -0
  106. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/webhooks/__init__.py +0 -0
  107. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/webhooks/client.py +0 -0
  108. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/webhooks/raw_client.py +0 -0
  109. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/webhooks/types/__init__.py +0 -0
  110. {pulse_python_sdk-1.0.1 → pulse_python_sdk-1.0.4}/src/pulse/webhooks/types/create_webhook_link_response.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pulse-python-sdk
3
- Version: 1.0.1
3
+ Version: 1.0.4
4
4
  Summary:
5
5
  Requires-Python: >=3.8,<4.0
6
6
  Classifier: Intended Audience :: Developers
@@ -4,7 +4,7 @@ dynamic = ["version"]
4
4
 
5
5
  [tool.poetry]
6
6
  name = "pulse-python-sdk"
7
- version = "1.0.1"
7
+ version = "1.0.4"
8
8
  description = ""
9
9
  readme = "README.md"
10
10
  authors = []
@@ -28,6 +28,8 @@ from .types.schema_config import SchemaConfig
28
28
  from .types.schema_response import SchemaResponse
29
29
  from .types.split_config import SplitConfig
30
30
  from .types.split_response import SplitResponse
31
+ from .types.tables_config import TablesConfig
32
+ from .types.tables_response import TablesResponse
31
33
  from .types.topic_schema_config import TopicSchemaConfig
32
34
 
33
35
  if typing.TYPE_CHECKING:
@@ -507,6 +509,59 @@ class Pulse:
507
509
  )
508
510
  return _response.data
509
511
 
512
+ def tables(
513
+ self,
514
+ *,
515
+ extraction_id: str,
516
+ tables_config: typing.Optional[TablesConfig] = OMIT,
517
+ async_: typing.Optional[bool] = OMIT,
518
+ request_options: typing.Optional[RequestOptions] = None,
519
+ ) -> TablesResponse:
520
+ """
521
+ Extract tables from a previously completed extraction. Processes the
522
+ extraction's document content and returns structured table data.
523
+
524
+ Requires the `tables_endpoint` feature flag to be enabled for your
525
+ organization.
526
+
527
+ Set `async: true` to return immediately with a `tables_id` for
528
+ polling via `GET /job/{tables_id}`.
529
+
530
+ Parameters
531
+ ----------
532
+ extraction_id : str
533
+ ID of a completed extraction to extract tables from.
534
+
535
+ tables_config : typing.Optional[TablesConfig]
536
+ Table extraction configuration. If omitted, defaults are used (`merge: false`, `table_format: "html"`).
537
+
538
+ async_ : typing.Optional[bool]
539
+ When true, returns immediately with a job ID. Poll `GET /job/{tables_id}` for the result.
540
+
541
+ request_options : typing.Optional[RequestOptions]
542
+ Request-specific configuration.
543
+
544
+ Returns
545
+ -------
546
+ TablesResponse
547
+ Table extraction result (when async=false or omitted).
548
+
549
+ Examples
550
+ --------
551
+ from pulse import Pulse
552
+
553
+ client = Pulse(
554
+ api_key="YOUR_API_KEY",
555
+ )
556
+ client.tables(
557
+ extraction_id="extraction_id",
558
+ )
559
+ """
560
+ _response = self._raw_client.tables(
561
+ extraction_id=extraction_id, tables_config=tables_config, async_=async_, request_options=request_options
562
+ )
563
+ return _response.data
564
+
510
565
  @property
511
566
  def jobs(self):
512
567
  if self._jobs is None:
@@ -1026,6 +1081,67 @@ class AsyncPulse:
1026
1081
  )
1027
1082
  return _response.data
1028
1083
 
1084
+ async def tables(
1085
+ self,
1086
+ *,
1087
+ extraction_id: str,
1088
+ tables_config: typing.Optional[TablesConfig] = OMIT,
1089
+ async_: typing.Optional[bool] = OMIT,
1090
+ request_options: typing.Optional[RequestOptions] = None,
1091
+ ) -> TablesResponse:
1092
+ """
1093
+ Extract tables from a previously completed extraction. Processes the
1094
+ extraction's document content and returns structured table data.
1095
+
1096
+ Requires the `tables_endpoint` feature flag to be enabled for your
1097
+ organization.
1098
+
1099
+ Set `async: true` to return immediately with a `tables_id` for
1100
+ polling via `GET /job/{tables_id}`.
1101
+
1102
+ Parameters
1103
+ ----------
1104
+ extraction_id : str
1105
+ ID of a completed extraction to extract tables from.
1106
+
1107
+ tables_config : typing.Optional[TablesConfig]
1108
+ Table extraction configuration. If omitted, defaults are used (`merge: false`, `table_format: "html"`).
1109
+
1110
+ async_ : typing.Optional[bool]
1111
+ When true, returns immediately with a job ID. Poll `GET /job/{tables_id}` for the result.
1112
+
1113
+ request_options : typing.Optional[RequestOptions]
1114
+ Request-specific configuration.
1115
+
1116
+ Returns
1117
+ -------
1118
+ TablesResponse
1119
+ Table extraction result (when async=false or omitted).
1120
+
1121
+ Examples
1122
+ --------
1123
+ import asyncio
1124
+
1125
+ from pulse import AsyncPulse
1126
+
1127
+ client = AsyncPulse(
1128
+ api_key="YOUR_API_KEY",
1129
+ )
1130
+
1131
+
1132
+ async def main() -> None:
1133
+ await client.tables(
1134
+ extraction_id="extraction_id",
1135
+ )
1136
+
1137
+
1138
+ asyncio.run(main())
1139
+ """
1140
+ _response = await self._raw_client.tables(
1141
+ extraction_id=extraction_id, tables_config=tables_config, async_=async_, request_options=request_options
1142
+ )
1143
+ return _response.data
1144
+
1029
1145
  @property
1030
1146
  def jobs(self):
1031
1147
  if self._jobs is None:
@@ -22,10 +22,10 @@ class BaseClientWrapper:
22
22
 
23
23
  def get_headers(self) -> typing.Dict[str, str]:
24
24
  headers: typing.Dict[str, str] = {
25
- "User-Agent": "pulse-python-sdk/1.0.1",
25
+ "User-Agent": "pulse-python-sdk/1.0.4",
26
26
  "X-Fern-Language": "Python",
27
27
  "X-Fern-SDK-Name": "pulse-python-sdk",
28
- "X-Fern-SDK-Version": "1.0.1",
28
+ "X-Fern-SDK-Version": "1.0.4",
29
29
  **(self.get_custom_headers() or {}),
30
30
  }
31
31
  headers["x-api-key"] = self.api_key
@@ -4,4 +4,4 @@ import enum
4
4
 
5
5
 
6
6
  class PulseEnvironment(enum.Enum):
7
- DEFAULT = "https://dev.api.runpulse.com"
7
+ DEFAULT = "https://api.runpulse.com"
@@ -11,6 +11,7 @@ from .core.request_options import RequestOptions
11
11
  from .core.serialization import convert_and_respect_annotation_metadata
12
12
  from .core.unchecked_base_model import construct_type
13
13
  from .errors.bad_request_error import BadRequestError
14
+ from .errors.forbidden_error import ForbiddenError
14
15
  from .errors.internal_server_error import InternalServerError
15
16
  from .errors.not_found_error import NotFoundError
16
17
  from .errors.too_many_requests_error import TooManyRequestsError
@@ -31,6 +32,8 @@ from .types.schema_config import SchemaConfig
31
32
  from .types.schema_response import SchemaResponse
32
33
  from .types.split_config import SplitConfig
33
34
  from .types.split_response import SplitResponse
35
+ from .types.tables_config import TablesConfig
36
+ from .types.tables_response import TablesResponse
34
37
  from .types.topic_schema_config import TopicSchemaConfig
35
38
 
36
39
  # this is used as the default value for optional parameters
@@ -657,6 +660,140 @@ class RawPulse:
657
660
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
658
661
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
659
662
 
663
+ def tables(
664
+ self,
665
+ *,
666
+ extraction_id: str,
667
+ tables_config: typing.Optional[TablesConfig] = OMIT,
668
+ async_: typing.Optional[bool] = OMIT,
669
+ request_options: typing.Optional[RequestOptions] = None,
670
+ ) -> HttpResponse[TablesResponse]:
671
+ """
672
+ Extract tables from a previously completed extraction. Processes the
673
+ extraction's document content and returns structured table data.
674
+
675
+ Requires the `tables_endpoint` feature flag to be enabled for your
676
+ organization.
677
+
678
+ Set `async: true` to return immediately with a `tables_id` for
679
+ polling via `GET /job/{tables_id}`.
680
+
681
+ Parameters
682
+ ----------
683
+ extraction_id : str
684
+ ID of a completed extraction to extract tables from.
685
+
686
+ tables_config : typing.Optional[TablesConfig]
687
+ Table extraction configuration. If omitted, defaults are used (`merge: false`, `table_format: "html"`).
688
+
689
+ async_ : typing.Optional[bool]
690
+ When true, returns immediately with a job ID. Poll `GET /job/{tables_id}` for the result.
691
+
692
+ request_options : typing.Optional[RequestOptions]
693
+ Request-specific configuration.
694
+
695
+ Returns
696
+ -------
697
+ HttpResponse[TablesResponse]
698
+ Table extraction result (when async=false or omitted).
699
+ """
700
+ _response = self._client_wrapper.httpx_client.request(
701
+ "tables",
702
+ method="POST",
703
+ json={
704
+ "extraction_id": extraction_id,
705
+ "tables_config": convert_and_respect_annotation_metadata(
706
+ object_=tables_config, annotation=TablesConfig, direction="write"
707
+ ),
708
+ "async": async_,
709
+ },
710
+ headers={
711
+ "content-type": "application/json",
712
+ },
713
+ request_options=request_options,
714
+ omit=OMIT,
715
+ )
716
+ try:
717
+ if 200 <= _response.status_code < 300:
718
+ _data = typing.cast(
719
+ TablesResponse,
720
+ construct_type(
721
+ type_=TablesResponse, # type: ignore
722
+ object_=_response.json(),
723
+ ),
724
+ )
725
+ return HttpResponse(response=_response, data=_data)
726
+ if _response.status_code == 400:
727
+ raise BadRequestError(
728
+ headers=dict(_response.headers),
729
+ body=typing.cast(
730
+ typing.Any,
731
+ construct_type(
732
+ type_=typing.Any, # type: ignore
733
+ object_=_response.json(),
734
+ ),
735
+ ),
736
+ )
737
+ if _response.status_code == 401:
738
+ raise UnauthorizedError(
739
+ headers=dict(_response.headers),
740
+ body=typing.cast(
741
+ typing.Any,
742
+ construct_type(
743
+ type_=typing.Any, # type: ignore
744
+ object_=_response.json(),
745
+ ),
746
+ ),
747
+ )
748
+ if _response.status_code == 403:
749
+ raise ForbiddenError(
750
+ headers=dict(_response.headers),
751
+ body=typing.cast(
752
+ typing.Any,
753
+ construct_type(
754
+ type_=typing.Any, # type: ignore
755
+ object_=_response.json(),
756
+ ),
757
+ ),
758
+ )
759
+ if _response.status_code == 404:
760
+ raise NotFoundError(
761
+ headers=dict(_response.headers),
762
+ body=typing.cast(
763
+ typing.Any,
764
+ construct_type(
765
+ type_=typing.Any, # type: ignore
766
+ object_=_response.json(),
767
+ ),
768
+ ),
769
+ )
770
+ if _response.status_code == 429:
771
+ raise TooManyRequestsError(
772
+ headers=dict(_response.headers),
773
+ body=typing.cast(
774
+ typing.Any,
775
+ construct_type(
776
+ type_=typing.Any, # type: ignore
777
+ object_=_response.json(),
778
+ ),
779
+ ),
780
+ )
781
+ if _response.status_code == 500:
782
+ raise InternalServerError(
783
+ headers=dict(_response.headers),
784
+ body=typing.cast(
785
+ typing.Any,
786
+ construct_type(
787
+ type_=typing.Any, # type: ignore
788
+ object_=_response.json(),
789
+ ),
790
+ ),
791
+ )
792
+ _response_json = _response.json()
793
+ except JSONDecodeError:
794
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
795
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
796
+
660
797
 
661
798
  class AsyncRawPulse:
662
799
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
@@ -1277,3 +1414,137 @@ class AsyncRawPulse:
1277
1414
  except JSONDecodeError:
1278
1415
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1279
1416
  raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
1417
+
1418
+ async def tables(
1419
+ self,
1420
+ *,
1421
+ extraction_id: str,
1422
+ tables_config: typing.Optional[TablesConfig] = OMIT,
1423
+ async_: typing.Optional[bool] = OMIT,
1424
+ request_options: typing.Optional[RequestOptions] = None,
1425
+ ) -> AsyncHttpResponse[TablesResponse]:
1426
+ """
1427
+ Extract tables from a previously completed extraction. Processes the
1428
+ extraction's document content and returns structured table data.
1429
+
1430
+ Requires the `tables_endpoint` feature flag to be enabled for your
1431
+ organization.
1432
+
1433
+ Set `async: true` to return immediately with a `tables_id` for
1434
+ polling via `GET /job/{tables_id}`.
1435
+
1436
+ Parameters
1437
+ ----------
1438
+ extraction_id : str
1439
+ ID of a completed extraction to extract tables from.
1440
+
1441
+ tables_config : typing.Optional[TablesConfig]
1442
+ Table extraction configuration. If omitted, defaults are used (`merge: false`, `table_format: "html"`).
1443
+
1444
+ async_ : typing.Optional[bool]
1445
+ When true, returns immediately with a job ID. Poll `GET /job/{tables_id}` for the result.
1446
+
1447
+ request_options : typing.Optional[RequestOptions]
1448
+ Request-specific configuration.
1449
+
1450
+ Returns
1451
+ -------
1452
+ AsyncHttpResponse[TablesResponse]
1453
+ Table extraction result (when async=false or omitted).
1454
+ """
1455
+ _response = await self._client_wrapper.httpx_client.request(
1456
+ "tables",
1457
+ method="POST",
1458
+ json={
1459
+ "extraction_id": extraction_id,
1460
+ "tables_config": convert_and_respect_annotation_metadata(
1461
+ object_=tables_config, annotation=TablesConfig, direction="write"
1462
+ ),
1463
+ "async": async_,
1464
+ },
1465
+ headers={
1466
+ "content-type": "application/json",
1467
+ },
1468
+ request_options=request_options,
1469
+ omit=OMIT,
1470
+ )
1471
+ try:
1472
+ if 200 <= _response.status_code < 300:
1473
+ _data = typing.cast(
1474
+ TablesResponse,
1475
+ construct_type(
1476
+ type_=TablesResponse, # type: ignore
1477
+ object_=_response.json(),
1478
+ ),
1479
+ )
1480
+ return AsyncHttpResponse(response=_response, data=_data)
1481
+ if _response.status_code == 400:
1482
+ raise BadRequestError(
1483
+ headers=dict(_response.headers),
1484
+ body=typing.cast(
1485
+ typing.Any,
1486
+ construct_type(
1487
+ type_=typing.Any, # type: ignore
1488
+ object_=_response.json(),
1489
+ ),
1490
+ ),
1491
+ )
1492
+ if _response.status_code == 401:
1493
+ raise UnauthorizedError(
1494
+ headers=dict(_response.headers),
1495
+ body=typing.cast(
1496
+ typing.Any,
1497
+ construct_type(
1498
+ type_=typing.Any, # type: ignore
1499
+ object_=_response.json(),
1500
+ ),
1501
+ ),
1502
+ )
1503
+ if _response.status_code == 403:
1504
+ raise ForbiddenError(
1505
+ headers=dict(_response.headers),
1506
+ body=typing.cast(
1507
+ typing.Any,
1508
+ construct_type(
1509
+ type_=typing.Any, # type: ignore
1510
+ object_=_response.json(),
1511
+ ),
1512
+ ),
1513
+ )
1514
+ if _response.status_code == 404:
1515
+ raise NotFoundError(
1516
+ headers=dict(_response.headers),
1517
+ body=typing.cast(
1518
+ typing.Any,
1519
+ construct_type(
1520
+ type_=typing.Any, # type: ignore
1521
+ object_=_response.json(),
1522
+ ),
1523
+ ),
1524
+ )
1525
+ if _response.status_code == 429:
1526
+ raise TooManyRequestsError(
1527
+ headers=dict(_response.headers),
1528
+ body=typing.cast(
1529
+ typing.Any,
1530
+ construct_type(
1531
+ type_=typing.Any, # type: ignore
1532
+ object_=_response.json(),
1533
+ ),
1534
+ ),
1535
+ )
1536
+ if _response.status_code == 500:
1537
+ raise InternalServerError(
1538
+ headers=dict(_response.headers),
1539
+ body=typing.cast(
1540
+ typing.Any,
1541
+ construct_type(
1542
+ type_=typing.Any, # type: ignore
1543
+ object_=_response.json(),
1544
+ ),
1545
+ ),
1546
+ )
1547
+ _response_json = _response.json()
1548
+ except JSONDecodeError:
1549
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1550
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
@@ -0,0 +1,33 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ from ..core.unchecked_base_model import UncheckedBaseModel
8
+ from .tables_config_table_format import TablesConfigTableFormat
9
+
10
+
11
+ class TablesConfig(UncheckedBaseModel):
12
+ """
13
+ Configuration for table extraction.
14
+ """
15
+
16
+ merge: typing.Optional[bool] = pydantic.Field(default=None)
17
+ """
18
+ When true, adjacent tables that appear to be continuations of each other are merged into a single table.
19
+ """
20
+
21
+ table_format: typing.Optional[TablesConfigTableFormat] = pydantic.Field(default=None)
22
+ """
23
+ Output format for table content. Currently only `html` is supported.
24
+ """
25
+
26
+ if IS_PYDANTIC_V2:
27
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
28
+ else:
29
+
30
+ class Config:
31
+ frozen = True
32
+ smart_union = True
33
+ extra = pydantic.Extra.allow
@@ -0,0 +1,5 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ TablesConfigTableFormat = typing.Union[typing.Literal["html"], typing.Any]
@@ -0,0 +1,33 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ from ..core.unchecked_base_model import UncheckedBaseModel
8
+ from .tables_response_tables_output import TablesResponseTablesOutput
9
+
10
+
11
+ class TablesResponse(UncheckedBaseModel):
12
+ """
13
+ Result of table extraction.
14
+ """
15
+
16
+ tables_id: str = pydantic.Field()
17
+ """
18
+ Persisted tables version ID. Can be used to retrieve the tables result later.
19
+ """
20
+
21
+ tables_output: TablesResponseTablesOutput = pydantic.Field()
22
+ """
23
+ The extracted tables data.
24
+ """
25
+
26
+ if IS_PYDANTIC_V2:
27
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
28
+ else:
29
+
30
+ class Config:
31
+ frozen = True
32
+ smart_union = True
33
+ extra = pydantic.Extra.allow
@@ -0,0 +1,28 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ from ..core.unchecked_base_model import UncheckedBaseModel
8
+ from .tables_response_tables_output_tables_item import TablesResponseTablesOutputTablesItem
9
+
10
+
11
+ class TablesResponseTablesOutput(UncheckedBaseModel):
12
+ """
13
+ The extracted tables data.
14
+ """
15
+
16
+ tables: typing.Optional[typing.List[TablesResponseTablesOutputTablesItem]] = pydantic.Field(default=None)
17
+ """
18
+ Array of extracted table objects. Each table includes its content, citations, and whether it was derived from a chart.
19
+ """
20
+
21
+ if IS_PYDANTIC_V2:
22
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
23
+ else:
24
+
25
+ class Config:
26
+ frozen = True
27
+ smart_union = True
28
+ extra = pydantic.Extra.allow
@@ -0,0 +1,33 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+
5
+ import pydantic
6
+ from ..core.pydantic_utilities import IS_PYDANTIC_V2
7
+ from ..core.unchecked_base_model import UncheckedBaseModel
8
+
9
+
10
+ class TablesResponseTablesOutputTablesItem(UncheckedBaseModel):
11
+ table_content: typing.Optional[str] = pydantic.Field(default=None)
12
+ """
13
+ The table content in the requested format (e.g. HTML).
14
+ """
15
+
16
+ citations: typing.Optional[typing.List[str]] = pydantic.Field(default=None)
17
+ """
18
+ Bounding box table IDs indicating where this table was found (e.g. "tbl-1"). Merged tables list all source IDs.
19
+ """
20
+
21
+ from_chart: typing.Optional[bool] = pydantic.Field(default=None)
22
+ """
23
+ Whether this table was extracted from a chart or figure rather than a native table.
24
+ """
25
+
26
+ if IS_PYDANTIC_V2:
27
+ model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2
28
+ else:
29
+
30
+ class Config:
31
+ frozen = True
32
+ smart_union = True
33
+ extra = pydantic.Extra.allow