elasticsearch9 9.0.2__py3-none-any.whl → 9.1.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 (110) hide show
  1. elasticsearch9/__init__.py +3 -3
  2. elasticsearch9/_async/client/__init__.py +88 -244
  3. elasticsearch9/_async/client/async_search.py +4 -4
  4. elasticsearch9/_async/client/autoscaling.py +4 -4
  5. elasticsearch9/_async/client/cat.py +419 -51
  6. elasticsearch9/_async/client/ccr.py +13 -13
  7. elasticsearch9/_async/client/cluster.py +32 -22
  8. elasticsearch9/_async/client/connector.py +30 -30
  9. elasticsearch9/_async/client/dangling_indices.py +3 -3
  10. elasticsearch9/_async/client/enrich.py +5 -5
  11. elasticsearch9/_async/client/eql.py +14 -6
  12. elasticsearch9/_async/client/esql.py +125 -9
  13. elasticsearch9/_async/client/features.py +2 -2
  14. elasticsearch9/_async/client/fleet.py +3 -3
  15. elasticsearch9/_async/client/graph.py +1 -1
  16. elasticsearch9/_async/client/ilm.py +11 -11
  17. elasticsearch9/_async/client/indices.py +592 -113
  18. elasticsearch9/_async/client/inference.py +521 -44
  19. elasticsearch9/_async/client/ingest.py +9 -16
  20. elasticsearch9/_async/client/license.py +11 -11
  21. elasticsearch9/_async/client/logstash.py +3 -3
  22. elasticsearch9/_async/client/migration.py +3 -3
  23. elasticsearch9/_async/client/ml.py +75 -87
  24. elasticsearch9/_async/client/monitoring.py +1 -1
  25. elasticsearch9/_async/client/nodes.py +7 -7
  26. elasticsearch9/_async/client/query_rules.py +8 -8
  27. elasticsearch9/_async/client/rollup.py +9 -30
  28. elasticsearch9/_async/client/search_application.py +10 -10
  29. elasticsearch9/_async/client/searchable_snapshots.py +4 -4
  30. elasticsearch9/_async/client/security.py +79 -81
  31. elasticsearch9/_async/client/shutdown.py +3 -3
  32. elasticsearch9/_async/client/simulate.py +1 -1
  33. elasticsearch9/_async/client/slm.py +9 -9
  34. elasticsearch9/_async/client/snapshot.py +64 -21
  35. elasticsearch9/_async/client/sql.py +6 -6
  36. elasticsearch9/_async/client/ssl.py +1 -1
  37. elasticsearch9/_async/client/synonyms.py +26 -7
  38. elasticsearch9/_async/client/tasks.py +4 -4
  39. elasticsearch9/_async/client/text_structure.py +4 -4
  40. elasticsearch9/_async/client/transform.py +11 -11
  41. elasticsearch9/_async/client/watcher.py +17 -15
  42. elasticsearch9/_async/client/xpack.py +2 -2
  43. elasticsearch9/_otel.py +8 -8
  44. elasticsearch9/_sync/client/__init__.py +88 -244
  45. elasticsearch9/_sync/client/async_search.py +4 -4
  46. elasticsearch9/_sync/client/autoscaling.py +4 -4
  47. elasticsearch9/_sync/client/cat.py +419 -51
  48. elasticsearch9/_sync/client/ccr.py +13 -13
  49. elasticsearch9/_sync/client/cluster.py +32 -22
  50. elasticsearch9/_sync/client/connector.py +30 -30
  51. elasticsearch9/_sync/client/dangling_indices.py +3 -3
  52. elasticsearch9/_sync/client/enrich.py +5 -5
  53. elasticsearch9/_sync/client/eql.py +14 -6
  54. elasticsearch9/_sync/client/esql.py +125 -9
  55. elasticsearch9/_sync/client/features.py +2 -2
  56. elasticsearch9/_sync/client/fleet.py +3 -3
  57. elasticsearch9/_sync/client/graph.py +1 -1
  58. elasticsearch9/_sync/client/ilm.py +11 -11
  59. elasticsearch9/_sync/client/indices.py +592 -113
  60. elasticsearch9/_sync/client/inference.py +521 -44
  61. elasticsearch9/_sync/client/ingest.py +9 -16
  62. elasticsearch9/_sync/client/license.py +11 -11
  63. elasticsearch9/_sync/client/logstash.py +3 -3
  64. elasticsearch9/_sync/client/migration.py +3 -3
  65. elasticsearch9/_sync/client/ml.py +75 -87
  66. elasticsearch9/_sync/client/monitoring.py +1 -1
  67. elasticsearch9/_sync/client/nodes.py +7 -7
  68. elasticsearch9/_sync/client/query_rules.py +8 -8
  69. elasticsearch9/_sync/client/rollup.py +9 -30
  70. elasticsearch9/_sync/client/search_application.py +10 -10
  71. elasticsearch9/_sync/client/searchable_snapshots.py +4 -4
  72. elasticsearch9/_sync/client/security.py +79 -81
  73. elasticsearch9/_sync/client/shutdown.py +3 -3
  74. elasticsearch9/_sync/client/simulate.py +1 -1
  75. elasticsearch9/_sync/client/slm.py +9 -9
  76. elasticsearch9/_sync/client/snapshot.py +64 -21
  77. elasticsearch9/_sync/client/sql.py +6 -6
  78. elasticsearch9/_sync/client/ssl.py +1 -1
  79. elasticsearch9/_sync/client/synonyms.py +26 -7
  80. elasticsearch9/_sync/client/tasks.py +4 -4
  81. elasticsearch9/_sync/client/text_structure.py +4 -4
  82. elasticsearch9/_sync/client/transform.py +11 -11
  83. elasticsearch9/_sync/client/watcher.py +17 -15
  84. elasticsearch9/_sync/client/xpack.py +2 -2
  85. elasticsearch9/_version.py +1 -1
  86. elasticsearch9/compat.py +5 -0
  87. elasticsearch9/dsl/__init__.py +2 -1
  88. elasticsearch9/dsl/aggs.py +20 -0
  89. elasticsearch9/dsl/document_base.py +177 -17
  90. elasticsearch9/dsl/field.py +230 -37
  91. elasticsearch9/dsl/query.py +6 -3
  92. elasticsearch9/dsl/response/__init__.py +1 -1
  93. elasticsearch9/dsl/types.py +169 -11
  94. elasticsearch9/dsl/utils.py +1 -1
  95. elasticsearch9/{dsl/_sync/_sync_check → esql}/__init__.py +2 -0
  96. elasticsearch9/esql/esql.py +1105 -0
  97. elasticsearch9/esql/esql1.py1 +307 -0
  98. elasticsearch9/esql/functions.py +1738 -0
  99. {elasticsearch9-9.0.2.dist-info → elasticsearch9-9.1.0.dist-info}/METADATA +3 -4
  100. elasticsearch9-9.1.0.dist-info/RECORD +164 -0
  101. elasticsearch9/dsl/_sync/_sync_check/document.py +0 -514
  102. elasticsearch9/dsl/_sync/_sync_check/faceted_search.py +0 -50
  103. elasticsearch9/dsl/_sync/_sync_check/index.py +0 -597
  104. elasticsearch9/dsl/_sync/_sync_check/mapping.py +0 -49
  105. elasticsearch9/dsl/_sync/_sync_check/search.py +0 -230
  106. elasticsearch9/dsl/_sync/_sync_check/update_by_query.py +0 -45
  107. elasticsearch9-9.0.2.dist-info/RECORD +0 -167
  108. {elasticsearch9-9.0.2.dist-info → elasticsearch9-9.1.0.dist-info}/WHEEL +0 -0
  109. {elasticsearch9-9.0.2.dist-info → elasticsearch9-9.1.0.dist-info}/licenses/LICENSE +0 -0
  110. {elasticsearch9-9.0.2.dist-info → elasticsearch9-9.1.0.dist-info}/licenses/NOTICE +0 -0
