elasticsearch9 9.1.1__py3-none-any.whl → 9.1.3__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 (124) hide show
  1. elasticsearch9/_async/client/__init__.py +69 -65
  2. elasticsearch9/_async/client/async_search.py +3 -3
  3. elasticsearch9/_async/client/autoscaling.py +8 -4
  4. elasticsearch9/_async/client/cat.py +521 -27
  5. elasticsearch9/_async/client/ccr.py +10 -10
  6. elasticsearch9/_async/client/cluster.py +34 -33
  7. elasticsearch9/_async/client/connector.py +45 -44
  8. elasticsearch9/_async/client/dangling_indices.py +8 -12
  9. elasticsearch9/_async/client/enrich.py +10 -10
  10. elasticsearch9/_async/client/eql.py +10 -10
  11. elasticsearch9/_async/client/esql.py +16 -16
  12. elasticsearch9/_async/client/features.py +6 -6
  13. elasticsearch9/_async/client/fleet.py +8 -12
  14. elasticsearch9/_async/client/graph.py +3 -7
  15. elasticsearch9/_async/client/ilm.py +20 -28
  16. elasticsearch9/_async/client/indices.py +163 -169
  17. elasticsearch9/_async/client/inference.py +41 -127
  18. elasticsearch9/_async/client/ingest.py +9 -9
  19. elasticsearch9/_async/client/license.py +5 -7
  20. elasticsearch9/_async/client/logstash.py +7 -5
  21. elasticsearch9/_async/client/migration.py +6 -6
  22. elasticsearch9/_async/client/ml.py +125 -85
  23. elasticsearch9/_async/client/monitoring.py +4 -3
  24. elasticsearch9/_async/client/nodes.py +17 -17
  25. elasticsearch9/_async/client/query_rules.py +16 -16
  26. elasticsearch9/_async/client/rollup.py +21 -21
  27. elasticsearch9/_async/client/search_application.py +19 -19
  28. elasticsearch9/_async/client/searchable_snapshots.py +10 -10
  29. elasticsearch9/_async/client/security.py +8 -7
  30. elasticsearch9/_async/client/shutdown.py +14 -19
  31. elasticsearch9/_async/client/simulate.py +4 -4
  32. elasticsearch9/_async/client/slm.py +18 -22
  33. elasticsearch9/_async/client/snapshot.py +20 -20
  34. elasticsearch9/_async/client/sql.py +10 -10
  35. elasticsearch9/_async/client/streams.py +186 -0
  36. elasticsearch9/_async/client/synonyms.py +10 -10
  37. elasticsearch9/_async/client/tasks.py +8 -8
  38. elasticsearch9/_async/client/text_structure.py +13 -9
  39. elasticsearch9/_async/client/transform.py +51 -12
  40. elasticsearch9/_async/client/utils.py +4 -2
  41. elasticsearch9/_async/client/watcher.py +27 -31
  42. elasticsearch9/_async/client/xpack.py +6 -5
  43. elasticsearch9/_async/helpers.py +58 -9
  44. elasticsearch9/_sync/client/__init__.py +71 -65
  45. elasticsearch9/_sync/client/async_search.py +3 -3
  46. elasticsearch9/_sync/client/autoscaling.py +8 -4
  47. elasticsearch9/_sync/client/cat.py +521 -27
  48. elasticsearch9/_sync/client/ccr.py +10 -10
  49. elasticsearch9/_sync/client/cluster.py +34 -33
  50. elasticsearch9/_sync/client/connector.py +45 -44
  51. elasticsearch9/_sync/client/dangling_indices.py +8 -12
  52. elasticsearch9/_sync/client/enrich.py +10 -10
  53. elasticsearch9/_sync/client/eql.py +10 -10
  54. elasticsearch9/_sync/client/esql.py +16 -16
  55. elasticsearch9/_sync/client/features.py +6 -6
  56. elasticsearch9/_sync/client/fleet.py +8 -12
  57. elasticsearch9/_sync/client/graph.py +3 -7
  58. elasticsearch9/_sync/client/ilm.py +20 -28
  59. elasticsearch9/_sync/client/indices.py +163 -169
  60. elasticsearch9/_sync/client/inference.py +41 -127
  61. elasticsearch9/_sync/client/ingest.py +9 -9
  62. elasticsearch9/_sync/client/license.py +5 -7
  63. elasticsearch9/_sync/client/logstash.py +7 -5
  64. elasticsearch9/_sync/client/migration.py +6 -6
  65. elasticsearch9/_sync/client/ml.py +125 -85
  66. elasticsearch9/_sync/client/monitoring.py +4 -3
  67. elasticsearch9/_sync/client/nodes.py +17 -17
  68. elasticsearch9/_sync/client/query_rules.py +16 -16
  69. elasticsearch9/_sync/client/rollup.py +21 -21
  70. elasticsearch9/_sync/client/search_application.py +19 -19
  71. elasticsearch9/_sync/client/searchable_snapshots.py +10 -10
  72. elasticsearch9/_sync/client/security.py +8 -7
  73. elasticsearch9/_sync/client/shutdown.py +14 -19
  74. elasticsearch9/_sync/client/simulate.py +4 -4
  75. elasticsearch9/_sync/client/slm.py +18 -22
  76. elasticsearch9/_sync/client/snapshot.py +20 -20
  77. elasticsearch9/_sync/client/sql.py +10 -10
  78. elasticsearch9/_sync/client/streams.py +186 -0
  79. elasticsearch9/_sync/client/synonyms.py +10 -10
  80. elasticsearch9/_sync/client/tasks.py +8 -8
  81. elasticsearch9/_sync/client/text_structure.py +13 -9
  82. elasticsearch9/_sync/client/transform.py +51 -12
  83. elasticsearch9/_sync/client/utils.py +16 -2
  84. elasticsearch9/_sync/client/watcher.py +27 -31
  85. elasticsearch9/_sync/client/xpack.py +6 -5
  86. elasticsearch9/_version.py +2 -1
  87. elasticsearch9/client.py +2 -0
  88. elasticsearch9/compat.py +43 -1
  89. elasticsearch9/dsl/__init__.py +28 -0
  90. elasticsearch9/dsl/_async/document.py +4 -5
  91. elasticsearch9/dsl/_async/index.py +1 -1
  92. elasticsearch9/dsl/_async/search.py +2 -3
  93. elasticsearch9/dsl/_sync/document.py +4 -5
  94. elasticsearch9/dsl/_sync/index.py +1 -1
  95. elasticsearch9/dsl/_sync/search.py +2 -3
  96. elasticsearch9/dsl/aggs.py +100 -3
  97. elasticsearch9/dsl/async_connections.py +1 -2
  98. elasticsearch9/dsl/connections.py +1 -2
  99. elasticsearch9/dsl/document_base.py +15 -0
  100. elasticsearch9/dsl/field.py +12 -1
  101. elasticsearch9/dsl/query.py +23 -0
  102. elasticsearch9/dsl/response/__init__.py +3 -0
  103. elasticsearch9/dsl/serializer.py +1 -2
  104. elasticsearch9/dsl/types.py +185 -5
  105. elasticsearch9/dsl/utils.py +1 -2
  106. elasticsearch9/esql/esql.py +1 -1
  107. elasticsearch9/esql/functions.py +2 -2
  108. elasticsearch9/helpers/__init__.py +10 -1
  109. elasticsearch9/helpers/actions.py +106 -33
  110. elasticsearch9/helpers/vectorstore/__init__.py +7 -7
  111. elasticsearch9/helpers/vectorstore/_async/_utils.py +1 -1
  112. elasticsearch9/helpers/vectorstore/_async/embedding_service.py +2 -2
  113. elasticsearch9/helpers/vectorstore/_async/strategies.py +3 -3
  114. elasticsearch9/helpers/vectorstore/_async/vectorstore.py +5 -5
  115. elasticsearch9/helpers/vectorstore/_sync/_utils.py +1 -1
  116. elasticsearch9/helpers/vectorstore/_sync/embedding_service.py +2 -2
  117. elasticsearch9/helpers/vectorstore/_sync/strategies.py +3 -3
  118. elasticsearch9/helpers/vectorstore/_sync/vectorstore.py +5 -5
  119. {elasticsearch9-9.1.1.dist-info → elasticsearch9-9.1.3.dist-info}/METADATA +2 -2
  120. elasticsearch9-9.1.3.dist-info/RECORD +165 -0
  121. {elasticsearch9-9.1.1.dist-info → elasticsearch9-9.1.3.dist-info}/WHEEL +1 -1
  122. elasticsearch9-9.1.1.dist-info/RECORD +0 -163
  123. {elasticsearch9-9.1.1.dist-info → elasticsearch9-9.1.3.dist-info}/licenses/LICENSE +0 -0
  124. {elasticsearch9-9.1.1.dist-info → elasticsearch9-9.1.3.dist-info}/licenses/NOTICE +0 -0
