diff --git a/docs/sphinx/api.rst b/docs/sphinx/api.rst index 56c5bc6..52cab2c 100644 --- a/docs/sphinx/api.rst +++ b/docs/sphinx/api.rst @@ -51,6 +51,13 @@ Enrich Policies Event Query Language (EQL) -------------------------- +.. autoclass:: EqlClient + :members: + + +ES|QL +----- + .. autoclass:: EqlClient :members: diff --git a/elasticsearch_serverless/_async/client/__init__.py b/elasticsearch_serverless/_async/client/__init__.py index 130373b..292fe17 100644 --- a/elasticsearch_serverless/_async/client/__init__.py +++ b/elasticsearch_serverless/_async/client/__init__.py @@ -39,6 +39,7 @@ from .cluster import ClusterClient from .enrich import EnrichClient from .eql import EqlClient +from .esql import EsqlClient from .graph import GraphClient from .indices import IndicesClient from .inference import InferenceClient @@ -286,6 +287,7 @@ def __init__( self.enrich = EnrichClient(self) self.eql = EqlClient(self) + self.esql = EsqlClient(self) self.graph = GraphClient(self) self.license = LicenseClient(self) self.logstash = LogstashClient(self) diff --git a/elasticsearch_serverless/_async/client/esql.py b/elasticsearch_serverless/_async/client/esql.py new file mode 100644 index 0000000..db6056c --- /dev/null +++ b/elasticsearch_serverless/_async/client/esql.py @@ -0,0 +1,100 @@ +# 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. + +import typing as t + +from elastic_transport import ObjectApiResponse + +from ._base import NamespacedClient +from .utils import _rewrite_parameters + + +class EsqlClient(NamespacedClient): + + @_rewrite_parameters( + body_fields=("query", "columnar", "filter", "locale", "params"), + ignore_deprecated_options={"params"}, + ) + async def query( + self, + *, + query: t.Optional[str] = None, + columnar: t.Optional[bool] = None, + delimiter: t.Optional[str] = None, + error_trace: t.Optional[bool] = None, + filter: t.Optional[t.Mapping[str, t.Any]] = None, + filter_path: t.Optional[t.Union[str, t.Sequence[str]]] = None, + format: t.Optional[str] = None, + human: t.Optional[bool] = None, + locale: t.Optional[str] = None, + params: t.Optional[t.Sequence[t.Union[None, bool, float, int, str]]] = None, + pretty: t.Optional[bool] = None, + body: t.Optional[t.Dict[str, t.Any]] = None, + ) -> ObjectApiResponse[t.Any]: + """ + Executes an ES|QL request + + ``_ + + :param query: The ES|QL query API accepts an ES|QL query string in the query + parameter, runs it, and returns the results. + :param columnar: By default, ES|QL returns results as rows. For example, FROM + returns each individual document as one row. For the JSON, YAML, CBOR and + smile formats, ES|QL can return the results in a columnar fashion where one + row represents all the values of a certain column in the results. + :param delimiter: The character to use between values within a CSV row. Only + valid for the CSV format. + :param filter: Specify a Query DSL query in the filter parameter to filter the + set of documents that an ES|QL query runs on. + :param format: A short version of the Accept header, e.g. json, yaml. + :param locale: + :param params: To avoid any attempts of hacking or code injection, extract the + values in a separate list of parameters. Use question mark placeholders (?) + in the query string for each of the parameters. + """ + if query is None and body is None: + raise ValueError("Empty value passed for parameter 'query'") + __path = "/_query" + __query: t.Dict[str, t.Any] = {} + __body: t.Dict[str, t.Any] = body if body is not None else {} + if delimiter is not None: + __query["delimiter"] = delimiter + if error_trace is not None: + __query["error_trace"] = error_trace + if filter_path is not None: + __query["filter_path"] = filter_path + if format is not None: + __query["format"] = format + if human is not None: + __query["human"] = human + if pretty is not None: + __query["pretty"] = pretty + if not __body: + if query is not None: + __body["query"] = query + if columnar is not None: + __body["columnar"] = columnar + if filter is not None: + __body["filter"] = filter + if locale is not None: + __body["locale"] = locale + if params is not None: + __body["params"] = params + __headers = {"accept": "application/json", "content-type": "application/json"} + return await self.perform_request( # type: ignore[return-value] + "POST", __path, params=__query, headers=__headers, body=__body + ) diff --git a/elasticsearch_serverless/_sync/client/__init__.py b/elasticsearch_serverless/_sync/client/__init__.py index 4b83337..934946b 100644 --- a/elasticsearch_serverless/_sync/client/__init__.py +++ b/elasticsearch_serverless/_sync/client/__init__.py @@ -39,6 +39,7 @@ from .cluster import ClusterClient from .enrich import EnrichClient from .eql import EqlClient +from .esql import EsqlClient from .graph import GraphClient from .indices import IndicesClient from .inference import InferenceClient @@ -286,6 +287,7 @@ def __init__( self.enrich = EnrichClient(self) self.eql = EqlClient(self) + self.esql = EsqlClient(self) self.graph = GraphClient(self) self.license = LicenseClient(self) self.logstash = LogstashClient(self) diff --git a/elasticsearch_serverless/_sync/client/esql.py b/elasticsearch_serverless/_sync/client/esql.py new file mode 100644 index 0000000..7434338 --- /dev/null +++ b/elasticsearch_serverless/_sync/client/esql.py @@ -0,0 +1,100 @@ +# 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. + +import typing as t + +from elastic_transport import ObjectApiResponse + +from ._base import NamespacedClient +from .utils import _rewrite_parameters + + +class EsqlClient(NamespacedClient): + + @_rewrite_parameters( + body_fields=("query", "columnar", "filter", "locale", "params"), + ignore_deprecated_options={"params"}, + ) + def query( + self, + *, + query: t.Optional[str] = None, + columnar: t.Optional[bool] = None, + delimiter: t.Optional[str] = None, + error_trace: t.Optional[bool] = None, + filter: t.Optional[t.Mapping[str, t.Any]] = None, + filter_path: t.Optional[t.Union[str, t.Sequence[str]]] = None, + format: t.Optional[str] = None, + human: t.Optional[bool] = None, + locale: t.Optional[str] = None, + params: t.Optional[t.Sequence[t.Union[None, bool, float, int, str]]] = None, + pretty: t.Optional[bool] = None, + body: t.Optional[t.Dict[str, t.Any]] = None, + ) -> ObjectApiResponse[t.Any]: + """ + Executes an ES|QL request + + ``_ + + :param query: The ES|QL query API accepts an ES|QL query string in the query + parameter, runs it, and returns the results. + :param columnar: By default, ES|QL returns results as rows. For example, FROM + returns each individual document as one row. For the JSON, YAML, CBOR and + smile formats, ES|QL can return the results in a columnar fashion where one + row represents all the values of a certain column in the results. + :param delimiter: The character to use between values within a CSV row. Only + valid for the CSV format. + :param filter: Specify a Query DSL query in the filter parameter to filter the + set of documents that an ES|QL query runs on. + :param format: A short version of the Accept header, e.g. json, yaml. + :param locale: + :param params: To avoid any attempts of hacking or code injection, extract the + values in a separate list of parameters. Use question mark placeholders (?) + in the query string for each of the parameters. + """ + if query is None and body is None: + raise ValueError("Empty value passed for parameter 'query'") + __path = "/_query" + __query: t.Dict[str, t.Any] = {} + __body: t.Dict[str, t.Any] = body if body is not None else {} + if delimiter is not None: + __query["delimiter"] = delimiter + if error_trace is not None: + __query["error_trace"] = error_trace + if filter_path is not None: + __query["filter_path"] = filter_path + if format is not None: + __query["format"] = format + if human is not None: + __query["human"] = human + if pretty is not None: + __query["pretty"] = pretty + if not __body: + if query is not None: + __body["query"] = query + if columnar is not None: + __body["columnar"] = columnar + if filter is not None: + __body["filter"] = filter + if locale is not None: + __body["locale"] = locale + if params is not None: + __body["params"] = params + __headers = {"accept": "application/json", "content-type": "application/json"} + return self.perform_request( # type: ignore[return-value] + "POST", __path, params=__query, headers=__headers, body=__body + ) diff --git a/elasticsearch_serverless/client.py b/elasticsearch_serverless/client.py index 80e1667..0fd72fa 100644 --- a/elasticsearch_serverless/client.py +++ b/elasticsearch_serverless/client.py @@ -25,6 +25,7 @@ from ._sync.client.cluster import ClusterClient as ClusterClient # noqa: F401 from ._sync.client.enrich import EnrichClient as EnrichClient # noqa: F401 from ._sync.client.eql import EqlClient as EqlClient # noqa: F401 +from ._sync.client.esql import EsqlClient as EsqlClient # noqa: F401 from ._sync.client.graph import GraphClient as GraphClient # noqa: F401 from ._sync.client.indices import IndicesClient as IndicesClient # noqa: F401 from ._sync.client.inference import InferenceClient as InferenceClient # noqa: F401