@@ -44,7 +44,7 @@ class TransformClient(NamespacedClient):
44
44
  <p>Delete a transform.</p>
45
45
 
46
46
 
47
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-delete-transform>`_
47
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-delete-transform>`_
48
48
 
49
49
  :param transform_id: Identifier for the transform.
50
50
  :param delete_dest_index: If this value is true, the destination index is deleted
@@ -108,7 +108,7 @@ class TransformClient(NamespacedClient):
108
108
  Get configuration information for transforms.</p>
109
109
 
110
110
 
111
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-get-transform>`_
111
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-get-transform>`_
112
112
 
113
113
  :param transform_id: Identifier for the transform. It can be a transform identifier
114
114
  or a wildcard expression. You can get information for all transforms by using
@@ -181,7 +181,7 @@ class TransformClient(NamespacedClient):
181
181
  <p>Get usage information for transforms.</p>
182
182
 
183
183
 
184
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-get-transform-stats>`_
184
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-get-transform-stats>`_
185
185
 
186
186
  :param transform_id: Identifier for the transform. It can be a transform identifier
187
187
  or a wildcard expression. You can get information for all transforms by using
@@ -269,7 +269,7 @@ class TransformClient(NamespacedClient):
269
269
  types of the source index and the transform aggregations.</p>