@@ -85,6 +85,45 @@ class TransformClient(NamespacedClient):
85
85
  path_parts=__path_parts,
86
86
  )
87
87
 
88
+ @_rewrite_parameters()
89
+ async def get_node_stats(
90
+ self,
91
+ *,
92
+ error_trace: t.Optional[bool] = None,
93
+ filter_path: t.Optional[t.Union[str, t.Sequence[str]]] = None,
94
+ human: t.Optional[bool] = None,
95
+ pretty: t.Optional[bool] = None,
96
+ ) -> ObjectApiResponse[t.Any]:
97
+ """
98
+ .. raw:: html
99
+
100
+ <p>Get node stats.</p>
101
+ <p>Get per-node information about transform usage.</p>
102
+
103
+
104
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-get-node-stats>`_
105
+ """
106
+ __path_parts: t.Dict[str, str] = {}
107
+ __path = "/_transform/_node_stats"
108
+ __query: t.Dict[str, t.Any] = {}
109
+ if error_trace is not None:
110
+ __query["error_trace"] = error_trace
111
+ if filter_path is not None:
112
+ __query["filter_path"] = filter_path
113
+ if human is not None:
114
+ __query["human"] = human
115
+ if pretty is not None:
116
+ __query["pretty"] = pretty
117
+ __headers = {"accept": "application/json"}
118
+ return await self.perform_request( # type: ignore[return-value]
119
+ "GET",
120
+ __path,
121
+ params=__query,
122
+ headers=__headers,
123
+ endpoint_id="transform.get_node_stats",
124
+ path_parts=__path_parts,
125
+ )
126
+
88
127
  @_rewrite_parameters(
89
128
  parameter_aliases={"from": "from_"},
90
129
  )
