diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 062264ff..d2ee42bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,7 +50,7 @@ To run the code generation make sure you have pre-requisites installed: Then you should be able to run the code generation by invoking: ``` -$ python utils/generate-api.py +$ python utils/generate-api.py 8.0.0-SNAPSHOT ``` ## Contributing Code Changes diff --git a/elasticsearch/_async/client/__init__.py b/elasticsearch/_async/client/__init__.py index c506cfe6..69c91dc5 100644 --- a/elasticsearch/_async/client/__init__.py +++ b/elasticsearch/_async/client/__init__.py @@ -32,6 +32,7 @@ from .deprecation import DeprecationClient from .enrich import EnrichClient from .eql import EqlClient from .features import FeaturesClient +from .fleet import FleetClient from .graph import GraphClient from .ilm import IlmClient from .indices import IndicesClient @@ -46,6 +47,7 @@ from .remote import RemoteClient from .rollup import RollupClient from .searchable_snapshots import SearchableSnapshotsClient from .security import SecurityClient +from .shutdown import ShutdownClient from .slm import SlmClient from .snapshot import SnapshotClient from .sql import SqlClient @@ -224,6 +226,7 @@ class AsyncElasticsearch(object): self.enrich = EnrichClient(self) self.eql = EqlClient(self) self.features = FeaturesClient(self) + self.fleet = FleetClient(self) self.graph = GraphClient(self) self.ilm = IlmClient(self) self.license = LicenseClient(self) @@ -235,6 +238,7 @@ class AsyncElasticsearch(object): self.searchable_snapshots = SearchableSnapshotsClient(self) self.security = SecurityClient(self) self.slm = SlmClient(self) + self.shutdown = ShutdownClient(self) self.sql = SqlClient(self) self.ssl = SslClient(self) self.text_structure = TextStructureClient(self) diff --git a/elasticsearch/_async/client/cluster.py b/elasticsearch/_async/client/cluster.py index e47fb31a..78c11c86 100644 --- a/elasticsearch/_async/client/cluster.py +++ b/elasticsearch/_async/client/cluster.py @@ -192,7 +192,7 @@ class ClusterClient(NamespacedClient): """ Returns cluster settings. - ``_ + ``_ :arg flat_settings: Return settings in flat format (default: false) diff --git a/elasticsearch/_async/client/fleet.py b/elasticsearch/_async/client/fleet.py new file mode 100644 index 00000000..3f98b968 --- /dev/null +++ b/elasticsearch/_async/client/fleet.py @@ -0,0 +1,48 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from .utils import SKIP_IN_PATH, NamespacedClient, _make_path, query_params + + +class FleetClient(NamespacedClient): + @query_params("checkpoints", "timeout", "wait_for_advance") + async def global_checkpoints(self, index, params=None, headers=None): + """ + Returns the current global checkpoints for an index. This API is design for + internal use by the fleet server project. + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg index: The name of the index. + :arg checkpoints: Comma separated list of checkpoints + :arg timeout: Timeout to wait for global checkpoint to advance + Default: 30s + :arg wait_for_advance: Whether to wait for the global checkpoint + to advance past the specified current checkpoints Default: false + """ + if index in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'index'.") + + return await self.transport.perform_request( + "GET", + _make_path(index, "_fleet", "global_checkpoints"), + params=params, + headers=headers, + ) diff --git a/elasticsearch/_async/client/fleet.pyi b/elasticsearch/_async/client/fleet.pyi new file mode 100644 index 00000000..e1872cdd --- /dev/null +++ b/elasticsearch/_async/client/fleet.pyi @@ -0,0 +1,40 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from typing import Any, Collection, MutableMapping, Optional, Union + +from .utils import NamespacedClient + +class FleetClient(NamespacedClient): + async def global_checkpoints( + self, + index: Any, + *, + checkpoints: Optional[Any] = ..., + timeout: Optional[Any] = ..., + wait_for_advance: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/_async/client/ingest.py b/elasticsearch/_async/client/ingest.py index d3cd793c..6a62fd9a 100644 --- a/elasticsearch/_async/client/ingest.py +++ b/elasticsearch/_async/client/ingest.py @@ -117,3 +117,14 @@ class IngestClient(NamespacedClient): return await self.transport.perform_request( "GET", "/_ingest/processor/grok", params=params, headers=headers ) + + @query_params() + async def geo_ip_stats(self, params=None, headers=None): + """ + Returns statistical information about geoip databases + + ``_ + """ + return await self.transport.perform_request( + "GET", "/_ingest/geoip/stats", params=params, headers=headers + ) diff --git a/elasticsearch/_async/client/ingest.pyi b/elasticsearch/_async/client/ingest.pyi index 505fc7ab..945c4a05 100644 --- a/elasticsearch/_async/client/ingest.pyi +++ b/elasticsearch/_async/client/ingest.pyi @@ -103,3 +103,17 @@ class IngestClient(NamespacedClient): params: Optional[MutableMapping[str, Any]] = ..., headers: Optional[MutableMapping[str, str]] = ... ) -> Any: ... + async def geo_ip_stats( + self, + *, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/_async/client/ml.py b/elasticsearch/_async/client/ml.py index 102ae1bb..76d68a3c 100644 --- a/elasticsearch/_async/client/ml.py +++ b/elasticsearch/_async/client/ml.py @@ -826,24 +826,24 @@ class MlClient(NamespacedClient): ) @query_params() - async def preview_datafeed(self, datafeed_id, params=None, headers=None): + async def preview_datafeed( + self, body=None, datafeed_id=None, params=None, headers=None + ): """ Previews a datafeed. ``_ + :arg body: The datafeed config and job config with which to + execute the preview :arg datafeed_id: The ID of the datafeed to preview """ - if datafeed_id in SKIP_IN_PATH: - raise ValueError( - "Empty value passed for a required argument 'datafeed_id'." - ) - return await self.transport.perform_request( - "GET", + "POST", _make_path("_ml", "datafeeds", datafeed_id, "_preview"), params=params, headers=headers, + body=body, ) @query_params() @@ -1762,3 +1762,76 @@ class MlClient(NamespacedClient): params=params, headers=headers, ) + + @query_params( + "charset", + "column_names", + "delimiter", + "explain", + "format", + "grok_pattern", + "has_header_row", + "line_merge_size_limit", + "lines_to_sample", + "quote", + "should_trim_fields", + "timeout", + "timestamp_field", + "timestamp_format", + ) + async def find_file_structure(self, body, params=None, headers=None): + """ + Finds the structure of a text file. The text file must contain data that is + suitable to be ingested into Elasticsearch. + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg body: The contents of the file to be analyzed + :arg charset: Optional parameter to specify the character set of + the file + :arg column_names: Optional parameter containing a comma + separated list of the column names for a delimited file + :arg delimiter: Optional parameter to specify the delimiter + character for a delimited file - must be a single character + :arg explain: Whether to include a commentary on how the + structure was derived + :arg format: Optional parameter to specify the high level file + format Valid choices: ndjson, xml, delimited, semi_structured_text + :arg grok_pattern: Optional parameter to specify the Grok + pattern that should be used to extract fields from messages in a semi- + structured text file + :arg has_header_row: Optional parameter to specify whether a + delimited file includes the column names in its first row + :arg line_merge_size_limit: Maximum number of characters + permitted in a single message when lines are merged to create messages. + Default: 10000 + :arg lines_to_sample: How many lines of the file should be + included in the analysis Default: 1000 + :arg quote: Optional parameter to specify the quote character + for a delimited file - must be a single character + :arg should_trim_fields: Optional parameter to specify whether + the values between delimiters in a delimited file should have whitespace + trimmed from them + :arg timeout: Timeout after which the analysis will be aborted + Default: 25s + :arg timestamp_field: Optional parameter to specify the + timestamp field in the file + :arg timestamp_format: Optional parameter to specify the + timestamp format in the file - may be either a Joda or Java time format + """ + if body in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'body'.") + + body = _bulk_body(self.transport.serializer, body) + return await self.transport.perform_request( + "POST", + "/_ml/find_file_structure", + params=params, + headers=headers, + body=body, + ) diff --git a/elasticsearch/_async/client/ml.pyi b/elasticsearch/_async/client/ml.pyi index da33a129..69fb485a 100644 --- a/elasticsearch/_async/client/ml.pyi +++ b/elasticsearch/_async/client/ml.pyi @@ -557,8 +557,9 @@ class MlClient(NamespacedClient): ) -> Any: ... async def preview_datafeed( self, - datafeed_id: Any, *, + body: Optional[Any] = ..., + datafeed_id: Optional[Any] = ..., pretty: Optional[bool] = ..., human: Optional[bool] = ..., error_trace: Optional[bool] = ..., @@ -1134,3 +1135,31 @@ class MlClient(NamespacedClient): params: Optional[MutableMapping[str, Any]] = ..., headers: Optional[MutableMapping[str, str]] = ... ) -> Any: ... + async def find_file_structure( + self, + *, + body: Any, + charset: Optional[Any] = ..., + column_names: Optional[Any] = ..., + delimiter: Optional[Any] = ..., + explain: Optional[Any] = ..., + format: Optional[Any] = ..., + grok_pattern: Optional[Any] = ..., + has_header_row: Optional[Any] = ..., + line_merge_size_limit: Optional[Any] = ..., + lines_to_sample: Optional[Any] = ..., + quote: Optional[Any] = ..., + should_trim_fields: Optional[Any] = ..., + timeout: Optional[Any] = ..., + timestamp_field: Optional[Any] = ..., + timestamp_format: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/_async/client/shutdown.py b/elasticsearch/_async/client/shutdown.py new file mode 100644 index 00000000..ec6df212 --- /dev/null +++ b/elasticsearch/_async/client/shutdown.py @@ -0,0 +1,94 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from .utils import SKIP_IN_PATH, NamespacedClient, _make_path, query_params + + +class ShutdownClient(NamespacedClient): + @query_params() + async def delete_node(self, node_id, params=None, headers=None): + """ + Removes a node from the shutdown list + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: The node id of node to be removed from the + shutdown state + """ + if node_id in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'node_id'.") + + return await self.transport.perform_request( + "DELETE", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + ) + + @query_params() + async def get_node(self, node_id=None, params=None, headers=None): + """ + Retrieve status of a node or nodes that are currently marked as shutting down + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: Which node for which to retrieve the shutdown + status + """ + return await self.transport.perform_request( + "GET", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + ) + + @query_params() + async def put_node(self, node_id, body, params=None, headers=None): + """ + Adds a node to be shut down + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: The node id of node to be shut down + :arg body: The shutdown type definition to register + """ + for param in (node_id, body): + if param in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument.") + + return await self.transport.perform_request( + "PUT", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + body=body, + ) diff --git a/elasticsearch/_async/client/shutdown.pyi b/elasticsearch/_async/client/shutdown.pyi new file mode 100644 index 00000000..90d4a1bc --- /dev/null +++ b/elasticsearch/_async/client/shutdown.pyi @@ -0,0 +1,68 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from typing import Any, Collection, MutableMapping, Optional, Union + +from .utils import NamespacedClient + +class ShutdownClient(NamespacedClient): + async def delete_node( + self, + node_id: Any, + *, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... + async def get_node( + self, + *, + node_id: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... + async def put_node( + self, + node_id: Any, + *, + body: Any, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/_async/client/text_structure.py b/elasticsearch/_async/client/text_structure.py index f396b0ca..b3b9694d 100644 --- a/elasticsearch/_async/client/text_structure.py +++ b/elasticsearch/_async/client/text_structure.py @@ -42,11 +42,6 @@ class TextStructureClient(NamespacedClient): ``_ - .. warning:: - - This API is **experimental** so may include breaking changes - or be removed in a future version - :arg body: The contents of the file to be analyzed :arg charset: Optional parameter to specify the character set of the file diff --git a/elasticsearch/client/__init__.py b/elasticsearch/client/__init__.py index 17be9e58..b0f1407f 100644 --- a/elasticsearch/client/__init__.py +++ b/elasticsearch/client/__init__.py @@ -32,6 +32,7 @@ from .deprecation import DeprecationClient from .enrich import EnrichClient from .eql import EqlClient from .features import FeaturesClient +from .fleet import FleetClient from .graph import GraphClient from .ilm import IlmClient from .indices import IndicesClient @@ -46,6 +47,7 @@ from .remote import RemoteClient from .rollup import RollupClient from .searchable_snapshots import SearchableSnapshotsClient from .security import SecurityClient +from .shutdown import ShutdownClient from .slm import SlmClient from .snapshot import SnapshotClient from .sql import SqlClient @@ -224,6 +226,7 @@ class Elasticsearch(object): self.enrich = EnrichClient(self) self.eql = EqlClient(self) self.features = FeaturesClient(self) + self.fleet = FleetClient(self) self.graph = GraphClient(self) self.ilm = IlmClient(self) self.license = LicenseClient(self) @@ -235,6 +238,7 @@ class Elasticsearch(object): self.searchable_snapshots = SearchableSnapshotsClient(self) self.security = SecurityClient(self) self.slm = SlmClient(self) + self.shutdown = ShutdownClient(self) self.sql = SqlClient(self) self.ssl = SslClient(self) self.text_structure = TextStructureClient(self) diff --git a/elasticsearch/client/cluster.py b/elasticsearch/client/cluster.py index 40098e70..6e8e0aa0 100644 --- a/elasticsearch/client/cluster.py +++ b/elasticsearch/client/cluster.py @@ -192,7 +192,7 @@ class ClusterClient(NamespacedClient): """ Returns cluster settings. - ``_ + ``_ :arg flat_settings: Return settings in flat format (default: false) diff --git a/elasticsearch/client/fleet.py b/elasticsearch/client/fleet.py new file mode 100644 index 00000000..bba0f5a9 --- /dev/null +++ b/elasticsearch/client/fleet.py @@ -0,0 +1,48 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from .utils import SKIP_IN_PATH, NamespacedClient, _make_path, query_params + + +class FleetClient(NamespacedClient): + @query_params("checkpoints", "timeout", "wait_for_advance") + def global_checkpoints(self, index, params=None, headers=None): + """ + Returns the current global checkpoints for an index. This API is design for + internal use by the fleet server project. + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg index: The name of the index. + :arg checkpoints: Comma separated list of checkpoints + :arg timeout: Timeout to wait for global checkpoint to advance + Default: 30s + :arg wait_for_advance: Whether to wait for the global checkpoint + to advance past the specified current checkpoints Default: false + """ + if index in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'index'.") + + return self.transport.perform_request( + "GET", + _make_path(index, "_fleet", "global_checkpoints"), + params=params, + headers=headers, + ) diff --git a/elasticsearch/client/fleet.pyi b/elasticsearch/client/fleet.pyi new file mode 100644 index 00000000..3b5085a6 --- /dev/null +++ b/elasticsearch/client/fleet.pyi @@ -0,0 +1,40 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from typing import Any, Collection, MutableMapping, Optional, Union + +from .utils import NamespacedClient + +class FleetClient(NamespacedClient): + def global_checkpoints( + self, + index: Any, + *, + checkpoints: Optional[Any] = ..., + timeout: Optional[Any] = ..., + wait_for_advance: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/client/ingest.py b/elasticsearch/client/ingest.py index f8d1933d..fbc867fa 100644 --- a/elasticsearch/client/ingest.py +++ b/elasticsearch/client/ingest.py @@ -117,3 +117,14 @@ class IngestClient(NamespacedClient): return self.transport.perform_request( "GET", "/_ingest/processor/grok", params=params, headers=headers ) + + @query_params() + def geo_ip_stats(self, params=None, headers=None): + """ + Returns statistical information about geoip databases + + ``_ + """ + return self.transport.perform_request( + "GET", "/_ingest/geoip/stats", params=params, headers=headers + ) diff --git a/elasticsearch/client/ingest.pyi b/elasticsearch/client/ingest.pyi index 17c7c655..1cc649af 100644 --- a/elasticsearch/client/ingest.pyi +++ b/elasticsearch/client/ingest.pyi @@ -103,3 +103,17 @@ class IngestClient(NamespacedClient): params: Optional[MutableMapping[str, Any]] = ..., headers: Optional[MutableMapping[str, str]] = ... ) -> Any: ... + def geo_ip_stats( + self, + *, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/client/ml.py b/elasticsearch/client/ml.py index d39fb064..2a3c7f6c 100644 --- a/elasticsearch/client/ml.py +++ b/elasticsearch/client/ml.py @@ -814,24 +814,22 @@ class MlClient(NamespacedClient): ) @query_params() - def preview_datafeed(self, datafeed_id, params=None, headers=None): + def preview_datafeed(self, body=None, datafeed_id=None, params=None, headers=None): """ Previews a datafeed. ``_ + :arg body: The datafeed config and job config with which to + execute the preview :arg datafeed_id: The ID of the datafeed to preview """ - if datafeed_id in SKIP_IN_PATH: - raise ValueError( - "Empty value passed for a required argument 'datafeed_id'." - ) - return self.transport.perform_request( - "GET", + "POST", _make_path("_ml", "datafeeds", datafeed_id, "_preview"), params=params, headers=headers, + body=body, ) @query_params() @@ -1744,3 +1742,76 @@ class MlClient(NamespacedClient): params=params, headers=headers, ) + + @query_params( + "charset", + "column_names", + "delimiter", + "explain", + "format", + "grok_pattern", + "has_header_row", + "line_merge_size_limit", + "lines_to_sample", + "quote", + "should_trim_fields", + "timeout", + "timestamp_field", + "timestamp_format", + ) + def find_file_structure(self, body, params=None, headers=None): + """ + Finds the structure of a text file. The text file must contain data that is + suitable to be ingested into Elasticsearch. + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg body: The contents of the file to be analyzed + :arg charset: Optional parameter to specify the character set of + the file + :arg column_names: Optional parameter containing a comma + separated list of the column names for a delimited file + :arg delimiter: Optional parameter to specify the delimiter + character for a delimited file - must be a single character + :arg explain: Whether to include a commentary on how the + structure was derived + :arg format: Optional parameter to specify the high level file + format Valid choices: ndjson, xml, delimited, semi_structured_text + :arg grok_pattern: Optional parameter to specify the Grok + pattern that should be used to extract fields from messages in a semi- + structured text file + :arg has_header_row: Optional parameter to specify whether a + delimited file includes the column names in its first row + :arg line_merge_size_limit: Maximum number of characters + permitted in a single message when lines are merged to create messages. + Default: 10000 + :arg lines_to_sample: How many lines of the file should be + included in the analysis Default: 1000 + :arg quote: Optional parameter to specify the quote character + for a delimited file - must be a single character + :arg should_trim_fields: Optional parameter to specify whether + the values between delimiters in a delimited file should have whitespace + trimmed from them + :arg timeout: Timeout after which the analysis will be aborted + Default: 25s + :arg timestamp_field: Optional parameter to specify the + timestamp field in the file + :arg timestamp_format: Optional parameter to specify the + timestamp format in the file - may be either a Joda or Java time format + """ + if body in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'body'.") + + body = _bulk_body(self.transport.serializer, body) + return self.transport.perform_request( + "POST", + "/_ml/find_file_structure", + params=params, + headers=headers, + body=body, + ) diff --git a/elasticsearch/client/ml.pyi b/elasticsearch/client/ml.pyi index 23db5f73..bb838645 100644 --- a/elasticsearch/client/ml.pyi +++ b/elasticsearch/client/ml.pyi @@ -557,8 +557,9 @@ class MlClient(NamespacedClient): ) -> Any: ... def preview_datafeed( self, - datafeed_id: Any, *, + body: Optional[Any] = ..., + datafeed_id: Optional[Any] = ..., pretty: Optional[bool] = ..., human: Optional[bool] = ..., error_trace: Optional[bool] = ..., @@ -1134,3 +1135,31 @@ class MlClient(NamespacedClient): params: Optional[MutableMapping[str, Any]] = ..., headers: Optional[MutableMapping[str, str]] = ... ) -> Any: ... + def find_file_structure( + self, + *, + body: Any, + charset: Optional[Any] = ..., + column_names: Optional[Any] = ..., + delimiter: Optional[Any] = ..., + explain: Optional[Any] = ..., + format: Optional[Any] = ..., + grok_pattern: Optional[Any] = ..., + has_header_row: Optional[Any] = ..., + line_merge_size_limit: Optional[Any] = ..., + lines_to_sample: Optional[Any] = ..., + quote: Optional[Any] = ..., + should_trim_fields: Optional[Any] = ..., + timeout: Optional[Any] = ..., + timestamp_field: Optional[Any] = ..., + timestamp_format: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/client/shutdown.py b/elasticsearch/client/shutdown.py new file mode 100644 index 00000000..4a868fe7 --- /dev/null +++ b/elasticsearch/client/shutdown.py @@ -0,0 +1,94 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from .utils import SKIP_IN_PATH, NamespacedClient, _make_path, query_params + + +class ShutdownClient(NamespacedClient): + @query_params() + def delete_node(self, node_id, params=None, headers=None): + """ + Removes a node from the shutdown list + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: The node id of node to be removed from the + shutdown state + """ + if node_id in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument 'node_id'.") + + return self.transport.perform_request( + "DELETE", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + ) + + @query_params() + def get_node(self, node_id=None, params=None, headers=None): + """ + Retrieve status of a node or nodes that are currently marked as shutting down + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: Which node for which to retrieve the shutdown + status + """ + return self.transport.perform_request( + "GET", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + ) + + @query_params() + def put_node(self, node_id, body, params=None, headers=None): + """ + Adds a node to be shut down + + ``_ + + .. warning:: + + This API is **experimental** so may include breaking changes + or be removed in a future version + + :arg node_id: The node id of node to be shut down + :arg body: The shutdown type definition to register + """ + for param in (node_id, body): + if param in SKIP_IN_PATH: + raise ValueError("Empty value passed for a required argument.") + + return self.transport.perform_request( + "PUT", + _make_path("_nodes", node_id, "shutdown"), + params=params, + headers=headers, + body=body, + ) diff --git a/elasticsearch/client/shutdown.pyi b/elasticsearch/client/shutdown.pyi new file mode 100644 index 00000000..a6ce2d2f --- /dev/null +++ b/elasticsearch/client/shutdown.pyi @@ -0,0 +1,68 @@ +# Licensed to Elasticsearch B.V. under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch B.V. licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from typing import Any, Collection, MutableMapping, Optional, Union + +from .utils import NamespacedClient + +class ShutdownClient(NamespacedClient): + def delete_node( + self, + node_id: Any, + *, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... + def get_node( + self, + *, + node_id: Optional[Any] = ..., + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... + def put_node( + self, + node_id: Any, + *, + body: Any, + pretty: Optional[bool] = ..., + human: Optional[bool] = ..., + error_trace: Optional[bool] = ..., + format: Optional[str] = ..., + filter_path: Optional[Union[str, Collection[str]]] = ..., + request_timeout: Optional[Union[int, float]] = ..., + ignore: Optional[Union[int, Collection[int]]] = ..., + opaque_id: Optional[str] = ..., + params: Optional[MutableMapping[str, Any]] = ..., + headers: Optional[MutableMapping[str, str]] = ... + ) -> Any: ... diff --git a/elasticsearch/client/text_structure.py b/elasticsearch/client/text_structure.py index 6af86d70..1122c2b4 100644 --- a/elasticsearch/client/text_structure.py +++ b/elasticsearch/client/text_structure.py @@ -42,11 +42,6 @@ class TextStructureClient(NamespacedClient): ``_ - .. warning:: - - This API is **experimental** so may include breaking changes - or be removed in a future version - :arg body: The contents of the file to be analyzed :arg charset: Optional parameter to specify the character set of the file diff --git a/utils/generate-api.py b/utils/generate-api.py index e35010e2..fd6c90a9 100644 --- a/utils/generate-api.py +++ b/utils/generate-api.py @@ -16,9 +16,15 @@ # specific language governing permissions and limitations # under the License. +import contextlib +import io import json import os import re +import shutil +import sys +import tempfile +import zipfile from functools import lru_cache from itertools import chain from pathlib import Path @@ -38,27 +44,6 @@ SUBSTITUTIONS = {"type": "doc_type", "from": "from_"} # api path(s) BRANCH_NAME = "7.x" CODE_ROOT = Path(__file__).absolute().parent.parent -BASE_PATH = ( - CODE_ROOT.parent - / "elasticsearch" - / "rest-api-spec" - / "src" - / "main" - / "resources" - / "rest-api-spec" - / "api" -) -XPACK_PATH = ( - CODE_ROOT.parent - / "elasticsearch" - / "x-pack" - / "plugin" - / "src" - / "test" - / "resources" - / "rest-api-spec" - / "api" -) GLOBAL_QUERY_PARAMS = { "pretty": "Optional[bool]", "human": "Optional[bool]", @@ -335,10 +320,43 @@ class API: ) -def read_modules(): +@contextlib.contextmanager +def download_artifact(version): + # Download the list of all artifacts for a version + # and find the latest build URL for 'rest-api-spec-X.jar' + resp = http.request( + "GET", f"https://artifacts-api.elastic.co/v1/versions/{version}" + ) + packages = json.loads(resp.data)["version"]["builds"][0]["projects"][ + "elasticsearch" + ]["packages"] + for package in packages: + if re.match(r"^rest-api-spec-.*-sources\.jar$", package): + zip_url = packages[package]["url"] + break + else: + raise ValueError("Could not find 'rest-api-spec'") + + # Download the .jar file and unzip only the API + # .json files into a temporary directory + resp = http.request("GET", zip_url) + + tmp = Path(tempfile.mkdtemp()) + zip = zipfile.ZipFile(io.BytesIO(resp.data)) + for name in zip.namelist(): + if not name.endswith(".json") or name == "schema.json": + continue + with (tmp / name.replace("rest-api-spec/api/", "")).open("wb") as f: + f.write(zip.read(name)) + + yield tmp + shutil.rmtree(tmp) + + +def read_modules(version): modules = {} - for path in (BASE_PATH, XPACK_PATH): + with download_artifact(version) as path: for f in sorted(os.listdir(path)): name, ext = f.rsplit(".", 1) @@ -403,4 +421,5 @@ def dump_modules(modules): if __name__ == "__main__": - dump_modules(read_modules()) + version = sys.argv[1] + dump_modules(read_modules(version))