270
270
 
271
271
 
272
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-preview-transform>`_
272
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-preview-transform>`_
273
273
 
274
274
  :param transform_id: Identifier for the transform to preview. If you specify
275
275
  this path parameter, you cannot provide transform configuration details in
@@ -406,7 +406,7 @@ class TransformClient(NamespacedClient):
406
406
  give users any privileges on <code>.data-frame-internal*</code> indices.</p>
407
407
 
408
408
 
409
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-put-transform>`_
409
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-put-transform>`_
410
410
 
411
411
  :param transform_id: Identifier for the transform. This identifier can contain
412
412
  lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores.
@@ -512,7 +512,7 @@ class TransformClient(NamespacedClient):
512
512
  If the destination index was created by the transform, it is deleted.</p>
513
513
 
514
514
 
515
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-reset-transform>`_
515
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-reset-transform>`_
516
516
 
517
517
  :param transform_id: Identifier for the transform. This identifier can contain
518
518
  lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores.
@@ -572,7 +572,7 @@ class TransformClient(NamespacedClient):
572
572
  is called again in the meantime.</p>
573
573
 
574
574
 
575
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-schedule-now-transform>`_
575
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-schedule-now-transform>`_
576
576
 
577
577
  :param transform_id: Identifier for the transform.
578
578
  :param timeout: Controls the time to wait for the scheduling to take place
@@ -635,7 +635,7 @@ class TransformClient(NamespacedClient):
635
635
  destination indices, the transform fails when it attempts unauthorized operations.</p>
636
636
 
637
637
 
638
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-start-transform>`_
638
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-start-transform>`_
639
639
 
640
640
  :param transform_id: Identifier for the transform.
641
641
  :param from_: Restricts the set of transformed entities to those changed after
@@ -693,7 +693,7 @@ class TransformClient(NamespacedClient):
693
693
  Stops one or more transforms.</p>
694
694
 
695
695
 
696
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-stop-transform>`_
696
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-stop-transform>`_
697
697
 
698
698
  :param transform_id: Identifier for the transform. To stop multiple transforms,
699
699
  use a comma-separated list or a wildcard expression. To stop all transforms,
@@ -795,7 +795,7 @@ class TransformClient(NamespacedClient):
795
795
  time of update and runs with those privileges.</p>
796
796
 
797
797
 
798
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-update-transform>`_
798
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-update-transform>`_
799
799
 
800
800
  :param transform_id: Identifier for the transform.
801
801
  :param defer_validation: When true, deferrable validations are not run. This
@@ -890,7 +890,7 @@ class TransformClient(NamespacedClient):
890
890
  You may want to perform a recent cluster backup prior to the upgrade.</p>
891
891
 
892
892
 
893
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-transform-upgrade-transforms>`_
893
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-transform-upgrade-transforms>`_
894
894
 
895
895
  :param dry_run: When true, the request checks for updates but does not run them.
896
896
  :param timeout: Period to wait for a response. If no response is received before
@@ -45,10 +45,11 @@ class WatcherClient(NamespacedClient):
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>
47
47
  <p>Acknowledging an action throttles further executions of that action until its <code>ack.state</code> is reset to <code>awaits_successful_execution</code>.
48
- This happens when the condition of the watch is not met (the condition evaluates to false).</p>
48
+ This happens when the condition of the watch is not met (the condition evaluates to false).
49
+ To demonstrate how throttling works in practice and how it can be configured for individual actions within a watch, refer to External documentation.</p>
49
50
 
50
51
 
51
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-ack-watch>`_
52
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-ack-watch>`_
52
53
 
53
54
  :param watch_id: The watch identifier.
54
55
  :param action_id: A comma-separated list of the action identifiers to acknowledge.
@@ -104,7 +105,7 @@ class WatcherClient(NamespacedClient):
104
105
  A watch can be either active or inactive.</p>
105
106
 
106
107
 
107
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-activate-watch>`_
108
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-activate-watch>`_
108
109
 
109
110
  :param watch_id: The watch identifier.