@@ -104,8 +143,8 @@ class TransformClient(NamespacedClient):
104
143
  """
105
144
  .. raw:: html
106
145
 
107
- <p>Get transforms.
108
- Get configuration information for transforms.</p>
146
+ <p>Get transforms.</p>
147
+ <p>Get configuration information for transforms.</p>
109
148
 
110
149
 
111
150
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-get-transform>`_
@@ -262,8 +301,8 @@ class TransformClient(NamespacedClient):
262
301
  """
263
302
  .. raw:: html
264
303
 
265
- <p>Preview a transform.
266
- Generates a preview of the results that you will get when you create a transform with the same configuration.</p>
304
+ <p>Preview a transform.</p>
305
+ <p>Generates a preview of the results that you will get when you create a transform with the same configuration.</p>
267
306
  <p>It returns a maximum of 100 results. The calculations are based on all the current data in the source index. It also
268
307
  generates a list of mappings and settings for the destination index. These values are determined based on the field
269
308
  types of the source index and the transform aggregations.</p>
@@ -386,8 +425,8 @@ class TransformClient(NamespacedClient):
386
425
  """
387
426
  .. raw:: html
388
427
 
389
- <p>Create a transform.
390
- Creates a transform.</p>
428
+ <p>Create a transform.</p>
429
+ <p>Creates a transform.</p>
391
430
  <p>A transform copies data from source indices, transforms it, and persists it into an entity-centric destination index. You can also think of the destination index as a two-dimensional tabular data structure (known as
392
431
  a data frame). The ID for each document in the data frame is generated from a hash of the entity, so there is a
393
432
  unique row per entity.</p>
@@ -616,8 +655,8 @@ class TransformClient(NamespacedClient):
616
655
  """
617
656
  .. raw:: html
618
657
 
619
- <p>Set upgrade_mode for transform indices.
620
- Sets a cluster wide upgrade_mode setting that prepares transform
658
+ <p>Set upgrade_mode for transform indices.</p>
659
+ <p>Sets a cluster wide upgrade_mode setting that prepares transform
621
660
  indices for an upgrade.
622
661
  When upgrading your cluster, in some circumstances you must restart your
623
662
  nodes and reindex your transform indices. In those circumstances,