110
111
  """
@@ -148,7 +149,7 @@ class WatcherClient(NamespacedClient):
148
149
  A watch can be either active or inactive.</p>
149
150
 
150
151
 
151
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-deactivate-watch>`_
152
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-deactivate-watch>`_
152
153
 
153
154
  :param watch_id: The watch identifier.
154
155
  """
@@ -196,7 +197,7 @@ class WatcherClient(NamespacedClient):
196
197
  When Elasticsearch security features are enabled, make sure no write privileges are granted to anyone for the <code>.watches</code> index.</p>
197
198
 
198
199
 
199
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-delete-watch>`_
200
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-delete-watch>`_
200
201
 
201
202
  :param id: The watch identifier.
202
203
  """
@@ -274,10 +275,11 @@ class WatcherClient(NamespacedClient):
274
275
  This serves as great tool for testing and debugging your watches prior to adding them to Watcher.</p>
275
276
  <p>When Elasticsearch security features are enabled on your cluster, watches are run with the privileges of the user that stored the watches.
276
277
  If your user is allowed to read index <code>a</code>, but not index <code>b</code>, then the exact same set of rules will apply during execution of a watch.</p>
277
- <p>When using the run watch API, the authorization data of the user that called the API will be used as a base, instead of the information who stored the watch.</p>
278
+ <p>When using the run watch API, the authorization data of the user that called the API will be used as a base, instead of the information who stored the watch.
279
+ Refer to the external documentation for examples of watch execution requests, including existing, customized, and inline watches.</p>
278
280
 
279
281
 
280
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-execute-watch>`_
282
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-execute-watch>`_
281
283
 
282
284
  :param id: The watch identifier.
283
285
  :param action_modes: Determines how to handle the watch actions as part of the
@@ -365,7 +367,7 @@ class WatcherClient(NamespacedClient):
365
367
  Only a subset of settings are shown, for example <code>index.auto_expand_replicas</code> and <code>index.number_of_replicas</code>.</p>
366
368
 
367
369
 
368
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-get-settings>`_
370
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-get-settings>`_
369
371
 
370
372
  :param master_timeout: The period to wait for a connection to the master node.
371
373
  If no response is received before the timeout expires, the request fails
@@ -410,7 +412,7 @@ class WatcherClient(NamespacedClient):
410
412
  <p>Get a watch.</p>
411
413
 
412
414
 
413
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-get-watch>`_
415
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-get-watch>`_
414
416
 
415
417
  :param id: The watch identifier.
416
418
  """
@@ -485,7 +487,7 @@ class WatcherClient(NamespacedClient):
485
487
  If the user is able to read index <code>a</code>, but not index <code>b</code>, the same will apply when the watch runs.</p>
486
488
 
487
489
 
488
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-put-watch>`_
490
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-put-watch>`_
489
491
 
490
492
  :param id: The identifier for the watch.
491
493
  :param actions: The list of actions that will be run if the condition matches.
@@ -598,7 +600,7 @@ class WatcherClient(NamespacedClient):
598
600
  <p>Note that only the <code>_id</code> and <code>metadata.*</code> fields are queryable or sortable.</p>
599
601
 
600
602
 
601
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-query-watches>`_
603
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-query-watches>`_
602
604
 
603
605
  :param from_: The offset from the first result to fetch. It must be non-negative.
604
606
  :param query: A query that filters the watches to be returned.
@@ -673,7 +675,7 @@ class WatcherClient(NamespacedClient):
673
675
  Start the Watcher service if it is not already running.</p>
674
676
 
675
677
 
676
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-start>`_
678
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-start>`_
677
679
 
678
680
  :param master_timeout: Period to wait for a connection to the master node.
679
681
  """
@@ -739,7 +741,7 @@ class WatcherClient(NamespacedClient):
739
741
  You retrieve more metrics by using the metric parameter.</p>
740
742
 
741
743
 
742
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-stats>`_
744
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-stats>`_
743
745
 
744
746
  :param metric: Defines which additional metrics are included in the response.
745
747
  :param emit_stacktraces: Defines whether stack traces are generated for each
@@ -790,7 +792,7 @@ class WatcherClient(NamespacedClient):
790
792
  Stop the Watcher service if it is running.</p>
791
793
 
792
794
 
793
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-stop>`_
795
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-stop>`_
794
796
 
795
797
  :param master_timeout: The period to wait for the master node. If the master
796
798
  node is not available before the timeout expires, the request fails and returns
@@ -851,7 +853,7 @@ class WatcherClient(NamespacedClient):
851
853
  Watcher shards must always be in the <code>data_content</code> tier.</p>
852
854
 
853
855
 
854
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-watcher-update-settings>`_
856
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-watcher-update-settings>`_
855
857
 
856
858
  :param index_auto_expand_replicas:
857
859
  :param index_number_of_replicas:
@@ -54,7 +54,7 @@ class XPackClient(NamespacedClient):
54
54
  </ul>
55
55
 
56
56
 
57
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/operation/operation-info>`_
57
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-info>`_
58
58
 
59
59
  :param accept_enterprise: If this param is used it must be set to true
60
60
  :param categories: A comma-separated list of the information categories to include
@@ -103,7 +103,7 @@ class XPackClient(NamespacedClient):
103
103
  The API also provides some usage statistics.</p>
104
104
 
105
105
 
106
- `<https://www.elastic.co/docs/api/doc/elasticsearch/v9/group/endpoint-xpack>`_
106
+ `<https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-xpack>`_
107
107
 
108
108
  :param master_timeout: The period to wait for a connection to the master node.
109
109
  If no response is received before the timeout expires, the request fails
@@ -15,4 +15,4 @@
15
15
  # specific language governing permissions and limitations
16
16
  # under the License.
17
17
 
18
- __versionstr__ = "9.0.2"
18
+ __versionstr__ = "9.1.0"
elasticsearch9/compat.py CHANGED
@@ -16,12 +16,15 @@
16
16
  # under the License.
17
17
 
18
18
  import inspect
19
+ import os
19
20
  import sys
20
21
  from pathlib import Path
21
22
  from typing import Tuple, Type, Union
22
23
 
23
24
  string_types: Tuple[Type[str], Type[bytes]] = (str, bytes)
24
25
 
26
+ DISABLE_WARN_STACKLEVEL_ENV_VAR = "DISABLE_WARN_STACKLEVEL"
27
+
25
28
 
26
29
  def to_str(x: Union[str, bytes], encoding: str = "ascii") -> str:
27
30
  if not isinstance(x, str):
@@ -37,6 +40,8 @@ def to_bytes(x: Union[str, bytes], encoding: str = "ascii") -> bytes:
37
40
 
38
41
  def warn_stacklevel() -> int:
39
42
  """Dynamically determine warning stacklevel for warnings based on the call stack"""
43
+ if os.environ.get(DISABLE_WARN_STACKLEVEL_ENV_VAR) in ["1", "true", "True"]:
44
+ return 0
40
45
  try:
41
46
  # Grab the root module from the current module '__name__'
42
47
  module_name = __name__.partition(".")[0]
@@ -19,7 +19,7 @@ from . import async_connections, connections
19
19
  from .aggs import A, Agg
20
20
  from .analysis import analyzer, char_filter, normalizer, token_filter, tokenizer
21
21
  from .document import AsyncDocument, Document
22
- from .document_base import InnerDoc, M, MetaField, mapped_field
22
+ from .document_base import E, InnerDoc, M, MetaField, mapped_field
23
23
  from .exceptions import (
24
24
  ElasticsearchDslException,
25
25
  IllegalOperation,
@@ -135,6 +135,7 @@ __all__ = [
135
135
  "Double",
136
136
  "DoubleRange",
137
137
  "DslBase",
138
+ "E",
138
139
  "ElasticsearchDslException",
139
140
  "EmptySearch",
140
141
  "Facet",
@@ -373,6 +373,12 @@ class Boxplot(Agg[_R]):
373
373
  :arg compression: Limits the maximum number of nodes used by the
374
374
  underlying TDigest algorithm to `20 * compression`, enabling
375
375
  control of memory usage and approximation error.
376
+ :arg execution_hint: The default implementation of TDigest is
377
+ optimized for performance, scaling to millions or even billions of
378
+ sample values while maintaining acceptable accuracy levels (close
379
+ to 1% relative error for millions of samples in some cases). To
380
+ use an implementation optimized for accuracy, set this parameter
381
+ to high_accuracy instead. Defaults to `default` if omitted.
376
382
  :arg field: The field on which to run the aggregation.
377
383
  :arg missing: The value to apply to documents that do not have a
378
384
  value. By default, documents without a value are ignored.
@@ -385,6 +391,9 @@ class Boxplot(Agg[_R]):
385
391
  self,
386
392
  *,
387
393
  compression: Union[float, "DefaultType"] = DEFAULT,
394
+ execution_hint: Union[
395
+ Literal["default", "high_accuracy"], "DefaultType"
396
+ ] = DEFAULT,
388
397
  field: Union[str, "InstrumentedField", "DefaultType"] = DEFAULT,
389
398
  missing: Union[str, int, float, bool, "DefaultType"] = DEFAULT,
390
399
  script: Union["types.Script", Dict[str, Any], "DefaultType"] = DEFAULT,
@@ -392,6 +401,7 @@ class Boxplot(Agg[_R]):
392
401
  ):
393
402
  super().__init__(
394
403
  compression=compression,
404
+ execution_hint=execution_hint,
395
405
  field=field,
396
406
  missing=missing,
397
407
  script=script,
@@ -1900,6 +1910,12 @@ class MedianAbsoluteDeviation(Agg[_R]):
1900
1910
  underlying TDigest algorithm to `20 * compression`, enabling
1901
1911
  control of memory usage and approximation error. Defaults to
1902
1912
  `1000` if omitted.
1913
+ :arg execution_hint: The default implementation of TDigest is
1914
+ optimized for performance, scaling to millions or even billions of
1915
+ sample values while maintaining acceptable accuracy levels (close
1916
+ to 1% relative error for millions of samples in some cases). To
1917
+ use an implementation optimized for accuracy, set this parameter
1918
+ to high_accuracy instead. Defaults to `default` if omitted.
1903
1919
  :arg format:
1904
1920
  :arg field: The field on which to run the aggregation.
1905
1921
  :arg missing: The value to apply to documents that do not have a
@@ -1913,6 +1929,9 @@ class MedianAbsoluteDeviation(Agg[_R]):
1913
1929
  self,
1914
1930
  *,
1915
1931
  compression: Union[float, "DefaultType"] = DEFAULT,
1932
+ execution_hint: Union[
1933
+ Literal["default", "high_accuracy"], "DefaultType"
1934
+ ] = DEFAULT,
1916
1935
  format: Union[str, "DefaultType"] = DEFAULT,
1917
1936
  field: Union[str, "InstrumentedField", "DefaultType"] = DEFAULT,
1918
1937
  missing: Union[str, int, float, bool, "DefaultType"] = DEFAULT,
@@ -1921,6 +1940,7 @@ class MedianAbsoluteDeviation(Agg[_R]):
1921
1940
  ):
1922
1941
  super().__init__(
1923
1942
  compression=compression,
1943
+ execution_hint=execution_hint,
1924
1944
  format=format,
1925
1945
  field=field,
1926
1946
  missing=missing,
@@ -15,6 +15,7 @@
15
15
  # specific language governing permissions and limitations
16
16
  # under the License.
17
17
 
18
+ import json
18
19
  from datetime import date, datetime
19
20
  from fnmatch import fnmatch
20
21
  from typing import (
@@ -56,7 +57,163 @@ class MetaField:
56
57
  self.args, self.kwargs = args, kwargs
57
58
 
58
59
 
59
- class InstrumentedField:
60
+ class InstrumentedExpression:
61
+ """Proxy object for a ES|QL expression."""
62
+
63
+ def __init__(self, expr: str):
64
+ self._expr = expr
65
+
66
+ def _render_value(self, value: Any) -> str:
67
+ if isinstance(value, InstrumentedExpression):
68
+ return str(value)
69
+ return json.dumps(value)
70
+
71
+ def __str__(self) -> str:
72
+ return self._expr
73
+
74
+ def __repr__(self) -> str:
75
+ return f"InstrumentedExpression[{self._expr}]"
76
+
77
+ def __pos__(self) -> "InstrumentedExpression":
78
+ return self
79
+
80
+ def __neg__(self) -> "InstrumentedExpression":
81
+ return InstrumentedExpression(f"-({self._expr})")
82
+
83
+ def __eq__(self, value: Any) -> "InstrumentedExpression": # type: ignore[override]
84
+ return InstrumentedExpression(f"{self._expr} == {self._render_value(value)}")
85
+
86
+ def __ne__(self, value: Any) -> "InstrumentedExpression": # type: ignore[override]
87
+ return InstrumentedExpression(f"{self._expr} != {self._render_value(value)}")
88
+
89
+ def __lt__(self, value: Any) -> "InstrumentedExpression":
90
+ return InstrumentedExpression(f"{self._expr} < {self._render_value(value)}")
91
+
92
+ def __gt__(self, value: Any) -> "InstrumentedExpression":
93
+ return InstrumentedExpression(f"{self._expr} > {self._render_value(value)}")
94
+
95
+ def __le__(self, value: Any) -> "InstrumentedExpression":
96
+ return InstrumentedExpression(f"{self._expr} <= {self._render_value(value)}")
97
+
98
+ def __ge__(self, value: Any) -> "InstrumentedExpression":
99
+ return InstrumentedExpression(f"{self._expr} >= {self._render_value(value)}")
100
+
101
+ def __add__(self, value: Any) -> "InstrumentedExpression":
102
+ return InstrumentedExpression(f"{self._expr} + {self._render_value(value)}")
103
+
104
+ def __radd__(self, value: Any) -> "InstrumentedExpression":
105
+ return InstrumentedExpression(f"{self._render_value(value)} + {self._expr}")
106
+
107
+ def __sub__(self, value: Any) -> "InstrumentedExpression":
108
+ return InstrumentedExpression(f"{self._expr} - {self._render_value(value)}")
109
+
110
+ def __rsub__(self, value: Any) -> "InstrumentedExpression":
111
+ return InstrumentedExpression(f"{self._render_value(value)} - {self._expr}")
112
+
113
+ def __mul__(self, value: Any) -> "InstrumentedExpression":
114
+ return InstrumentedExpression(f"{self._expr} * {self._render_value(value)}")
115
+
116
+ def __rmul__(self, value: Any) -> "InstrumentedExpression":
117
+ return InstrumentedExpression(f"{self._render_value(value)} * {self._expr}")
118
+
119
+ def __truediv__(self, value: Any) -> "InstrumentedExpression":
120
+ return InstrumentedExpression(f"{self._expr} / {self._render_value(value)}")
121
+
122
+ def __rtruediv__(self, value: Any) -> "InstrumentedExpression":
123
+ return InstrumentedExpression(f"{self._render_value(value)} / {self._expr}")
124
+
125
+ def __mod__(self, value: Any) -> "InstrumentedExpression":
126
+ return InstrumentedExpression(f"{self._expr} % {self._render_value(value)}")
127
+
128
+ def __rmod__(self, value: Any) -> "InstrumentedExpression":
129
+ return InstrumentedExpression(f"{self._render_value(value)} % {self._expr}")
130
+
131
+ def is_null(self) -> "InstrumentedExpression":
132
+ """Compare the expression against NULL."""
133
+ return InstrumentedExpression(f"{self._expr} IS NULL")
134
+
135
+ def is_not_null(self) -> "InstrumentedExpression":
136
+ """Compare the expression against NOT NULL."""
137
+ return InstrumentedExpression(f"{self._expr} IS NOT NULL")
138
+
139
+ def in_(self, *values: Any) -> "InstrumentedExpression":
140
+ """Test if the expression equals one of the given values."""
141
+ rendered_values = ", ".join([f"{value}" for value in values])
142
+ return InstrumentedExpression(f"{self._expr} IN ({rendered_values})")
143
+
144
+ def like(self, *patterns: str) -> "InstrumentedExpression":
145
+ """Filter the expression using a string pattern."""
146
+ if len(patterns) == 1:
147
+ return InstrumentedExpression(
148
+ f"{self._expr} LIKE {self._render_value(patterns[0])}"
149
+ )
150
+ else:
151
+ return InstrumentedExpression(
152
+ f'{self._expr} LIKE ({", ".join([self._render_value(p) for p in patterns])})'
153
+ )
154
+
155
+ def rlike(self, *patterns: str) -> "InstrumentedExpression":
156
+ """Filter the expression using a regular expression."""
157
+ if len(patterns) == 1:
158
+ return InstrumentedExpression(
159
+ f"{self._expr} RLIKE {self._render_value(patterns[0])}"
160
+ )
161
+ else:
162
+ return InstrumentedExpression(
163
+ f'{self._expr} RLIKE ({", ".join([self._render_value(p) for p in patterns])})'
164
+ )
165
+
166
+ def match(self, query: str) -> "InstrumentedExpression":
167
+ """Perform a match query on the field."""
168
+ return InstrumentedExpression(f"{self._expr}:{self._render_value(query)}")
169
+
170
+ def asc(self) -> "InstrumentedExpression":
171
+ """Return the field name representation for ascending sort order.
172
+
173
+ For use in ES|QL queries only.
174
+ """
175
+ return InstrumentedExpression(f"{self._expr} ASC")
176
+
177
+ def desc(self) -> "InstrumentedExpression":
178
+ """Return the field name representation for descending sort order.
179
+
180
+ For use in ES|QL queries only.
181
+ """
182
+ return InstrumentedExpression(f"{self._expr} DESC")
183
+
184
+ def nulls_first(self) -> "InstrumentedExpression":
185
+ """Return the field name representation for nulls first sort order.
186
+
187
+ For use in ES|QL queries only.
188
+ """
189
+ return InstrumentedExpression(f"{self._expr} NULLS FIRST")
190
+
191
+ def nulls_last(self) -> "InstrumentedExpression":
192
+ """Return the field name representation for nulls last sort order.
193
+
194
+ For use in ES|QL queries only.
195
+ """
196
+ return InstrumentedExpression(f"{self._expr} NULLS LAST")
197
+
198
+ def where(
199
+ self, *expressions: Union[str, "InstrumentedExpression"]
200
+ ) -> "InstrumentedExpression":
201
+ """Add a condition to be met for the row to be included.
202
+
203
+ Use only in expressions given in the ``STATS`` command.
204
+ """
205
+ if len(expressions) == 1:
206
+ return InstrumentedExpression(f"{self._expr} WHERE {expressions[0]}")
207
+ else:
208
+ return InstrumentedExpression(
209
+ f'{self._expr} WHERE {" AND ".join([f"({expr})" for expr in expressions])}'
210
+ )
211
+
212
+
213
+ E = InstrumentedExpression
214
+
215
+
216
+ class InstrumentedField(InstrumentedExpression):
60
217
  """Proxy object for a mapped document field.