@@ -749,8 +788,8 @@ class TransformClient(NamespacedClient):
749
788
  """
750
789
  .. raw:: html
751
790
 
752
- <p>Stop transforms.
753
- Stops one or more transforms.</p>
791
+ <p>Stop transforms.</p>
792
+ <p>Stops one or more transforms.</p>
754
793
 
755
794
 
756
795
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-stop-transform>`_
@@ -846,8 +885,8 @@ class TransformClient(NamespacedClient):
846
885
  """
847
886
  .. raw:: html
848
887
 
849
- <p>Update a transform.
850
- Updates certain properties of a transform.</p>
888
+ <p>Update a transform.</p>
889
+ <p>Updates certain properties of a transform.</p>
851
890
  <p>All updated properties except <code>description</code> do not take effect until after the transform starts the next checkpoint,
852
891
  thus there is data consistency in each checkpoint. To use this API, you must have <code>read</code> and <code>view_index_metadata</code>
853
892
  privileges for the source indices. You must also have <code>index</code> and <code>read</code> privileges for the destination index. When
@@ -21,11 +21,12 @@ from ..._sync.client.utils import (
21
21
  CLIENT_META_SERVICE,
22
22
  SKIP_IN_PATH,
23
23
  Stability,
24
+ Visibility,
25
+ _availability_warning,
24
26
  _base64_auth_header,
25
27
  _quote,
26
28
  _quote_query,
27
29
  _rewrite_parameters,
28
- _stability_warning,
29
30
  client_node_configs,
30
31
  is_requests_http_auth,
31
32
  is_requests_node_class,
@@ -40,9 +41,10 @@ __all__ = [
40
41
  "_TYPE_HOSTS",
41
42
  "SKIP_IN_PATH",
42
43
  "Stability",
44
+ "Visibility",
43
45
  "client_node_configs",
44
46
  "_rewrite_parameters",
45
- "_stability_warning",
47
+ "_availability_warning",
46
48
  "is_requests_http_auth",
47
49
  "is_requests_node_class",
48
50
  ]
@@ -39,8 +39,8 @@ class WatcherClient(NamespacedClient):
39
39
  """
40
40
  .. raw:: html
41
41
 
42
- <p>Acknowledge a watch.
43
- Acknowledging a watch enables you to manually throttle the execution of the watch's actions.</p>
42
+ <p>Acknowledge a watch.</p>
43
+ <p>Acknowledging a watch enables you to manually throttle the execution of the watch's actions.</p>
44
44
  <p>The acknowledgement state of an action is stored in the <code>status.actions.&lt;id&gt;.ack.state</code> structure.</p>
45
45
  <p>IMPORTANT: If the specified watch is currently being executed, this API will return an error
46
46
  The reason for this behavior is to prevent overwriting the watch status from a watch execution.</p>
@@ -101,8 +101,8 @@ class WatcherClient(NamespacedClient):
101
101
  """
102
102
  .. raw:: html
103
103
 
104
- <p>Activate a watch.
105
- A watch can be either active or inactive.</p>
104
+ <p>Activate a watch.</p>
105
+ <p>A watch can be either active or inactive.</p>
106
106
 
107
107
 
108
108
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-activate-watch>`_
@@ -145,8 +145,8 @@ class WatcherClient(NamespacedClient):
145
145
  """
146
146
  .. raw:: html
147
147
 
148
- <p>Deactivate a watch.
149
- A watch can be either active or inactive.</p>
148
+ <p>Deactivate a watch.</p>
149
+ <p>A watch can be either active or inactive.</p>
150
150
 
151
151
 
152
152
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-deactivate-watch>`_
@@ -189,8 +189,8 @@ class WatcherClient(NamespacedClient):
189
189
  """
190
190
  .. raw:: html
191
191
 
192
- <p>Delete a watch.
193
- When the watch is removed, the document representing the watch in the <code>.watches</code> index is gone and it will never be run again.</p>
192
+ <p>Delete a watch.</p>
193
+ <p>When the watch is removed, the document representing the watch in the <code>.watches</code> index is gone and it will never be run again.</p>
194
194
  <p>Deleting a watch does not delete any watch execution records related to this watch from the watch history.</p>
195
195
  <p>IMPORTANT: Deleting a watch must be done by using only this API.
196
196
  Do not delete the watch directly from the <code>.watches</code> index using the Elasticsearch delete document API
@@ -266,8 +266,8 @@ class WatcherClient(NamespacedClient):
266
266
  """
267
267
  .. raw:: html
268
268
 
269
- <p>Run a watch.
270
- This API can be used to force execution of the watch outside of its triggering logic or to simulate the watch execution for debugging purposes.</p>
269
+ <p>Run a watch.</p>
270
+ <p>This API can be used to force execution of the watch outside of its triggering logic or to simulate the watch execution for debugging purposes.</p>
271
271
  <p>For testing and debugging purposes, you also have fine-grained control on how the watch runs.
272
272
  You can run the watch without running all of its actions or alternatively by simulating them.
273
273
  You can also force execution by ignoring the watch condition and control whether a watch record would be written to the watch history after it runs.</p>
@@ -362,8 +362,8 @@ class WatcherClient(NamespacedClient):
362
362
  """
363
363
  .. raw:: html
364
364
 
365
- <p>Get Watcher index settings.
366
- Get settings for the Watcher internal index (<code>.watches</code>).
365
+ <p>Get Watcher index settings.</p>
366
+ <p>Get settings for the Watcher internal index (<code>.watches</code>).
367
367
  Only a subset of settings are shown, for example <code>index.auto_expand_replicas</code> and <code>index.number_of_replicas</code>.</p>
368
368
 
369
369
 
@@ -476,8 +476,8 @@ class WatcherClient(NamespacedClient):
476
476
  """
477
477
  .. raw:: html
478
478
 
479
- <p>Create or update a watch.
480
- When a watch is registered, a new document that represents the watch is added to the <code>.watches</code> index and its trigger is immediately registered with the relevant trigger engine.
479
+ <p>Create or update a watch.</p>
480
+ <p>When a watch is registered, a new document that represents the watch is added to the <code>.watches</code> index and its trigger is immediately registered with the relevant trigger engine.
481
481
  Typically for the <code>schedule</code> trigger, the scheduler is the trigger engine.</p>
482
482
  <p>IMPORTANT: You must use Kibana or this API to create a watch.
483
483
  Do not add a watch directly to the <code>.watches</code> index by using the Elasticsearch index API.
@@ -494,9 +494,9 @@ class WatcherClient(NamespacedClient):
494
494
  :param active: The initial state of the watch. The default value is `true`, which
495
495
  means the watch is active by default.
496
496
  :param condition: The condition that defines if the actions should be run.
497
- :param if_primary_term: only update the watch if the last operation that has
497
+ :param if_primary_term: Only update the watch if the last operation that has
498
498
  changed the watch has the specified primary term
499
- :param if_seq_no: only update the watch if the last operation that has changed
499
+ :param if_seq_no: Only update the watch if the last operation that has changed
500
500
  the watch has the specified sequence number
501
501
  :param input: The input that defines the input that loads the data for the watch.
502
502
  :param metadata: Metadata JSON that will be copied into the history entries.
@@ -552,11 +552,7 @@ class WatcherClient(NamespacedClient):
552
552
  __body["transform"] = transform
553
553
  if trigger is not None:
554
554
  __body["trigger"] = trigger
555
- if not __body:
556
- __body = None # type: ignore[assignment]
557
- __headers = {"accept": "application/json"}
558
- if __body is not None:
559
- __headers["content-type"] = "application/json"
555
+ __headers = {"accept": "application/json", "content-type": "application/json"}
560
556
  return await self.perform_request( # type: ignore[return-value]
561
557
  "PUT",
562
558
  __path,
@@ -595,8 +591,8 @@ class WatcherClient(NamespacedClient):
595
591
  """
596
592
  .. raw:: html
597
593
 
598
- <p>Query watches.
599
- Get all registered watches in a paginated manner and optionally filter watches by a query.</p>
594
+ <p>Query watches.</p>
595
+ <p>Get all registered watches in a paginated manner and optionally filter watches by a query.</p>
600
596
  <p>Note that only the <code>_id</code> and <code>metadata.*</code> fields are queryable or sortable.</p>
601
597
 
602
598
 
@@ -671,8 +667,8 @@ class WatcherClient(NamespacedClient):
671
667
  """
672
668
  .. raw:: html
673
669
 
674
- <p>Start the watch service.
675
- Start the Watcher service if it is not already running.</p>
670
+ <p>Start the watch service.</p>
671
+ <p>Start the Watcher service if it is not already running.</p>
676
672
 
677
673
 
678
674
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-start>`_
@@ -736,8 +732,8 @@ class WatcherClient(NamespacedClient):
736
732
  """
737
733
  .. raw:: html
738
734
 
739
- <p>Get Watcher statistics.
740
- This API always returns basic metrics.
735
+ <p>Get Watcher statistics.</p>
736
+ <p>This API always returns basic metrics.
741
737
  You retrieve more metrics by using the metric parameter.</p>
742
738
 
743
739
 
@@ -788,8 +784,8 @@ class WatcherClient(NamespacedClient):
788
784
  """
789
785
  .. raw:: html
790
786
 
791
- <p>Stop the watch service.
792
- Stop the Watcher service if it is running.</p>
787
+ <p>Stop the watch service.</p>
788
+ <p>Stop the Watcher service if it is running.</p>
793
789
 
794
790
 
795
791
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-stop>`_
@@ -844,8 +840,8 @@ class WatcherClient(NamespacedClient):
844
840
  """
845
841
  .. raw:: html
846
842
 
847
- <p>Update Watcher index settings.
848
- Update settings for the Watcher internal index (<code>.watches</code>).
843
+ <p>Update Watcher index settings.</p>
844
+ <p>Update settings for the Watcher internal index (<code>.watches</code>).
849
845
  Only a subset of settings can be modified.
850
846
  This includes <code>index.auto_expand_replicas</code>, <code>index.number_of_replicas</code>, <code>index.routing.allocation.exclude.*</code>,
851
847
  <code>index.routing.allocation.include.*</code> and <code>index.routing.allocation.require.*</code>.
@@ -45,8 +45,8 @@ class XPackClient(NamespacedClient):
45
45
  """
46
46
  .. raw:: html
47
47
 
48
- <p>Get information.
49
- The information provided by the API includes:</p>
48
+ <p>Get information.</p>
49
+ <p>The information provided by the API includes:</p>
50
50
  <ul>
51
51
  <li>Build information including the build number and timestamp.</li>
52
52
  <li>License information about the currently installed license.</li>
@@ -56,7 +56,8 @@ class XPackClient(NamespacedClient):
56
56
 
57
57
  `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-info>`_
58
58
 
59
- :param accept_enterprise: If this param is used it must be set to true
59
+ :param accept_enterprise: If used, this otherwise ignored parameter must be set
60
+ to true
60
61
  :param categories: A comma-separated list of the information categories to include
61
62
  in the response. For example, `build,license,features`.
62
63
  """
@@ -98,8 +99,8 @@ class XPackClient(NamespacedClient):
98
99
  """
99
100
  .. raw:: html
100
101
 
101
- <p>Get usage information.
102
- Get information about the features that are currently enabled and available under the current license.
102
+ <p>Get usage information.</p>
103
+ <p>Get information about the features that are currently enabled and available under the current license.
103
104
  The API also provides some usage statistics.</p>
104
105
 
105
106
 
@@ -33,12 +33,16 @@ from typing import (
33
33
  Union,
34
34
  )
35
35
 
36
+ from ..compat import safe_task
36
37
  from ..exceptions import ApiError, NotFoundError, TransportError
37
38
  from ..helpers.actions import (
38
39
  _TYPE_BULK_ACTION,
39
40
  _TYPE_BULK_ACTION_BODY,
40
41
  _TYPE_BULK_ACTION_HEADER,
41
42
  _TYPE_BULK_ACTION_HEADER_AND_BODY,
43
+ _TYPE_BULK_ACTION_HEADER_WITH_META_AND_BODY,
44
+ _TYPE_BULK_ACTION_WITH_META,
45
+ BulkMeta,
42
46
  _ActionChunker,
43
47
  _process_bulk_chunk_error,
44
48
  _process_bulk_chunk_success,
@@ -54,9 +58,10 @@ T = TypeVar("T")
54
58
 
55
59
 
56
60
  async def _chunk_actions(
57
- actions: AsyncIterable[_TYPE_BULK_ACTION_HEADER_AND_BODY],
61
+ actions: AsyncIterable[_TYPE_BULK_ACTION_HEADER_WITH_META_AND_BODY],
58
62
  chunk_size: int,
59
63
  max_chunk_bytes: int,
64
+ flush_after_seconds: Optional[float],
60
65
  serializer: Serializer,
61
66
  ) -> AsyncIterable[
62
67
  Tuple[
@@ -76,10 +81,42 @@ async def _chunk_actions(
76
81
  chunker = _ActionChunker(
77
82
  chunk_size=chunk_size, max_chunk_bytes=max_chunk_bytes, serializer=serializer
78
83
  )
79
- async for action, data in actions:
80
- ret = chunker.feed(action, data)
81
- if ret:
82
- yield ret
84
+
85
+ if not flush_after_seconds:
86
+ async for action, data in actions:
87
+ ret = chunker.feed(action, data)
88
+ if ret:
89
+ yield ret
90
+ else:
91
+ item_queue: asyncio.Queue[_TYPE_BULK_ACTION_HEADER_WITH_META_AND_BODY] = (
92
+ asyncio.Queue()
93
+ )
94
+
95
+ async def get_items() -> None:
96
+ try:
97
+ async for item in actions:
98
+ await item_queue.put(item)
99
+ finally:
100
+ await item_queue.put((BulkMeta.done, None))
101
+
102
+ async with safe_task(get_items()):
103
+ timeout: Optional[float] = flush_after_seconds
104
+ while True:
105
+ try:
106
+ action, data = await asyncio.wait_for(
107
+ item_queue.get(), timeout=timeout
108
+ )
109
+ timeout = flush_after_seconds
110
+ except asyncio.TimeoutError:
111
+ action, data = BulkMeta.flush, None
112
+ timeout = None
113
+
114
+ if action is BulkMeta.done:
115
+ break
116
+ ret = chunker.feed(action, data)
117
+ if ret:
118
+ yield ret
119
+
83
120
  ret = chunker.flush()
84
121
  if ret:
85
122
  yield ret
@@ -159,9 +196,13 @@ async def azip(
159
196
 
160
197
  async def async_streaming_bulk(
161
198
  client: AsyncElasticsearch,
162
- actions: Union[Iterable[_TYPE_BULK_ACTION], AsyncIterable[_TYPE_BULK_ACTION]],
199
+ actions: Union[
200
+ Iterable[_TYPE_BULK_ACTION_WITH_META],
201
+ AsyncIterable[_TYPE_BULK_ACTION_WITH_META],
202
+ ],
163
203
  chunk_size: int = 500,
164
204
  max_chunk_bytes: int = 100 * 1024 * 1024,
205
+ flush_after_seconds: Optional[float] = None,
165
206
  raise_on_error: bool = True,
166
207
  expand_action_callback: Callable[
167
208
  [_TYPE_BULK_ACTION], _TYPE_BULK_ACTION_HEADER_AND_BODY
@@ -194,6 +235,9 @@ async def async_streaming_bulk(
194
235
  :arg actions: iterable or async iterable containing the actions to be executed
195
236
  :arg chunk_size: number of docs in one chunk sent to es (default: 500)
196
237
  :arg max_chunk_bytes: the maximum size of the request in bytes (default: 100MB)
238
+ :arg flush_after_seconds: time in seconds after which a chunk is written even
239
+ if hasn't reached `chunk_size` or `max_chunk_bytes`. Set to 0 to not use a
240
+ timeout-based flush. (default: 0)
197
241
  :arg raise_on_error: raise ``BulkIndexError`` containing errors (as `.errors`)
198
242
  from the execution of the last chunk when some occur. By default we raise.
199
243
  :arg raise_on_exception: if ``False`` then don't propagate exceptions from
@@ -220,9 +264,14 @@ async def async_streaming_bulk(
220
264
  if isinstance(retry_on_status, int):
221
265
  retry_on_status = (retry_on_status,)
222
266
 
223
- async def map_actions() -> AsyncIterable[_TYPE_BULK_ACTION_HEADER_AND_BODY]:
267
+ async def map_actions() -> (
268
+ AsyncIterable[_TYPE_BULK_ACTION_HEADER_WITH_META_AND_BODY]
269
+ ):
224
270
  async for item in aiter(actions):
225
- yield expand_action_callback(item)
271
+ if isinstance(item, BulkMeta):
272
+ yield item, None
273
+ else:
274
+ yield expand_action_callback(item)
226
275
 
227
276
  serializer = client.transport.serializers.get_serializer("application/json")
228
277
 
@@ -234,7 +283,7 @@ async def async_streaming_bulk(
234
283
  ]
235
284
  bulk_actions: List[bytes]
236
285
  async for bulk_data, bulk_actions in _chunk_actions(
237
- map_actions(), chunk_size, max_chunk_bytes, serializer
286
+ map_actions(), chunk_size, max_chunk_bytes, flush_after_seconds, serializer
238
287
  ):
239
288
  for attempt in range(max_retries + 1):
240
289
  to_retry: List[bytes] = []