61
218
 
62
219
  An object of this instance is returned when a field is accessed as a class
@@ -71,8 +228,8 @@ class InstrumentedField:
71
228
  s = s.sort(-MyDocument.name) # sort by name in descending order
72
229
  """
73
230
 
74
- def __init__(self, name: str, field: Field):
75
- self._name = name
231
+ def __init__(self, name: str, field: Optional[Field]):
232
+ super().__init__(name)
76
233
  self._field = field
77
234
 
78
235
  # note that the return value type here assumes classes will only be used to
@@ -83,26 +240,29 @@ class InstrumentedField:
83
240
  # first let's see if this is an attribute of this object
84
241
  return super().__getattribute__(attr) # type: ignore[no-any-return]
85
242
  except AttributeError:
86
- try:
87
- # next we see if we have a sub-field with this name
88
- return InstrumentedField(f"{self._name}.{attr}", self._field[attr])
89
- except KeyError:
90
- # lastly we let the wrapped field resolve this attribute
91
- return getattr(self._field, attr) # type: ignore[no-any-return]
92
-
93
- def __pos__(self) -> str:
243
+ if self._field:
244
+ try:
245
+ # next we see if we have a sub-field with this name
246
+ return InstrumentedField(f"{self._expr}.{attr}", self._field[attr])
247
+ except KeyError:
248
+ # lastly we let the wrapped field resolve this attribute
249
+ return getattr(self._field, attr) # type: ignore[no-any-return]
250
+ else:
251
+ raise
252
+
253
+ def __pos__(self) -> str: # type: ignore[override]
94
254
  """Return the field name representation for ascending sort order"""
95
- return f"{self._name}"
255
+ return f"{self._expr}"
96
256
 
97
- def __neg__(self) -> str:
257
+ def __neg__(self) -> str: # type: ignore[override]
98
258
  """Return the field name representation for descending sort order"""
99
- return f"-{self._name}"
259
+ return f"-{self._expr}"
100
260
 
101
261
  def __str__(self) -> str:
102
- return self._name
262
+ return self._expr
103
263
 
104
264
  def __repr__(self) -> str:
105
- return f"InstrumentedField[{self._name}]"
265
+ return f"InstrumentedField[{self._expr}]"
106
266
 
107
267
 
108
268
  class DocumentMeta(type):
@@ -171,7 +331,7 @@ class DocumentOptions:
171
331
  # # ignore attributes
172
332
  # field10: ClassVar[string] = "a regular class variable"
173
333
  annotations = attrs.get("__annotations__", {})
174
- fields = set([n for n in attrs if isinstance(attrs[n], Field)])
334
+ fields = {n for n in attrs if isinstance(attrs[n], Field)}
175
335
  fields.update(annotations.keys())
176
336
  field_defaults = {}
177
337
  for name in fields: