Rename Elasticsearch -> OpenSearch

Signed-off-by: Rushi Agrawal <rushi.agr@gmail.com>
This commit is contained in:
Rushi Agrawal
2021-08-13 15:51:50 +05:30
parent 43f5ac58b5
commit 9e9269c8f3
139 changed files with 486 additions and 495 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
ARG PYTHON_VERSION=3.8 ARG PYTHON_VERSION=3.8
FROM python:${PYTHON_VERSION} FROM python:${PYTHON_VERSION}
WORKDIR /code/elasticsearch-py WORKDIR /code/opensearch-py
COPY dev-requirements.txt . COPY dev-requirements.txt .
RUN python -m pip install \ RUN python -m pip install \
-U --no-cache-dir \ -U --no-cache-dir \
+7 -4
View File
@@ -12,13 +12,16 @@ if [[ -z $es_node_name ]]; then
export RUNSCRIPTS=${RUNSCRIPTS-} export RUNSCRIPTS=${RUNSCRIPTS-}
export DETACH=${DETACH-false} export DETACH=${DETACH-false}
export CLEANUP=${CLEANUP-false} export CLEANUP=${CLEANUP-false}
export ELASTICSEARCH_URL_EXTENSION=${ELASTICSEARCH_URL_EXTENSION-http} export OPENSEARCH_URL_EXTENSION=${OPENSEARCH_URL_EXTENSION-http}
export es_node_name=instance export es_node_name=instance
export elastic_password=changeme export opensearch_image=opensearchproject/opensearch
if [[ "$CLUSTER" == "opendistro" ]]; then
export opensearch_image=amazon/opendistro-for-elasticsearch
fi
export elasticsearch_url=$ELASTICSEARCH_URL_EXTENSION://${es_node_name}:9200 export opensearch_url=$OPENSEARCH_URL_EXTENSION://${opensearch_node_name}:9200
export external_elasticsearch_url=${elasticsearch_url/$es_node_name/localhost} export external_opensearch_url=${opensearch_url/$opensearch_node_name/localhost}
export network_name=search-rest-test export network_name=search-rest-test
+5 -5
View File
@@ -2,7 +2,7 @@
# ------------------------------------------------------- # # ------------------------------------------------------- #
# #
# Skeleton for common build entry script for all elastic # Skeleton for common build entry script for all opensearch
# clients. Needs to be adapted to individual client usage. # clients. Needs to be adapted to individual client usage.
# #
# Must be called: ./.ci/make.sh <target> <params> # Must be called: ./.ci/make.sh <target> <params>
@@ -35,7 +35,7 @@ VERSION=$2
STACK_VERSION=$VERSION STACK_VERSION=$VERSION
set -euo pipefail set -euo pipefail
product="elastic/elasticsearch-py" product="opensearch-project/opensearch-py"
output_folder=".ci/output" output_folder=".ci/output"
codegen_folder=".ci/output" codegen_folder=".ci/output"
OUTPUT_DIR="$repo/${output_folder}" OUTPUT_DIR="$repo/${output_folder}"
@@ -129,15 +129,15 @@ if [[ "$CMD" == "assemble" ]]; then
# Build dists into .ci/output # Build dists into .ci/output
docker run \ docker run \
--rm -v $repo/.ci/output:/code/elasticsearch-py/dist \ --rm -v $repo/.ci/output:/code/opensearch-py/dist \
$product \ $product \
/bin/bash -c "python /code/elasticsearch-py/utils/build-dists.py $VERSION" /bin/bash -c "python /code/opensearch-py/utils/build-dists.py $VERSION"
# Verify that there are dists in .ci/output # Verify that there are dists in .ci/output
if compgen -G ".ci/output/*" > /dev/null; then if compgen -G ".ci/output/*" > /dev/null; then
# Tarball everything up in .ci/output # Tarball everything up in .ci/output
cd $repo/.ci/output && tar -czvf elasticsearch-py-$VERSION.tar.gz * && cd - cd $repo/.ci/output && tar -czvf opensearch-py-$VERSION.tar.gz * && cd -
echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m" echo -e "\033[32;1mTARGET: successfully assembled client v$VERSION\033[0m"
exit 0 exit 0
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# Launch one or more Elasticsearch nodes via the Docker image, # Launch one or more OpenSearch nodes via the Docker image,
# to form a cluster suitable for running the REST API tests. # to form a cluster suitable for running the REST API tests.
# #
# Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'. # Export the STACK_VERSION variable, eg. '8.0.0-SNAPSHOT'.
@@ -8,7 +8,7 @@
# Export the NUMBER_OF_NODES variable to start more than 1 node # Export the NUMBER_OF_NODES variable to start more than 1 node
# Version 1.4.0 # Version 1.4.0
# - Initial version of the run-elasticsearch.sh script # - Initial version of the run-opensearch.sh script
# - Deleting the volume should not dependent on the container still running # - Deleting the volume should not dependent on the container still running
# - Fixed `ES_JAVA_OPTS` config # - Fixed `ES_JAVA_OPTS` config
# - Moved to STACK_VERSION and TEST_VERSION # - Moved to STACK_VERSION and TEST_VERSION
@@ -47,7 +47,7 @@ NUMBER_OF_NODES=${NUMBER_OF_NODES-1}
http_port=9200 http_port=9200
for (( i=0; i<$NUMBER_OF_NODES; i++, http_port++ )); do for (( i=0; i<$NUMBER_OF_NODES; i++, http_port++ )); do
node_name=${es_node_name}$i node_name=${es_node_name}$i
node_url=${external_elasticsearch_url/9200/${http_port}}$i node_url=${external_opensearch_url/9200/${http_port}}$i
if [[ "$i" == "0" ]]; then node_name=$es_node_name; fi if [[ "$i" == "0" ]]; then node_name=$es_node_name; fi
environment+=($(cat <<-END environment+=($(cat <<-END
--env node.name=$node_name --env node.name=$node_name
@@ -56,7 +56,7 @@ END
echo "$i: $http_port $node_url " echo "$i: $http_port $node_url "
volume_name=${node_name}-rest-test-data volume_name=${node_name}-rest-test-data
volumes+=($(cat <<-END volumes+=($(cat <<-END
--volume $volume_name:/usr/share/elasticsearch/data${i} --volume $volume_name:/usr/share/opensearch/data${i}
END END
)) ))
@@ -84,7 +84,7 @@ END
--ulimit nofile=65536:65536 \ --ulimit nofile=65536:65536 \
--ulimit memlock=-1:-1 \ --ulimit memlock=-1:-1 \
--detach="$local_detach" \ --detach="$local_detach" \
--health-cmd="curl -vvv -s --fail $elasticsearch_url/_cluster/health || exit 1" \ --health-cmd="curl -vvv -s --fail $opensearch_url/_cluster/health || exit 1" \
--health-interval=2s \ --health-interval=2s \
--health-retries=20 \ --health-retries=20 \
--health-timeout=2s \ --health-timeout=2s \
+12 -12
View File
@@ -1,43 +1,43 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Called by entry point `run-test` use this script to add your repository specific test commands # Called by entry point `run-test` use this script to add your repository specific test commands
# Once called Elasticsearch is up and running and the following parameters are available to this script # Once called opensearch is up and running and the following parameters are available to this script
# ELASTICSEARCH_VERSION -- version e.g Major.Minor.Patch(-Prelease) # OPENSEARCH_VERSION -- version e.g Major.Minor.Patch(-Prelease)
# ELASTICSEARCH_URL -- The url at which elasticsearch is reachable # OPENSEARCH_URL -- The url at which opensearch is reachable
# network_name -- The docker network name # network_name -- The docker network name
# NODE_NAME -- The docker container name also used as Elasticsearch node name # NODE_NAME -- The docker container name also used as opensearch node name
# When run in CI the test-matrix is used to define additional variables # When run in CI the test-matrix is used to define additional variables
# TEST_SUITE -- defaults to `oss` in `run-tests` # TEST_SUITE -- defaults to `oss` in `run-tests`
set -e set -e
echo -e "\033[34;1mINFO:\033[0m URL ${elasticsearch_url}\033[0m" echo -e "\033[34;1mINFO:\033[0m URL ${opensearch_url}\033[0m"
echo -e "\033[34;1mINFO:\033[0m VERSION ${ELASTICSEARCH_VERSION}\033[0m" echo -e "\033[34;1mINFO:\033[0m VERSION ${OPENSEARCH_VERSION}\033[0m"
echo -e "\033[34;1mINFO:\033[0m TEST_SUITE ${TEST_SUITE}\033[0m" echo -e "\033[34;1mINFO:\033[0m TEST_SUITE ${TEST_SUITE}\033[0m"
echo -e "\033[34;1mINFO:\033[0m PYTHON_VERSION ${PYTHON_VERSION}\033[0m" echo -e "\033[34;1mINFO:\033[0m PYTHON_VERSION ${PYTHON_VERSION}\033[0m"
echo -e "\033[34;1mINFO:\033[0m PYTHON_CONNECTION_CLASS ${PYTHON_CONNECTION_CLASS}\033[0m" echo -e "\033[34;1mINFO:\033[0m PYTHON_CONNECTION_CLASS ${PYTHON_CONNECTION_CLASS}\033[0m"
echo -e "\033[1m>>>>> Build [elastic/elasticsearch-py container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" echo -e "\033[1m>>>>> Build [opensearch-project/opensearch-py container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m"
docker build \ docker build \
--file .ci/Dockerfile.client \ --file .ci/Dockerfile.client \
--tag elastic/elasticsearch-py \ --tag opensearch-project/opensearch-py \
--build-arg PYTHON_VERSION=${PYTHON_VERSION} \ --build-arg PYTHON_VERSION=${PYTHON_VERSION} \
. .
echo -e "\033[1m>>>>> Run [elastic/elasticsearch-py container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" echo -e "\033[1m>>>>> Run [opensearch-project/opensearch-py container] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m"
mkdir -p junit mkdir -p junit
docker run \ docker run \
--network=${network_name} \ --network=${network_name} \
--env "STACK_VERSION=${STACK_VERSION}" \ --env "STACK_VERSION=${STACK_VERSION}" \
--env "ELASTICSEARCH_URL=${elasticsearch_url}" \ --env "OPENSEARCH_URL=${opensearch_url}" \
--env "TEST_SUITE=${TEST_SUITE}" \ --env "TEST_SUITE=${TEST_SUITE}" \
--env "PYTHON_CONNECTION_CLASS=${PYTHON_CONNECTION_CLASS}" \ --env "PYTHON_CONNECTION_CLASS=${PYTHON_CONNECTION_CLASS}" \
--env "TEST_TYPE=server" \ --env "TEST_TYPE=server" \
--name elasticsearch-py \ --name opensearch-py \
--rm \ --rm \
elastic/elasticsearch-py \ opensearch-project/opensearch-py \
python setup.py test python setup.py test
+3 -4
View File
@@ -2,21 +2,20 @@
# #
# Version 1.1 # Version 1.1
# - Moved to .ci folder and seperated out `run-repository.sh` # - Moved to .ci folder and seperated out `run-repository.sh`
# - Add `$RUNSCRIPTS` env var for running Elasticsearch dependent products # - Add `$RUNSCRIPTS` env var for running opensearch dependent products
# Default environment variables # Default environment variables
export TEST_SUITE="${TEST_SUITE:=oss}" export TEST_SUITE="${TEST_SUITE:=oss}"
export PYTHON_VERSION="${PYTHON_VERSION:=3.9}" export PYTHON_VERSION="${PYTHON_VERSION:=3.9}"
export PYTHON_CONNECTION_CLASS="${PYTHON_CONNECTION_CLASS:=Urllib3HttpConnection}" export PYTHON_CONNECTION_CLASS="${PYTHON_CONNECTION_CLASS:=Urllib3HttpConnection}"
export ELASTICSEARCH_URL_EXTENSION="${ELASTICSEARCH_URL_EXTENSION:=http}" export OPENSEARCH_URL_EXTENSION="${OPENSEARCH_URL_EXTENSION:=http}"
export CLUSTER="${1:=opensearch}" export CLUSTER="${1:=opensearch}"
script_path=$(dirname $(realpath -s $0)) script_path=$(dirname $(realpath -s $0))
source $script_path/functions/imports.sh source $script_path/functions/imports.sh
set -euo pipefail set -euo pipefail
echo -e "\033[1m>>>>> Start server container >>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m" DETACH=true bash .ci/run-opensearch.sh
DETACH=true bash .ci/run-elasticsearch.sh
if [[ -n "$RUNSCRIPTS" ]]; then if [[ -n "$RUNSCRIPTS" ]]; then
for RUNSCRIPT in ${RUNSCRIPTS//,/ } ; do for RUNSCRIPT in ${RUNSCRIPTS//,/ } ; do
+2 -2
View File
@@ -5,5 +5,5 @@ omit =
*/lib_pypy/* */lib_pypy/*
*/site-packages/* */site-packages/*
*.egg/* *.egg/*
test_elasticsearch/* test_opensearch/*
elasticsearch/connection/esthrift/* opensearch/connection/esthrift/*
+3 -3
View File
@@ -137,7 +137,7 @@ cython_debug/
# Pycharm project settings # Pycharm project settings
.idea .idea
# elasticsearch files # opensearch files
test_elasticsearch/cover test_opensearch/cover
test_elasticsearch/local.py test_opensearch/local.py
.ci/output .ci/output
+2 -2
View File
@@ -5,8 +5,8 @@ include LICENSE
include MANIFEST.in include MANIFEST.in
include README.md include README.md
include setup.py include setup.py
recursive-include elasticsearch* py.typed *.pyi recursive-include opensearch* py.typed *.pyi
prune test_elasticsearch prune test_opensearch
recursive-exclude * __pycache__ recursive-exclude * __pycache__
recursive-exclude * *.py[co] recursive-exclude * *.py[co]
+4 -4
View File
@@ -5,14 +5,14 @@ build:
PYTHON_VERSION=${PYTHON_VERSION} docker-compose build client PYTHON_VERSION=${PYTHON_VERSION} docker-compose build client
pull: pull:
ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION} PYTHON_VERSION=${PYTHON_VERSION} docker-compose pull OPENSEARCH_VERSION=${OPENSEARCH_VERSION} PYTHON_VERSION=${PYTHON_VERSION} docker-compose pull
push: push:
# requires authentication. # requires authentication.
PYTHON_VERSION=${PYTHON_VERSION} docker-compose push client PYTHON_VERSION=${PYTHON_VERSION} docker-compose push client
run_tests: run_tests:
ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION} PYTHON_VERSION=${PYTHON_VERSION} docker-compose -p "${ELASTIC_VERSION}-${PYTHON_VERSION}" run client python setup.py test OPENSEARCH_VERSION=${OPENSEARCH_VERSION} PYTHON_VERSION=${PYTHON_VERSION} docker-compose -p "${OPEN_VERSION}-${PYTHON_VERSION}" run client python setup.py test
start_elasticsearch: start_opensearch:
ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION} docker-compose up -d elasticsearch OPENSEARCH_VERSION=${OPENSEARCH_VERSION} docker-compose up -d opensearch
+7 -7
View File
@@ -29,8 +29,8 @@ import nox
SOURCE_FILES = ( SOURCE_FILES = (
"setup.py", "setup.py",
"noxfile.py", "noxfile.py",
"elasticsearch/", "opensearch/",
"test_elasticsearch/", "test_opensearch/",
"utils/", "utils/",
) )
@@ -68,15 +68,15 @@ def lint(session):
# Run mypy on the package and then the type examples separately for # Run mypy on the package and then the type examples separately for
# the two different mypy use-cases, ourselves and our users. # the two different mypy use-cases, ourselves and our users.
session.run("mypy", "--strict", "elasticsearch/") session.run("mypy", "--strict", "opensearch/")
session.run("mypy", "--strict", "test_elasticsearch/test_types/sync_types.py") session.run("mypy", "--strict", "test_opensearch/test_types/sync_types.py")
session.run("mypy", "--strict", "test_elasticsearch/test_types/async_types.py") session.run("mypy", "--strict", "test_opensearch/test_types/async_types.py")
# Make sure we don't require aiohttp to be installed for users to # Make sure we don't require aiohttp to be installed for users to
# receive type hint information from mypy. # receive type hint information from mypy.
session.run("python", "-m", "pip", "uninstall", "--yes", "aiohttp") session.run("python", "-m", "pip", "uninstall", "--yes", "aiohttp")
session.run("mypy", "--strict", "elasticsearch/") session.run("mypy", "--strict", "opensearch/")
session.run("mypy", "--strict", "test_elasticsearch/test_types/sync_types.py") session.run("mypy", "--strict", "test_opensearch/test_types/sync_types.py")
@nox.session() @nox.session()
@@ -39,10 +39,10 @@ _major, _minor, _patch = [
] ]
VERSION = __version__ = (_major, _minor, _patch) VERSION = __version__ = (_major, _minor, _patch)
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
logger.addHandler(logging.NullHandler()) logger.addHandler(logging.NullHandler())
from .client import Elasticsearch from .client import OpenSearch
from .connection import Connection, RequestsHttpConnection, Urllib3HttpConnection from .connection import Connection, RequestsHttpConnection, Urllib3HttpConnection
from .connection_pool import ConnectionPool, ConnectionSelector, RoundRobinSelector from .connection_pool import ConnectionPool, ConnectionSelector, RoundRobinSelector
from .exceptions import ( from .exceptions import (
@@ -51,11 +51,11 @@ from .exceptions import (
ConflictError, ConflictError,
ConnectionError, ConnectionError,
ConnectionTimeout, ConnectionTimeout,
ElasticsearchDeprecationWarning,
ElasticsearchException,
ElasticsearchWarning,
ImproperlyConfigured, ImproperlyConfigured,
NotFoundError, NotFoundError,
OpenSearchDeprecationWarning,
OpenSearchException,
OpenSearchWarning,
RequestError, RequestError,
SerializationError, SerializationError,
SSLError, SSLError,
@@ -66,10 +66,10 @@ from .transport import Transport
# Only raise one warning per deprecation message so as not # Only raise one warning per deprecation message so as not
# to spam up the user if the same action is done multiple times. # to spam up the user if the same action is done multiple times.
warnings.simplefilter("default", category=ElasticsearchDeprecationWarning, append=True) warnings.simplefilter("default", category=OpenSearchDeprecationWarning, append=True)
__all__ = [ __all__ = [
"Elasticsearch", "OpenSearch",
"Transport", "Transport",
"ConnectionPool", "ConnectionPool",
"ConnectionSelector", "ConnectionSelector",
@@ -79,7 +79,7 @@ __all__ = [
"RequestsHttpConnection", "RequestsHttpConnection",
"Urllib3HttpConnection", "Urllib3HttpConnection",
"ImproperlyConfigured", "ImproperlyConfigured",
"ElasticsearchException", "OpenSearchException",
"SerializationError", "SerializationError",
"TransportError", "TransportError",
"NotFoundError", "NotFoundError",
@@ -90,8 +90,8 @@ __all__ = [
"ConnectionTimeout", "ConnectionTimeout",
"AuthenticationException", "AuthenticationException",
"AuthorizationException", "AuthorizationException",
"ElasticsearchWarning", "OpenSearchWarning",
"ElasticsearchDeprecationWarning", "OpenSearchDeprecationWarning",
] ]
try: try:
@@ -99,7 +99,7 @@ try:
if sys.version_info < (3, 6): if sys.version_info < (3, 6):
raise ImportError raise ImportError
from ._async.client import AsyncElasticsearch from ._async.client import AsyncOpenSearch
from ._async.http_aiohttp import AIOHttpConnection, AsyncConnection from ._async.http_aiohttp import AIOHttpConnection, AsyncConnection
from ._async.transport import AsyncTransport from ._async.transport import AsyncTransport
@@ -107,7 +107,7 @@ try:
"AIOHttpConnection", "AIOHttpConnection",
"AsyncConnection", "AsyncConnection",
"AsyncTransport", "AsyncTransport",
"AsyncElasticsearch", "AsyncOpenSearch",
] ]
except (ImportError, SyntaxError): except (ImportError, SyntaxError):
pass pass
@@ -27,7 +27,7 @@
import sys import sys
from typing import Tuple from typing import Tuple
from .client import Elasticsearch as Elasticsearch from .client import OpenSearch as OpenSearch
from .connection import Connection as Connection from .connection import Connection as Connection
from .connection import RequestsHttpConnection as RequestsHttpConnection from .connection import RequestsHttpConnection as RequestsHttpConnection
from .connection import Urllib3HttpConnection as Urllib3HttpConnection from .connection import Urllib3HttpConnection as Urllib3HttpConnection
@@ -39,12 +39,10 @@ from .exceptions import AuthorizationException as AuthorizationException
from .exceptions import ConflictError as ConflictError from .exceptions import ConflictError as ConflictError
from .exceptions import ConnectionError as ConnectionError from .exceptions import ConnectionError as ConnectionError
from .exceptions import ConnectionTimeout as ConnectionTimeout from .exceptions import ConnectionTimeout as ConnectionTimeout
from .exceptions import (
ElasticsearchDeprecationWarning as ElasticsearchDeprecationWarning,
)
from .exceptions import ElasticsearchException as ElasticsearchException
from .exceptions import ImproperlyConfigured as ImproperlyConfigured from .exceptions import ImproperlyConfigured as ImproperlyConfigured
from .exceptions import NotFoundError as NotFoundError from .exceptions import NotFoundError as NotFoundError
from .exceptions import OpenSearchDeprecationWarning as OpenSearchDeprecationWarning
from .exceptions import OpenSearchException as OpenSearchException
from .exceptions import RequestError as RequestError from .exceptions import RequestError as RequestError
from .exceptions import SerializationError as SerializationError from .exceptions import SerializationError as SerializationError
from .exceptions import SSLError as SSLError from .exceptions import SSLError as SSLError
@@ -56,7 +54,7 @@ try:
if sys.version_info < (3, 6): if sys.version_info < (3, 6):
raise ImportError raise ImportError
from ._async.client import AsyncElasticsearch as AsyncElasticsearch from ._async.client import AsyncOpenSearch as AsyncOpenSearch
from ._async.http_aiohttp import AIOHttpConnection as AIOHttpConnection from ._async.http_aiohttp import AIOHttpConnection as AIOHttpConnection
from ._async.transport import AsyncTransport as AsyncTransport from ._async.transport import AsyncTransport as AsyncTransport
except (ImportError, SyntaxError): except (ImportError, SyntaxError):
@@ -42,23 +42,23 @@ from .snapshot import SnapshotClient
from .tasks import TasksClient from .tasks import TasksClient
from .utils import SKIP_IN_PATH, _bulk_body, _make_path, _normalize_hosts, query_params from .utils import SKIP_IN_PATH, _bulk_body, _make_path, _normalize_hosts, query_params
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
class AsyncElasticsearch(object): class AsyncOpenSearch(object):
""" """
Elasticsearch low-level client. Provides a straightforward mapping from OpenSearch low-level client. Provides a straightforward mapping from
Python to ES REST endpoints. Python to ES REST endpoints.
The instance has attributes ``cat``, ``cluster``, ``indices``, ``ingest``, The instance has attributes ``cat``, ``cluster``, ``indices``, ``ingest``,
``nodes``, ``snapshot`` and ``tasks`` that provide access to instances of ``nodes``, ``snapshot`` and ``tasks`` that provide access to instances of
:class:`~elasticsearch.client.CatClient`, :class:`~opensearch.client.CatClient`,
:class:`~elasticsearch.client.ClusterClient`, :class:`~opensearch.client.ClusterClient`,
:class:`~elasticsearch.client.IndicesClient`, :class:`~opensearch.client.IndicesClient`,
:class:`~elasticsearch.client.IngestClient`, :class:`~opensearch.client.IngestClient`,
:class:`~elasticsearch.client.NodesClient`, :class:`~opensearch.client.NodesClient`,
:class:`~elasticsearch.client.SnapshotClient` and :class:`~opensearch.client.SnapshotClient` and
:class:`~elasticsearch.client.TasksClient` respectively. This is the :class:`~opensearch.client.TasksClient` respectively. This is the
preferred (and only supported) way to get access to those classes and their preferred (and only supported) way to get access to those classes and their
methods. methods.
@@ -66,15 +66,15 @@ class AsyncElasticsearch(object):
the ``connection_class`` parameter:: the ``connection_class`` parameter::
# create connection to localhost using the ThriftConnection # create connection to localhost using the ThriftConnection
es = Elasticsearch(connection_class=ThriftConnection) es = OpenSearch(connection_class=ThriftConnection)
If you want to turn on :ref:`sniffing` you have several options (described If you want to turn on :ref:`sniffing` you have several options (described
in :class:`~elasticsearch.Transport`):: in :class:`~opensearch.Transport`)::
# create connection that will automatically inspect the cluster to get # create connection that will automatically inspect the cluster to get
# the list of active nodes. Start with nodes running on 'esnode1' and # the list of active nodes. Start with nodes running on 'esnode1' and
# 'esnode2' # 'esnode2'
es = Elasticsearch( es = OpenSearch(
['esnode1', 'esnode2'], ['esnode1', 'esnode2'],
# sniff before doing anything # sniff before doing anything
sniff_on_start=True, sniff_on_start=True,
@@ -89,16 +89,16 @@ class AsyncElasticsearch(object):
# connect to localhost directly and another node using SSL on port 443 # connect to localhost directly and another node using SSL on port 443
# and an url_prefix. Note that ``port`` needs to be an int. # and an url_prefix. Note that ``port`` needs to be an int.
es = Elasticsearch([ es = OpenSearch([
{'host': 'localhost'}, {'host': 'localhost'},
{'host': 'othernode', 'port': 443, 'url_prefix': 'es', 'use_ssl': True}, {'host': 'othernode', 'port': 443, 'url_prefix': 'es', 'use_ssl': True},
]) ])
If using SSL, there are several parameters that control how we deal with If using SSL, there are several parameters that control how we deal with
certificates (see :class:`~elasticsearch.Urllib3HttpConnection` for certificates (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -109,10 +109,10 @@ class AsyncElasticsearch(object):
) )
If using SSL, but don't verify the certs, a warning message is showed If using SSL, but don't verify the certs, a warning message is showed
optionally (see :class:`~elasticsearch.Urllib3HttpConnection` for optionally (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -123,10 +123,10 @@ class AsyncElasticsearch(object):
) )
SSL client authentication is supported SSL client authentication is supported
(see :class:`~elasticsearch.Urllib3HttpConnection` for (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -143,7 +143,7 @@ class AsyncElasticsearch(object):
Alternatively you can use RFC-1738 formatted URLs, as long as they are not Alternatively you can use RFC-1738 formatted URLs, as long as they are not
in conflict with other options:: in conflict with other options::
es = Elasticsearch( es = OpenSearch(
[ [
'http://user:secret@localhost:9200/', 'http://user:secret@localhost:9200/',
'https://user:secret@other_host:443/production' 'https://user:secret@other_host:443/production'
@@ -152,11 +152,11 @@ class AsyncElasticsearch(object):
) )
By default, `JSONSerializer By default, `JSONSerializer
<https://github.com/elastic/elasticsearch-py/blob/master/elasticsearch/serializer.py#L24>`_ <https://github.com/opensearch-project/opensearch-py/blob/master/opensearch/serializer.py#L24>`_
is used to encode all outgoing requests. is used to encode all outgoing requests.
However, you can implement your own custom serializer:: However, you can implement your own custom serializer::
from elasticsearch.serializer import JSONSerializer from opensearch.serializer import JSONSerializer
class SetEncoder(JSONSerializer): class SetEncoder(JSONSerializer):
def default(self, obj): def default(self, obj):
@@ -166,7 +166,7 @@ class AsyncElasticsearch(object):
return 'CustomSomethingRepresentation' return 'CustomSomethingRepresentation'
return JSONSerializer.default(self, obj) return JSONSerializer.default(self, obj)
es = Elasticsearch(serializer=SetEncoder()) es = OpenSearch(serializer=SetEncoder())
""" """
@@ -174,16 +174,16 @@ class AsyncElasticsearch(object):
""" """
:arg hosts: list of nodes, or a single node, we should connect to. :arg hosts: list of nodes, or a single node, we should connect to.
Node should be a dictionary ({"host": "localhost", "port": 9200}), Node should be a dictionary ({"host": "localhost", "port": 9200}),
the entire dictionary will be passed to the :class:`~elasticsearch.Connection` the entire dictionary will be passed to the :class:`~opensearch.Connection`
class as kwargs, or a string in the format of ``host[:port]`` which will be class as kwargs, or a string in the format of ``host[:port]`` which will be
translated to a dictionary automatically. If no value is given the translated to a dictionary automatically. If no value is given the
:class:`~elasticsearch.Connection` class defaults will be used. :class:`~opensearch.Connection` class defaults will be used.
:arg transport_class: :class:`~elasticsearch.Transport` subclass to use. :arg transport_class: :class:`~opensearch.Transport` subclass to use.
:arg kwargs: any additional arguments will be passed on to the :arg kwargs: any additional arguments will be passed on to the
:class:`~elasticsearch.Transport` class and, subsequently, to the :class:`~opensearch.Transport` class and, subsequently, to the
:class:`~elasticsearch.Connection` instances. :class:`~opensearch.Connection` instances.
""" """
self.transport = transport_class(_normalize_hosts(hosts), **kwargs) self.transport = transport_class(_normalize_hosts(hosts), **kwargs)
@@ -210,7 +210,7 @@ class AsyncElasticsearch(object):
return "<{cls}({cons})>".format(cls=self.__class__.__name__, cons=cons) return "<{cls}({cons})>".format(cls=self.__class__.__name__, cons=cons)
except Exception: except Exception:
# probably operating on custom transport and connection_pool, ignore # probably operating on custom transport and connection_pool, ignore
return super(AsyncElasticsearch, self).__repr__() return super(AsyncOpenSearch, self).__repr__()
async def __aenter__(self): async def __aenter__(self):
if hasattr(self.transport, "_async_call"): if hasattr(self.transport, "_async_call"):
@@ -44,7 +44,7 @@ from .tasks import TasksClient
logger: logging.Logger logger: logging.Logger
class AsyncElasticsearch(object): class AsyncOpenSearch(object):
transport: AsyncTransport transport: AsyncTransport
cat: CatClient cat: CatClient
@@ -63,7 +63,7 @@ class AsyncElasticsearch(object):
**kwargs: Any, **kwargs: Any,
) -> None: ... ) -> None: ...
def __repr__(self) -> str: ... def __repr__(self) -> str: ...
async def __aenter__(self) -> "AsyncElasticsearch": ... async def __aenter__(self) -> "AsyncOpenSearch": ...
async def __aexit__(self, *_: Any) -> None: ... async def __aexit__(self, *_: Any) -> None: ...
async def close(self) -> None: ... async def close(self) -> None: ...
# AUTO-GENERATED-API-DEFINITIONS # # AUTO-GENERATED-API-DEFINITIONS #
@@ -37,7 +37,7 @@ class NodesClient(NamespacedClient):
:arg body: An object containing the password for the :arg body: An object containing the password for the
elasticsearch keystore opensearch keystore
:arg node_id: A comma-separated list of node IDs to span the :arg node_id: A comma-separated list of node IDs to span the
reload/reinit call. Should stay empty because reloading usually involves reload/reinit call. Should stay empty because reloading usually involves
all cluster nodes. all cluster nodes.
@@ -30,11 +30,11 @@ from ...client.utils import _escape as _escape
from ...client.utils import _make_path as _make_path # noqa from ...client.utils import _make_path as _make_path # noqa
from ...client.utils import _normalize_hosts as _normalize_hosts from ...client.utils import _normalize_hosts as _normalize_hosts
from ...client.utils import query_params as query_params from ...client.utils import query_params as query_params
from ..client import AsyncElasticsearch from ..client import AsyncOpenSearch
from ..transport import AsyncTransport from ..transport import AsyncTransport
class NamespacedClient: class NamespacedClient:
client: AsyncElasticsearch client: AsyncOpenSearch
def __init__(self, client: AsyncElasticsearch) -> None: ... def __init__(self, client: AsyncOpenSearch) -> None: ...
@property @property
def transport(self) -> AsyncTransport: ... def transport(self) -> AsyncTransport: ...
@@ -24,8 +24,8 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# Licensed to Elasticsearch B.V under one or more agreements. # Licensed to Elasticsearch B.V.under one or more agreements.
# Elasticsearch B.V licenses this file to you under the Apache 2.0 License. # Elasticsearch B.V.licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information # See the LICENSE file in the project root for more information
import asyncio import asyncio
@@ -40,9 +40,9 @@ from ..helpers.actions import (
expand_action, expand_action,
) )
from ..helpers.errors import ScanError from ..helpers.errors import ScanError
from .client import AsyncElasticsearch # noqa from .client import AsyncOpenSearch # noqa
logger = logging.getLogger("elasticsearch.helpers") logger = logging.getLogger("opensearch.helpers")
async def _chunk_actions(actions, chunk_size, max_chunk_bytes, serializer): async def _chunk_actions(actions, chunk_size, max_chunk_bytes, serializer):
@@ -73,7 +73,7 @@ async def _process_bulk_chunk(
**kwargs **kwargs
): ):
""" """
Send a bulk request to elasticsearch and process the output. Send a bulk request to opensearch and process the output.
""" """
if not isinstance(ignore_status, (list, tuple)): if not isinstance(ignore_status, (list, tuple)):
ignore_status = (ignore_status,) ignore_status = (ignore_status,)
@@ -146,7 +146,7 @@ async def async_streaming_bulk(
""" """
Streaming bulk consumes actions from the iterable passed in and yields Streaming bulk consumes actions from the iterable passed in and yields
results per action. For non-streaming usecases use results per action. For non-streaming usecases use
:func:`~elasticsearch.helpers.async_bulk` which is a wrapper around streaming :func:`~opensearch.helpers.async_bulk` which is a wrapper around streaming
bulk that returns summary information about the bulk operation once the bulk that returns summary information about the bulk operation once the
entire input is consumed and sent. entire input is consumed and sent.
@@ -156,7 +156,7 @@ async def async_streaming_bulk(
every subsequent rejection for the same chunk, for double the time every every subsequent rejection for the same chunk, for double the time every
time up to ``max_backoff`` seconds. time up to ``max_backoff`` seconds.
:arg client: instance of :class:`~elasticsearch.AsyncElasticsearch` to use :arg client: instance of :class:`~opensearch.AsyncOpenSearch` to use
:arg actions: iterable or async iterable containing the actions to be executed :arg actions: iterable or async iterable containing the actions to be executed
:arg chunk_size: number of docs in one chunk sent to es (default: 500) :arg chunk_size: number of docs in one chunk sent to es (default: 500)
:arg max_chunk_bytes: the maximum size of the request in bytes (default: 100MB) :arg max_chunk_bytes: the maximum size of the request in bytes (default: 100MB)
@@ -242,9 +242,9 @@ async def async_bulk(
client, actions, stats_only=False, ignore_status=(), *args, **kwargs client, actions, stats_only=False, ignore_status=(), *args, **kwargs
): ):
""" """
Helper for the :meth:`~elasticsearch.AsyncElasticsearch.bulk` api that provides Helper for the :meth:`~opensearch.AsyncOpenSearch.bulk` api that provides
a more human friendly interface - it consumes an iterator of actions and a more human friendly interface - it consumes an iterator of actions and
sends them to elasticsearch in chunks. It returns a tuple with summary sends them to opensearch in chunks. It returns a tuple with summary
information - number of successfully executed actions and either list of information - number of successfully executed actions and either list of
errors or number of errors if ``stats_only`` is set to ``True``. Note that errors or number of errors if ``stats_only`` is set to ``True``. Note that
by default we raise a ``BulkIndexError`` when we encounter an error so by default we raise a ``BulkIndexError`` when we encounter an error so
@@ -254,19 +254,19 @@ async def async_bulk(
When errors are being collected original document data is included in the When errors are being collected original document data is included in the
error dictionary which can lead to an extra high memory usage. If you need error dictionary which can lead to an extra high memory usage. If you need
to process a lot of data and want to ignore/collect errors please consider to process a lot of data and want to ignore/collect errors please consider
using the :func:`~elasticsearch.helpers.async_streaming_bulk` helper which will using the :func:`~opensearch.helpers.async_streaming_bulk` helper which will
just return the errors and not store them in memory. just return the errors and not store them in memory.
:arg client: instance of :class:`~elasticsearch.AsyncElasticsearch` to use :arg client: instance of :class:`~opensearch.AsyncOpenSearch` to use
:arg actions: iterator containing the actions :arg actions: iterator containing the actions
:arg stats_only: if `True` only report number of successful/failed :arg stats_only: if `True` only report number of successful/failed
operations instead of just number of successful and a list of error responses operations instead of just number of successful and a list of error responses
:arg ignore_status: list of HTTP status code that you want to ignore :arg ignore_status: list of HTTP status code that you want to ignore
Any additional keyword arguments will be passed to Any additional keyword arguments will be passed to
:func:`~elasticsearch.helpers.async_streaming_bulk` which is used to execute :func:`~opensearch.helpers.async_streaming_bulk` which is used to execute
the operation, see :func:`~elasticsearch.helpers.async_streaming_bulk` for more the operation, see :func:`~opensearch.helpers.async_streaming_bulk` for more
accepted parameters. accepted parameters.
""" """
success, failed = 0, 0 success, failed = 0, 0
@@ -304,7 +304,7 @@ async def async_scan(
): ):
""" """
Simple abstraction on top of the Simple abstraction on top of the
:meth:`~elasticsearch.AsyncElasticsearch.scroll` api - a simple iterator that :meth:`~opensearch.AsyncOpenSearch.scroll` api - a simple iterator that
yields all hits as returned by underlining scroll requests. yields all hits as returned by underlining scroll requests.
By default scan does not return results in any pre-determined order. To By default scan does not return results in any pre-determined order. To
@@ -313,8 +313,8 @@ async def async_scan(
may be an expensive operation and will negate the performance benefits of may be an expensive operation and will negate the performance benefits of
using ``scan``. using ``scan``.
:arg client: instance of :class:`~elasticsearch.AsyncElasticsearch` to use :arg client: instance of :class:`~opensearch.AsyncOpenSearch` to use
:arg query: body for the :meth:`~elasticsearch.AsyncElasticsearch.search` api :arg query: body for the :meth:`~opensearch.AsyncOpenSearch.search` api
:arg scroll: Specify how long a consistent view of the index should be :arg scroll: Specify how long a consistent view of the index should be
maintained for scrolled search maintained for scrolled search
:arg raise_on_error: raises an exception (``ScanError``) if an error is :arg raise_on_error: raises an exception (``ScanError``) if an error is
@@ -329,10 +329,10 @@ async def async_scan(
scroll API at the end of the method on completion or error, defaults scroll API at the end of the method on completion or error, defaults
to true. to true.
:arg scroll_kwargs: additional kwargs to be passed to :arg scroll_kwargs: additional kwargs to be passed to
:meth:`~elasticsearch.AsyncElasticsearch.scroll` :meth:`~opensearch.AsyncOpenSearch.scroll`
Any additional keyword arguments will be passed to the initial Any additional keyword arguments will be passed to the initial
:meth:`~elasticsearch.AsyncElasticsearch.search` call:: :meth:`~opensearch.AsyncOpenSearch.search` call::
async_scan(es, async_scan(es,
query={"query": {"match": {"title": "python"}}}, query={"query": {"match": {"title": "python"}}},
@@ -428,8 +428,8 @@ async def async_reindex(
to another, potentially (if `target_client` is specified) on a different cluster. to another, potentially (if `target_client` is specified) on a different cluster.
If you don't specify the query you will reindex all the documents. If you don't specify the query you will reindex all the documents.
Since ``2.3`` a :meth:`~elasticsearch.AsyncElasticsearch.reindex` api is Since ``2.3`` a :meth:`~opensearch.AsyncOpenSearch.reindex` api is
available as part of elasticsearch itself. It is recommended to use the api available as part of opensearch itself. It is recommended to use the api
instead of this helper wherever possible. The helper is here mostly for instead of this helper wherever possible. The helper is here mostly for
backwards compatibility and for situations where more flexibility is backwards compatibility and for situations where more flexibility is
needed. needed.
@@ -438,20 +438,20 @@ async def async_reindex(
This helper doesn't transfer mappings, just the data. This helper doesn't transfer mappings, just the data.
:arg client: instance of :class:`~elasticsearch.AsyncElasticsearch` to use (for :arg client: instance of :class:`~opensearch.AsyncOpenSearch` to use (for
read if `target_client` is specified as well) read if `target_client` is specified as well)
:arg source_index: index (or list of indices) to read documents from :arg source_index: index (or list of indices) to read documents from
:arg target_index: name of the index in the target cluster to populate :arg target_index: name of the index in the target cluster to populate
:arg query: body for the :meth:`~elasticsearch.AsyncElasticsearch.search` api :arg query: body for the :meth:`~opensearch.AsyncOpenSearch.search` api
:arg target_client: optional, is specified will be used for writing (thus :arg target_client: optional, is specified will be used for writing (thus
enabling reindex between clusters) enabling reindex between clusters)
:arg chunk_size: number of docs in one chunk sent to es (default: 500) :arg chunk_size: number of docs in one chunk sent to es (default: 500)
:arg scroll: Specify how long a consistent view of the index should be :arg scroll: Specify how long a consistent view of the index should be
maintained for scrolled search maintained for scrolled search
:arg scan_kwargs: additional kwargs to be passed to :arg scan_kwargs: additional kwargs to be passed to
:func:`~elasticsearch.helpers.async_scan` :func:`~opensearch.helpers.async_scan`
:arg bulk_kwargs: additional kwargs to be passed to :arg bulk_kwargs: additional kwargs to be passed to
:func:`~elasticsearch.helpers.async_bulk` :func:`~opensearch.helpers.async_bulk`
""" """
target_client = client if target_client is None else target_client target_client = client if target_client is None else target_client
docs = async_scan( docs = async_scan(
@@ -42,7 +42,7 @@ from typing import (
) )
from ..serializer import Serializer from ..serializer import Serializer
from .client import AsyncElasticsearch from .client import AsyncOpenSearch
logger: logging.Logger logger: logging.Logger
@@ -52,7 +52,7 @@ def _chunk_actions(
actions: Any, chunk_size: int, max_chunk_bytes: int, serializer: Serializer actions: Any, chunk_size: int, max_chunk_bytes: int, serializer: Serializer
) -> AsyncGenerator[Any, None]: ... ) -> AsyncGenerator[Any, None]: ...
def _process_bulk_chunk( def _process_bulk_chunk(
client: AsyncElasticsearch, client: AsyncOpenSearch,
bulk_actions: Any, bulk_actions: Any,
bulk_data: Any, bulk_data: Any,
raise_on_exception: bool = ..., raise_on_exception: bool = ...,
@@ -66,7 +66,7 @@ def azip(
*iterables: Union[Iterable[T], AsyncIterable[T]] *iterables: Union[Iterable[T], AsyncIterable[T]]
) -> AsyncGenerator[Tuple[T, ...], None]: ... ) -> AsyncGenerator[Tuple[T, ...], None]: ...
def async_streaming_bulk( def async_streaming_bulk(
client: AsyncElasticsearch, client: AsyncOpenSearch,
actions: Union[Iterable[Any], AsyncIterable[Any]], actions: Union[Iterable[Any], AsyncIterable[Any]],
chunk_size: int = ..., chunk_size: int = ...,
max_chunk_bytes: int = ..., max_chunk_bytes: int = ...,
@@ -82,7 +82,7 @@ def async_streaming_bulk(
**kwargs: Any **kwargs: Any
) -> AsyncGenerator[Tuple[bool, Any], None]: ... ) -> AsyncGenerator[Tuple[bool, Any], None]: ...
async def async_bulk( async def async_bulk(
client: AsyncElasticsearch, client: AsyncOpenSearch,
actions: Union[Iterable[Any], AsyncIterable[Any]], actions: Union[Iterable[Any], AsyncIterable[Any]],
stats_only: bool = ..., stats_only: bool = ...,
ignore_status: Optional[Union[int, Collection[int]]] = ..., ignore_status: Optional[Union[int, Collection[int]]] = ...,
@@ -90,7 +90,7 @@ async def async_bulk(
**kwargs: Any **kwargs: Any
) -> Tuple[int, Union[int, List[Any]]]: ... ) -> Tuple[int, Union[int, List[Any]]]: ...
def async_scan( def async_scan(
client: AsyncElasticsearch, client: AsyncOpenSearch,
query: Optional[Any] = ..., query: Optional[Any] = ...,
scroll: str = ..., scroll: str = ...,
raise_on_error: bool = ..., raise_on_error: bool = ...,
@@ -102,11 +102,11 @@ def async_scan(
**kwargs: Any **kwargs: Any
) -> AsyncGenerator[int, None]: ... ) -> AsyncGenerator[int, None]: ...
async def async_reindex( async def async_reindex(
client: AsyncElasticsearch, client: AsyncOpenSearch,
source_index: Union[str, Collection[str]], source_index: Union[str, Collection[str]],
target_index: str, target_index: str,
query: Any = ..., query: Any = ...,
target_client: Optional[AsyncElasticsearch] = ..., target_client: Optional[AsyncOpenSearch] = ...,
chunk_size: int = ..., chunk_size: int = ...,
scroll: str = ..., scroll: str = ...,
scan_kwargs: Optional[Mapping[str, Any]] = ..., scan_kwargs: Optional[Mapping[str, Any]] = ...,
@@ -106,11 +106,11 @@ class AIOHttpConnection(AsyncConnection):
**kwargs, **kwargs,
): ):
""" """
Default connection class for ``AsyncElasticsearch`` using the `aiohttp` library and the http protocol. Default connection class for ``AsyncOpenSearch`` using the `aiohttp` library and the http protocol.
:arg host: hostname of the node (default: localhost) :arg host: hostname of the node (default: localhost)
:arg port: port to use (integer, default: 9200) :arg port: port to use (integer, default: 9200)
:arg url_prefix: optional url prefix for elasticsearch :arg url_prefix: optional url prefix for opensearch
:arg timeout: default timeout in seconds (float, default: 10) :arg timeout: default timeout in seconds (float, default: 10)
:arg http_auth: optional http auth information as either ':' separated :arg http_auth: optional http auth information as either ':' separated
string or a tuple string or a tuple
@@ -39,7 +39,7 @@ from ..transport import Transport
from .compat import get_running_loop from .compat import get_running_loop
from .http_aiohttp import AIOHttpConnection from .http_aiohttp import AIOHttpConnection
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
class AsyncTransport(Transport): class AsyncTransport(Transport):
@@ -56,8 +56,8 @@ class AsyncTransport(Transport):
""" """
:arg hosts: list of dictionaries, each containing keyword arguments to :arg hosts: list of dictionaries, each containing keyword arguments to
create a `connection_class` instance create a `connection_class` instance
:arg connection_class: subclass of :class:`~elasticsearch.Connection` to use :arg connection_class: subclass of :class:`~opensearch.Connection` to use
:arg connection_pool_class: subclass of :class:`~elasticsearch.ConnectionPool` to use :arg connection_pool_class: subclass of :class:`~opensearch.ConnectionPool` to use
:arg host_info_callback: callback responsible for taking the node information from :arg host_info_callback: callback responsible for taking the node information from
`/_cluster/nodes`, along with already extracted information, and `/_cluster/nodes`, along with already extracted information, and
producing a list of arguments (same as `hosts` parameter) producing a list of arguments (same as `hosts` parameter)
@@ -114,7 +114,7 @@ class AsyncTransport(Transport):
that was deferred within __init__() should be done here now. that was deferred within __init__() should be done here now.
This method will only be called once per AsyncTransport instance This method will only be called once per AsyncTransport instance
and is called from one of AsyncElasticsearch.__aenter__(), and is called from one of AsyncOpenSearch.__aenter__(),
AsyncTransport.perform_request() or AsyncTransport.get_connection() AsyncTransport.perform_request() or AsyncTransport.get_connection()
""" """
# Detect the async loop we're running in and set it # Detect the async loop we're running in and set it
@@ -300,7 +300,7 @@ class AsyncTransport(Transport):
Mark a connection as dead (failed) in the connection pool. If sniffing Mark a connection as dead (failed) in the connection pool. If sniffing
on failure is enabled this will initiate the sniffing process. on failure is enabled this will initiate the sniffing process.
:arg connection: instance of :class:`~elasticsearch.Connection` that failed :arg connection: instance of :class:`~opensearch.Connection` that failed
""" """
self.connection_pool.mark_dead(connection) self.connection_pool.mark_dead(connection)
if self.sniff_on_connection_fail: if self.sniff_on_connection_fail:
@@ -324,9 +324,9 @@ class AsyncTransport(Transport):
:arg method: HTTP method to use :arg method: HTTP method to use
:arg url: absolute url (without host) to target :arg url: absolute url (without host) to target
:arg headers: dictionary of headers, will be handed over to the :arg headers: dictionary of headers, will be handed over to the
underlying :class:`~elasticsearch.Connection` class underlying :class:`~opensearch.Connection` class
:arg params: dictionary of query parameters, will be handed over to the :arg params: dictionary of query parameters, will be handed over to the
underlying :class:`~elasticsearch.Connection` class for serialization underlying :class:`~opensearch.Connection` class for serialization
:arg body: body of the request, will be serialized using serializer and :arg body: body of the request, will be serialized using serializer and
passed to the connection passed to the connection
""" """
@@ -42,23 +42,23 @@ from .snapshot import SnapshotClient
from .tasks import TasksClient from .tasks import TasksClient
from .utils import SKIP_IN_PATH, _bulk_body, _make_path, _normalize_hosts, query_params from .utils import SKIP_IN_PATH, _bulk_body, _make_path, _normalize_hosts, query_params
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
class Elasticsearch(object): class OpenSearch(object):
""" """
Elasticsearch low-level client. Provides a straightforward mapping from OpenSearch low-level client. Provides a straightforward mapping from
Python to ES REST endpoints. Python to ES REST endpoints.
The instance has attributes ``cat``, ``cluster``, ``indices``, ``ingest``, The instance has attributes ``cat``, ``cluster``, ``indices``, ``ingest``,
``nodes``, ``snapshot`` and ``tasks`` that provide access to instances of ``nodes``, ``snapshot`` and ``tasks`` that provide access to instances of
:class:`~elasticsearch.client.CatClient`, :class:`~opensearch.client.CatClient`,
:class:`~elasticsearch.client.ClusterClient`, :class:`~opensearch.client.ClusterClient`,
:class:`~elasticsearch.client.IndicesClient`, :class:`~opensearch.client.IndicesClient`,
:class:`~elasticsearch.client.IngestClient`, :class:`~opensearch.client.IngestClient`,
:class:`~elasticsearch.client.NodesClient`, :class:`~opensearch.client.NodesClient`,
:class:`~elasticsearch.client.SnapshotClient` and :class:`~opensearch.client.SnapshotClient` and
:class:`~elasticsearch.client.TasksClient` respectively. This is the :class:`~opensearch.client.TasksClient` respectively. This is the
preferred (and only supported) way to get access to those classes and their preferred (and only supported) way to get access to those classes and their
methods. methods.
@@ -66,15 +66,15 @@ class Elasticsearch(object):
the ``connection_class`` parameter:: the ``connection_class`` parameter::
# create connection to localhost using the ThriftConnection # create connection to localhost using the ThriftConnection
es = Elasticsearch(connection_class=ThriftConnection) es = OpenSearch(connection_class=ThriftConnection)
If you want to turn on :ref:`sniffing` you have several options (described If you want to turn on :ref:`sniffing` you have several options (described
in :class:`~elasticsearch.Transport`):: in :class:`~opensearch.Transport`)::
# create connection that will automatically inspect the cluster to get # create connection that will automatically inspect the cluster to get
# the list of active nodes. Start with nodes running on 'esnode1' and # the list of active nodes. Start with nodes running on 'esnode1' and
# 'esnode2' # 'esnode2'
es = Elasticsearch( es = OpenSearch(
['esnode1', 'esnode2'], ['esnode1', 'esnode2'],
# sniff before doing anything # sniff before doing anything
sniff_on_start=True, sniff_on_start=True,
@@ -89,16 +89,16 @@ class Elasticsearch(object):
# connect to localhost directly and another node using SSL on port 443 # connect to localhost directly and another node using SSL on port 443
# and an url_prefix. Note that ``port`` needs to be an int. # and an url_prefix. Note that ``port`` needs to be an int.
es = Elasticsearch([ es = OpenSearch([
{'host': 'localhost'}, {'host': 'localhost'},
{'host': 'othernode', 'port': 443, 'url_prefix': 'es', 'use_ssl': True}, {'host': 'othernode', 'port': 443, 'url_prefix': 'es', 'use_ssl': True},
]) ])
If using SSL, there are several parameters that control how we deal with If using SSL, there are several parameters that control how we deal with
certificates (see :class:`~elasticsearch.Urllib3HttpConnection` for certificates (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -109,10 +109,10 @@ class Elasticsearch(object):
) )
If using SSL, but don't verify the certs, a warning message is showed If using SSL, but don't verify the certs, a warning message is showed
optionally (see :class:`~elasticsearch.Urllib3HttpConnection` for optionally (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -123,10 +123,10 @@ class Elasticsearch(object):
) )
SSL client authentication is supported SSL client authentication is supported
(see :class:`~elasticsearch.Urllib3HttpConnection` for (see :class:`~opensearch.Urllib3HttpConnection` for
detailed description of the options):: detailed description of the options)::
es = Elasticsearch( es = OpenSearch(
['localhost:443', 'other_host:443'], ['localhost:443', 'other_host:443'],
# turn on SSL # turn on SSL
use_ssl=True, use_ssl=True,
@@ -143,7 +143,7 @@ class Elasticsearch(object):
Alternatively you can use RFC-1738 formatted URLs, as long as they are not Alternatively you can use RFC-1738 formatted URLs, as long as they are not
in conflict with other options:: in conflict with other options::
es = Elasticsearch( es = OpenSearch(
[ [
'http://user:secret@localhost:9200/', 'http://user:secret@localhost:9200/',
'https://user:secret@other_host:443/production' 'https://user:secret@other_host:443/production'
@@ -152,11 +152,11 @@ class Elasticsearch(object):
) )
By default, `JSONSerializer By default, `JSONSerializer
<https://github.com/elastic/elasticsearch-py/blob/master/elasticsearch/serializer.py#L24>`_ <https://github.com/opensearch-project/opensearch-py/blob/master/opensearch/serializer.py#L24>`_
is used to encode all outgoing requests. is used to encode all outgoing requests.
However, you can implement your own custom serializer:: However, you can implement your own custom serializer::
from elasticsearch.serializer import JSONSerializer from opensearch.serializer import JSONSerializer
class SetEncoder(JSONSerializer): class SetEncoder(JSONSerializer):
def default(self, obj): def default(self, obj):
@@ -166,7 +166,7 @@ class Elasticsearch(object):
return 'CustomSomethingRepresentation' return 'CustomSomethingRepresentation'
return JSONSerializer.default(self, obj) return JSONSerializer.default(self, obj)
es = Elasticsearch(serializer=SetEncoder()) es = OpenSearch(serializer=SetEncoder())
""" """
@@ -174,16 +174,16 @@ class Elasticsearch(object):
""" """
:arg hosts: list of nodes, or a single node, we should connect to. :arg hosts: list of nodes, or a single node, we should connect to.
Node should be a dictionary ({"host": "localhost", "port": 9200}), Node should be a dictionary ({"host": "localhost", "port": 9200}),
the entire dictionary will be passed to the :class:`~elasticsearch.Connection` the entire dictionary will be passed to the :class:`~opensearch.Connection`
class as kwargs, or a string in the format of ``host[:port]`` which will be class as kwargs, or a string in the format of ``host[:port]`` which will be
translated to a dictionary automatically. If no value is given the translated to a dictionary automatically. If no value is given the
:class:`~elasticsearch.Connection` class defaults will be used. :class:`~opensearch.Connection` class defaults will be used.
:arg transport_class: :class:`~elasticsearch.Transport` subclass to use. :arg transport_class: :class:`~opensearch.Transport` subclass to use.
:arg kwargs: any additional arguments will be passed on to the :arg kwargs: any additional arguments will be passed on to the
:class:`~elasticsearch.Transport` class and, subsequently, to the :class:`~opensearch.Transport` class and, subsequently, to the
:class:`~elasticsearch.Connection` instances. :class:`~opensearch.Connection` instances.
""" """
self.transport = transport_class(_normalize_hosts(hosts), **kwargs) self.transport = transport_class(_normalize_hosts(hosts), **kwargs)
@@ -210,7 +210,7 @@ class Elasticsearch(object):
return "<{cls}({cons})>".format(cls=self.__class__.__name__, cons=cons) return "<{cls}({cons})>".format(cls=self.__class__.__name__, cons=cons)
except Exception: except Exception:
# probably operating on custom transport and connection_pool, ignore # probably operating on custom transport and connection_pool, ignore
return super(Elasticsearch, self).__repr__() return super(OpenSearch, self).__repr__()
def __enter__(self): def __enter__(self):
if hasattr(self.transport, "_async_call"): if hasattr(self.transport, "_async_call"):
@@ -44,7 +44,7 @@ from .tasks import TasksClient
logger: logging.Logger logger: logging.Logger
class Elasticsearch(object): class OpenSearch(object):
transport: Transport transport: Transport
cat: CatClient cat: CatClient
@@ -63,7 +63,7 @@ class Elasticsearch(object):
**kwargs: Any, **kwargs: Any,
) -> None: ... ) -> None: ...
def __repr__(self) -> str: ... def __repr__(self) -> str: ...
def __enter__(self) -> "Elasticsearch": ... def __enter__(self) -> "OpenSearch": ...
def __exit__(self, *_: Any) -> None: ... def __exit__(self, *_: Any) -> None: ...
def close(self) -> None: ... def close(self) -> None: ...
# AUTO-GENERATED-API-DEFINITIONS # # AUTO-GENERATED-API-DEFINITIONS #
@@ -37,7 +37,7 @@ class NodesClient(NamespacedClient):
:arg body: An object containing the password for the :arg body: An object containing the password for the
elasticsearch keystore opensearch keystore
:arg node_id: A comma-separated list of node IDs to span the :arg node_id: A comma-separated list of node IDs to span the
reload/reinit call. Should stay empty because reloading usually involves reload/reinit call. Should stay empty because reloading usually involves
all cluster nodes. all cluster nodes.
@@ -40,7 +40,7 @@ SKIP_IN_PATH = (None, "", b"", [], ())
def _normalize_hosts(hosts): def _normalize_hosts(hosts):
""" """
Helper function to transform hosts argument to Helper function to transform hosts argument to
:class:`~elasticsearch.Elasticsearch` to a list of dicts. :class:`~opensearch.OpenSearch` to a list of dicts.
""" """
# if hosts are empty, just defer to defaults down the line # if hosts are empty, just defer to defaults down the line
if hosts is None: if hosts is None:
@@ -38,7 +38,7 @@ from typing import (
Union, Union,
) )
from ..client import Elasticsearch from ..client import OpenSearch
from ..serializer import Serializer from ..serializer import Serializer
from ..transport import Transport from ..transport import Transport
@@ -61,7 +61,7 @@ def _bulk_body(
) -> str: ... ) -> str: ...
class NamespacedClient: class NamespacedClient:
client: Elasticsearch client: OpenSearch
def __init__(self, client: Elasticsearch) -> None: ... def __init__(self, client: OpenSearch) -> None: ...
@property @property
def transport(self) -> Transport: ... def transport(self) -> Transport: ...
@@ -41,17 +41,17 @@ except ImportError:
from .. import __version__, __versionstr__ from .. import __version__, __versionstr__
from ..exceptions import ( from ..exceptions import (
HTTP_EXCEPTIONS, HTTP_EXCEPTIONS,
ElasticsearchWarning,
ImproperlyConfigured, ImproperlyConfigured,
OpenSearchWarning,
TransportError, TransportError,
) )
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
# create the elasticsearch.trace logger, but only set propagate to False if the # create the opensearch.trace logger, but only set propagate to False if the
# logger hasn't already been configured # logger hasn't already been configured
_tracer_already_configured = "elasticsearch.trace" in logging.Logger.manager.loggerDict _tracer_already_configured = "opensearch.trace" in logging.Logger.manager.loggerDict
tracer = logging.getLogger("elasticsearch.trace") tracer = logging.getLogger("opensearch.trace")
if not _tracer_already_configured: if not _tracer_already_configured:
tracer.propagate = False tracer.propagate = False
@@ -60,7 +60,7 @@ _WARNING_RE = re.compile(r"\"([^\"]*)\"")
class Connection(object): class Connection(object):
""" """
Class responsible for maintaining a connection to an Elasticsearch node. It Class responsible for maintaining a connection to an OpenSearch node. It
holds persistent connection pool to it and it's main interface holds persistent connection pool to it and it's main interface
(`perform_request`) is thread-safe. (`perform_request`) is thread-safe.
@@ -69,7 +69,7 @@ class Connection(object):
:arg host: hostname of the node (default: localhost) :arg host: hostname of the node (default: localhost)
:arg port: port to use (integer, default: 9200) :arg port: port to use (integer, default: 9200)
:arg use_ssl: use ssl for the connection if `True` :arg use_ssl: use ssl for the connection if `True`
:arg url_prefix: optional url prefix for elasticsearch :arg url_prefix: optional url prefix for opensearch
:arg timeout: default timeout in seconds (float, default: 10) :arg timeout: default timeout in seconds (float, default: 10)
:arg http_compress: Use gzip compression :arg http_compress: Use gzip compression
:arg cloud_id: The Cloud ID from ElasticCloud. Convenient way to connect to cloud instances. :arg cloud_id: The Cloud ID from ElasticCloud. Convenient way to connect to cloud instances.
@@ -134,7 +134,7 @@ class Connection(object):
if os.getenv("ELASTIC_CLIENT_APIVERSIONING") == "1": if os.getenv("ELASTIC_CLIENT_APIVERSIONING") == "1":
self.headers.setdefault( self.headers.setdefault(
"accept", "accept",
"application/vnd.elasticsearch+json;compatible-with=%s" "application/vnd.opensearch+json;compatible-with=%s"
% (str(__version__[0]),), % (str(__version__[0]),),
) )
@@ -198,7 +198,7 @@ class Connection(object):
return return
# Grab only the message from each header, the rest is discarded. # Grab only the message from each header, the rest is discarded.
# Format is: '(number) Elasticsearch-(version)-(instance) "(message)"' # Format is: '(number) OpenSearch-(version)-(instance) "(message)"'
warning_messages = [] warning_messages = []
for header in warning_headers: for header in warning_headers:
# Because 'Requests' does it's own folding of multiple HTTP headers # Because 'Requests' does it's own folding of multiple HTTP headers
@@ -214,7 +214,7 @@ class Connection(object):
warning_messages.append(header) warning_messages.append(header)
for message in warning_messages: for message in warning_messages:
warnings.warn(message, category=ElasticsearchWarning) warnings.warn(message, category=OpenSearchWarning)
def _pretty_json(self, data): def _pretty_json(self, data):
# pretty JSON in tracer curl logs # pretty JSON in tracer curl logs
@@ -341,7 +341,7 @@ class Connection(object):
) )
def _get_default_user_agent(self): def _get_default_user_agent(self):
return "elasticsearch-py/%s (Python %s)" % (__versionstr__, python_version()) return "opensearch-py/%s (Python %s)" % (__versionstr__, python_version())
def _get_api_key_header_val(self, api_key): def _get_api_key_header_val(self, api_key):
""" """
@@ -77,7 +77,7 @@ class Urllib3HttpConnection(Connection):
:arg host: hostname of the node (default: localhost) :arg host: hostname of the node (default: localhost)
:arg port: port to use (integer, default: 9200) :arg port: port to use (integer, default: 9200)
:arg url_prefix: optional url prefix for elasticsearch :arg url_prefix: optional url prefix for opensearch
:arg timeout: default timeout in seconds (float, default: 10) :arg timeout: default timeout in seconds (float, default: 10)
:arg http_auth: optional http auth information as either ':' separated :arg http_auth: optional http auth information as either ':' separated
string or a tuple string or a tuple
@@ -36,7 +36,7 @@ except ImportError:
from .exceptions import ImproperlyConfigured from .exceptions import ImproperlyConfigured
logger = logging.getLogger("elasticsearch") logger = logging.getLogger("opensearch")
class ConnectionSelector(object): class ConnectionSelector(object):
@@ -48,7 +48,7 @@ class ConnectionSelector(object):
*currently* live connections to choose from. *currently* live connections to choose from.
The options dictionary is the one that has been passed to The options dictionary is the one that has been passed to
:class:`~elasticsearch.Transport` as `hosts` param and the same that is :class:`~opensearch.Transport` as `hosts` param and the same that is
used to construct the Connection object itself. When the Connection was used to construct the Connection object itself. When the Connection was
created from information retrieved from the cluster via the sniffing created from information retrieved from the cluster via the sniffing
process it will be the dictionary returned by the `host_info_callback`. process it will be the dictionary returned by the `host_info_callback`.
@@ -99,11 +99,11 @@ class RoundRobinSelector(ConnectionSelector):
class ConnectionPool(object): class ConnectionPool(object):
""" """
Container holding the :class:`~elasticsearch.Connection` instances, Container holding the :class:`~opensearch.Connection` instances,
managing the selection process (via a managing the selection process (via a
:class:`~elasticsearch.ConnectionSelector`) and dead connections. :class:`~opensearch.ConnectionSelector`) and dead connections.
It's only interactions are with the :class:`~elasticsearch.Transport` class It's only interactions are with the :class:`~opensearch.Transport` class
that drives all the actions within `ConnectionPool`. that drives all the actions within `ConnectionPool`.
Initially connections are stored on the class as a list and, along with the Initially connections are stored on the class as a list and, along with the
@@ -131,12 +131,12 @@ class ConnectionPool(object):
): ):
""" """
:arg connections: list of tuples containing the :arg connections: list of tuples containing the
:class:`~elasticsearch.Connection` instance and it's options :class:`~opensearch.Connection` instance and it's options
:arg dead_timeout: number of seconds a connection should be retired for :arg dead_timeout: number of seconds a connection should be retired for
after a failure, increases on consecutive failures after a failure, increases on consecutive failures
:arg timeout_cutoff: number of consecutive failures after which the :arg timeout_cutoff: number of consecutive failures after which the
timeout doesn't increase timeout doesn't increase
:arg selector_class: :class:`~elasticsearch.ConnectionSelector` :arg selector_class: :class:`~opensearch.ConnectionSelector`
subclass to use if more than one connection is live subclass to use if more than one connection is live
:arg randomize_hosts: shuffle the list of connections upon arrival to :arg randomize_hosts: shuffle the list of connections upon arrival to
avoid dog piling effect across processes avoid dog piling effect across processes
@@ -26,7 +26,7 @@
__all__ = [ __all__ = [
"ImproperlyConfigured", "ImproperlyConfigured",
"ElasticsearchException", "OpenSearchException",
"SerializationError", "SerializationError",
"TransportError", "TransportError",
"NotFoundError", "NotFoundError",
@@ -46,21 +46,21 @@ class ImproperlyConfigured(Exception):
""" """
class ElasticsearchException(Exception): class OpenSearchException(Exception):
""" """
Base class for all exceptions raised by this package's operations (doesn't Base class for all exceptions raised by this package's operations (doesn't
apply to :class:`~elasticsearch.ImproperlyConfigured`). apply to :class:`~opensearch.ImproperlyConfigured`).
""" """
class SerializationError(ElasticsearchException): class SerializationError(OpenSearchException):
""" """
Data passed in failed to serialize properly in the ``Serializer`` being Data passed in failed to serialize properly in the ``Serializer`` being
used. used.
""" """
class TransportError(ElasticsearchException): class TransportError(OpenSearchException):
""" """
Exception raised when ES returns a non-OK (>=400) HTTP status code. Or when Exception raised when ES returns a non-OK (>=400) HTTP status code. Or when
an actual connection error happens; in that case the ``status_code`` will an actual connection error happens; in that case the ``status_code`` will
@@ -116,7 +116,7 @@ class TransportError(ElasticsearchException):
class ConnectionError(TransportError): class ConnectionError(TransportError):
""" """
Error raised when there was an exception while talking to ES. Original Error raised when there was an exception while talking to ES. Original
exception from the underlying :class:`~elasticsearch.Connection` exception from the underlying :class:`~opensearch.Connection`
implementation is available as ``.info``. implementation is available as ``.info``.
""" """
@@ -162,16 +162,16 @@ class AuthorizationException(TransportError):
"""Exception representing a 403 status code.""" """Exception representing a 403 status code."""
class ElasticsearchWarning(Warning): class OpenSearchWarning(Warning):
"""Warning that is raised when a deprecated option """Warning that is raised when a deprecated option
or incorrect usage is flagged via the 'Warning' HTTP header. or incorrect usage is flagged via the 'Warning' HTTP header.
""" """
# Alias of 'ElasticsearchWarning' for backwards compatibility. # Alias of 'OpenSearchWarning' for backwards compatibility.
# Additional functionality was added to the 'Warning' HTTP header # Additional functionality was added to the 'Warning' HTTP header
# not related to deprecations. # not related to deprecations.
ElasticsearchDeprecationWarning = ElasticsearchWarning OpenSearchDeprecationWarning = OpenSearchWarning
# more generic mappings from status_code to python exceptions # more generic mappings from status_code to python exceptions
@@ -27,10 +27,10 @@
from typing import Any, Dict, Union from typing import Any, Dict, Union
class ImproperlyConfigured(Exception): ... class ImproperlyConfigured(Exception): ...
class ElasticsearchException(Exception): ... class OpenSearchException(Exception): ...
class SerializationError(ElasticsearchException): ... class SerializationError(OpenSearchException): ...
class TransportError(ElasticsearchException): class TransportError(OpenSearchException):
@property @property
def status_code(self) -> Union[str, int]: ... def status_code(self) -> Union[str, int]: ...
@property @property
@@ -52,8 +52,8 @@ class ConflictError(TransportError): ...
class RequestError(TransportError): ... class RequestError(TransportError): ...
class AuthenticationException(TransportError): ... class AuthenticationException(TransportError): ...
class AuthorizationException(TransportError): ... class AuthorizationException(TransportError): ...
class ElasticsearchWarning(Warning): ... class OpenSearchWarning(Warning): ...
ElasticsearchDeprecationWarning = ElasticsearchWarning OpenSearchDeprecationWarning = OpenSearchWarning
HTTP_EXCEPTIONS: Dict[int, ElasticsearchException] HTTP_EXCEPTIONS: Dict[int, OpenSearchException]
@@ -32,14 +32,14 @@ from ..compat import Mapping, Queue, map, string_types
from ..exceptions import TransportError from ..exceptions import TransportError
from .errors import BulkIndexError, ScanError from .errors import BulkIndexError, ScanError
logger = logging.getLogger("elasticsearch.helpers") logger = logging.getLogger("opensearch.helpers")
def expand_action(data): def expand_action(data):
""" """
From one document or action definition passed in by the user extract the From one document or action definition passed in by the user extract the
action/data lines needed for elasticsearch's action/data lines needed for opensearch's
:meth:`~elasticsearch.Elasticsearch.bulk` api. :meth:`~opensearch.OpenSearch.bulk` api.
""" """
# when given a string, assume user wants to index raw json # when given a string, assume user wants to index raw json
if isinstance(data, string_types): if isinstance(data, string_types):
@@ -237,7 +237,7 @@ def _process_bulk_chunk(
**kwargs **kwargs
): ):
""" """
Send a bulk request to elasticsearch and process the output. Send a bulk request to opensearch and process the output.
""" """
kwargs = _add_helper_meta_to_kwargs(kwargs, "bp") kwargs = _add_helper_meta_to_kwargs(kwargs, "bp")
@@ -293,7 +293,7 @@ def streaming_bulk(
""" """
Streaming bulk consumes actions from the iterable passed in and yields Streaming bulk consumes actions from the iterable passed in and yields
results per action. For non-streaming usecases use results per action. For non-streaming usecases use
:func:`~elasticsearch.helpers.bulk` which is a wrapper around streaming :func:`~opensearch.helpers.bulk` which is a wrapper around streaming
bulk that returns summary information about the bulk operation once the bulk that returns summary information about the bulk operation once the
entire input is consumed and sent. entire input is consumed and sent.
@@ -303,7 +303,7 @@ def streaming_bulk(
every subsequent rejection for the same chunk, for double the time every every subsequent rejection for the same chunk, for double the time every
time up to ``max_backoff`` seconds. time up to ``max_backoff`` seconds.
:arg client: instance of :class:`~elasticsearch.Elasticsearch` to use :arg client: instance of :class:`~opensearch.OpenSearch` to use
:arg actions: iterable containing the actions to be executed :arg actions: iterable containing the actions to be executed
:arg chunk_size: number of docs in one chunk sent to es (default: 500) :arg chunk_size: number of docs in one chunk sent to es (default: 500)
:arg max_chunk_bytes: the maximum size of the request in bytes (default: 100MB) :arg max_chunk_bytes: the maximum size of the request in bytes (default: 100MB)
@@ -382,9 +382,9 @@ def streaming_bulk(
def bulk(client, actions, stats_only=False, ignore_status=(), *args, **kwargs): def bulk(client, actions, stats_only=False, ignore_status=(), *args, **kwargs):
""" """
Helper for the :meth:`~elasticsearch.Elasticsearch.bulk` api that provides Helper for the :meth:`~opensearch.OpenSearch.bulk` api that provides
a more human friendly interface - it consumes an iterator of actions and a more human friendly interface - it consumes an iterator of actions and
sends them to elasticsearch in chunks. It returns a tuple with summary sends them to opensearch in chunks. It returns a tuple with summary
information - number of successfully executed actions and either list of information - number of successfully executed actions and either list of
errors or number of errors if ``stats_only`` is set to ``True``. Note that errors or number of errors if ``stats_only`` is set to ``True``. Note that
by default we raise a ``BulkIndexError`` when we encounter an error so by default we raise a ``BulkIndexError`` when we encounter an error so
@@ -394,19 +394,19 @@ def bulk(client, actions, stats_only=False, ignore_status=(), *args, **kwargs):
When errors are being collected original document data is included in the When errors are being collected original document data is included in the
error dictionary which can lead to an extra high memory usage. If you need error dictionary which can lead to an extra high memory usage. If you need
to process a lot of data and want to ignore/collect errors please consider to process a lot of data and want to ignore/collect errors please consider
using the :func:`~elasticsearch.helpers.streaming_bulk` helper which will using the :func:`~opensearch.helpers.streaming_bulk` helper which will
just return the errors and not store them in memory. just return the errors and not store them in memory.
:arg client: instance of :class:`~elasticsearch.Elasticsearch` to use :arg client: instance of :class:`~opensearch.OpenSearch` to use
:arg actions: iterator containing the actions :arg actions: iterator containing the actions
:arg stats_only: if `True` only report number of successful/failed :arg stats_only: if `True` only report number of successful/failed
operations instead of just number of successful and a list of error responses operations instead of just number of successful and a list of error responses
:arg ignore_status: list of HTTP status code that you want to ignore :arg ignore_status: list of HTTP status code that you want to ignore
Any additional keyword arguments will be passed to Any additional keyword arguments will be passed to
:func:`~elasticsearch.helpers.streaming_bulk` which is used to execute :func:`~opensearch.helpers.streaming_bulk` which is used to execute
the operation, see :func:`~elasticsearch.helpers.streaming_bulk` for more the operation, see :func:`~opensearch.helpers.streaming_bulk` for more
accepted parameters. accepted parameters.
""" """
success, failed = 0, 0 success, failed = 0, 0
@@ -445,7 +445,7 @@ def parallel_bulk(
""" """
Parallel version of the bulk helper run in multiple threads at once. Parallel version of the bulk helper run in multiple threads at once.
:arg client: instance of :class:`~elasticsearch.Elasticsearch` to use :arg client: instance of :class:`~opensearch.OpenSearch` to use
:arg actions: iterator containing the actions :arg actions: iterator containing the actions
:arg thread_count: size of the threadpool to use for the bulk requests :arg thread_count: size of the threadpool to use for the bulk requests
:arg chunk_size: number of docs in one chunk sent to es (default: 500) :arg chunk_size: number of docs in one chunk sent to es (default: 500)
@@ -515,7 +515,7 @@ def scan(
): ):
""" """
Simple abstraction on top of the Simple abstraction on top of the
:meth:`~elasticsearch.Elasticsearch.scroll` api - a simple iterator that :meth:`~opensearch.OpenSearch.scroll` api - a simple iterator that
yields all hits as returned by underlining scroll requests. yields all hits as returned by underlining scroll requests.
By default scan does not return results in any pre-determined order. To By default scan does not return results in any pre-determined order. To
@@ -524,8 +524,8 @@ def scan(
may be an expensive operation and will negate the performance benefits of may be an expensive operation and will negate the performance benefits of
using ``scan``. using ``scan``.
:arg client: instance of :class:`~elasticsearch.Elasticsearch` to use :arg client: instance of :class:`~opensearch.OpenSearch` to use
:arg query: body for the :meth:`~elasticsearch.Elasticsearch.search` api :arg query: body for the :meth:`~opensearch.OpenSearch.search` api
:arg scroll: Specify how long a consistent view of the index should be :arg scroll: Specify how long a consistent view of the index should be
maintained for scrolled search maintained for scrolled search
:arg raise_on_error: raises an exception (``ScanError``) if an error is :arg raise_on_error: raises an exception (``ScanError``) if an error is
@@ -540,10 +540,10 @@ def scan(
scroll API at the end of the method on completion or error, defaults scroll API at the end of the method on completion or error, defaults
to true. to true.
:arg scroll_kwargs: additional kwargs to be passed to :arg scroll_kwargs: additional kwargs to be passed to
:meth:`~elasticsearch.Elasticsearch.scroll` :meth:`~opensearch.OpenSearch.scroll`
Any additional keyword arguments will be passed to the initial Any additional keyword arguments will be passed to the initial
:meth:`~elasticsearch.Elasticsearch.search` call:: :meth:`~opensearch.OpenSearch.search` call::
scan(es, scan(es,
query={"query": {"match": {"title": "python"}}}, query={"query": {"match": {"title": "python"}}},
@@ -640,8 +640,8 @@ def reindex(
to another, potentially (if `target_client` is specified) on a different cluster. to another, potentially (if `target_client` is specified) on a different cluster.
If you don't specify the query you will reindex all the documents. If you don't specify the query you will reindex all the documents.
Since ``2.3`` a :meth:`~elasticsearch.Elasticsearch.reindex` api is Since ``2.3`` a :meth:`~opensearch.OpenSearch.reindex` api is
available as part of elasticsearch itself. It is recommended to use the api available as part of opensearch itself. It is recommended to use the api
instead of this helper wherever possible. The helper is here mostly for instead of this helper wherever possible. The helper is here mostly for
backwards compatibility and for situations where more flexibility is backwards compatibility and for situations where more flexibility is
needed. needed.
@@ -650,20 +650,20 @@ def reindex(
This helper doesn't transfer mappings, just the data. This helper doesn't transfer mappings, just the data.
:arg client: instance of :class:`~elasticsearch.Elasticsearch` to use (for :arg client: instance of :class:`~opensearch.OpenSearch` to use (for
read if `target_client` is specified as well) read if `target_client` is specified as well)
:arg source_index: index (or list of indices) to read documents from :arg source_index: index (or list of indices) to read documents from
:arg target_index: name of the index in the target cluster to populate :arg target_index: name of the index in the target cluster to populate
:arg query: body for the :meth:`~elasticsearch.Elasticsearch.search` api :arg query: body for the :meth:`~opensearch.OpenSearch.search` api
:arg target_client: optional, is specified will be used for writing (thus :arg target_client: optional, is specified will be used for writing (thus
enabling reindex between clusters) enabling reindex between clusters)
:arg chunk_size: number of docs in one chunk sent to es (default: 500) :arg chunk_size: number of docs in one chunk sent to es (default: 500)
:arg scroll: Specify how long a consistent view of the index should be :arg scroll: Specify how long a consistent view of the index should be
maintained for scrolled search maintained for scrolled search
:arg scan_kwargs: additional kwargs to be passed to :arg scan_kwargs: additional kwargs to be passed to
:func:`~elasticsearch.helpers.scan` :func:`~opensearch.helpers.scan`
:arg bulk_kwargs: additional kwargs to be passed to :arg bulk_kwargs: additional kwargs to be passed to
:func:`~elasticsearch.helpers.bulk` :func:`~opensearch.helpers.bulk`
""" """
target_client = client if target_client is None else target_client target_client = client if target_client is None else target_client
docs = scan(client, query=query, index=source_index, scroll=scroll, **scan_kwargs) docs = scan(client, query=query, index=source_index, scroll=scroll, **scan_kwargs)
@@ -40,7 +40,7 @@ from typing import (
Union, Union,
) )
from ..client import Elasticsearch from ..client import OpenSearch
from ..serializer import Serializer from ..serializer import Serializer
logger: logging.Logger logger: logging.Logger
@@ -50,7 +50,7 @@ def _chunk_actions(
actions: Any, chunk_size: int, max_chunk_bytes: int, serializer: Serializer actions: Any, chunk_size: int, max_chunk_bytes: int, serializer: Serializer
) -> Generator[Any, None, None]: ... ) -> Generator[Any, None, None]: ...
def _process_bulk_chunk( def _process_bulk_chunk(
client: Elasticsearch, client: OpenSearch,
bulk_actions: Any, bulk_actions: Any,
bulk_data: Any, bulk_data: Any,
raise_on_exception: bool = ..., raise_on_exception: bool = ...,
@@ -59,7 +59,7 @@ def _process_bulk_chunk(
**kwargs: Any **kwargs: Any
) -> Generator[Tuple[bool, Any], None, None]: ... ) -> Generator[Tuple[bool, Any], None, None]: ...
def streaming_bulk( def streaming_bulk(
client: Elasticsearch, client: OpenSearch,
actions: Union[Iterable[Any], AsyncIterable[Any]], actions: Union[Iterable[Any], AsyncIterable[Any]],
chunk_size: int = ..., chunk_size: int = ...,
max_chunk_bytes: int = ..., max_chunk_bytes: int = ...,
@@ -75,7 +75,7 @@ def streaming_bulk(
**kwargs: Any **kwargs: Any
) -> Generator[Tuple[bool, Any], None, None]: ... ) -> Generator[Tuple[bool, Any], None, None]: ...
def bulk( def bulk(
client: Elasticsearch, client: OpenSearch,
actions: Iterable[Any], actions: Iterable[Any],
stats_only: bool = ..., stats_only: bool = ...,
ignore_status: Optional[Union[int, Collection[int]]] = ..., ignore_status: Optional[Union[int, Collection[int]]] = ...,
@@ -83,7 +83,7 @@ def bulk(
**kwargs: Any **kwargs: Any
) -> Tuple[int, Union[int, List[Any]]]: ... ) -> Tuple[int, Union[int, List[Any]]]: ...
def parallel_bulk( def parallel_bulk(
client: Elasticsearch, client: OpenSearch,
actions: Iterable[Any], actions: Iterable[Any],
thread_count: int = ..., thread_count: int = ...,
chunk_size: int = ..., chunk_size: int = ...,
@@ -95,7 +95,7 @@ def parallel_bulk(
**kwargs: Any **kwargs: Any
) -> Generator[Tuple[bool, Any], None, None]: ... ) -> Generator[Tuple[bool, Any], None, None]: ...
def scan( def scan(
client: Elasticsearch, client: OpenSearch,
query: Optional[Any] = ..., query: Optional[Any] = ...,
scroll: str = ..., scroll: str = ...,
raise_on_error: bool = ..., raise_on_error: bool = ...,
@@ -107,11 +107,11 @@ def scan(
**kwargs: Any **kwargs: Any
) -> Generator[Any, None, None]: ... ) -> Generator[Any, None, None]: ...
def reindex( def reindex(
client: Elasticsearch, client: OpenSearch,
source_index: Union[str, Collection[str]], source_index: Union[str, Collection[str]],
target_index: str, target_index: str,
query: Any = ..., query: Any = ...,
target_client: Optional[Elasticsearch] = ..., target_client: Optional[OpenSearch] = ...,
chunk_size: int = ..., chunk_size: int = ...,
scroll: str = ..., scroll: str = ...,
scan_kwargs: Optional[Mapping[str, Any]] = ..., scan_kwargs: Optional[Mapping[str, Any]] = ...,
@@ -24,17 +24,17 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from ..exceptions import ElasticsearchException from ..exceptions import OpenSearchException
class BulkIndexError(ElasticsearchException): class BulkIndexError(OpenSearchException):
@property @property
def errors(self): def errors(self):
"""List of errors from execution of the last chunk.""" """List of errors from execution of the last chunk."""
return self.args[1] return self.args[1]
class ScanError(ElasticsearchException): class ScanError(OpenSearchException):
def __init__(self, scroll_id, *args, **kwargs): def __init__(self, scroll_id, *args, **kwargs):
super(ScanError, self).__init__(*args, **kwargs) # type: ignore super(ScanError, self).__init__(*args, **kwargs) # type: ignore
self.scroll_id = scroll_id self.scroll_id = scroll_id
@@ -26,12 +26,12 @@
from typing import Any, List from typing import Any, List
from ..exceptions import ElasticsearchException from ..exceptions import OpenSearchException
class BulkIndexError(ElasticsearchException): class BulkIndexError(OpenSearchException):
@property @property
def errors(self) -> List[Any]: ... def errors(self) -> List[Any]: ...
class ScanError(ElasticsearchException): class ScanError(OpenSearchException):
scroll_id: str scroll_id: str
def __init__(self, scroll_id: str, *args: Any, **kwargs: Any) -> None: ... def __init__(self, scroll_id: str, *args: Any, **kwargs: Any) -> None: ...
@@ -31,13 +31,13 @@ import time
from os.path import abspath, dirname, join from os.path import abspath, dirname, join
from unittest import SkipTest, TestCase from unittest import SkipTest, TestCase
from elasticsearch import Elasticsearch from opensearch import OpenSearch
from elasticsearch.exceptions import ConnectionError from opensearch.exceptions import ConnectionError
if "ELASTICSEARCH_URL" in os.environ: if "OPENSEARCH_URL" in os.environ:
ELASTICSEARCH_URL = os.environ["ELASTICSEARCH_URL"] OPENSEARCH_URL = os.environ["OPENSEARCH_URL"]
else: else:
ELASTICSEARCH_URL = "https://elastic:changeme@localhost:9200" OPENSEARCH_URL = "https://elastic:changeme@localhost:9200"
CA_CERTS = join(dirname(dirname(dirname(abspath(__file__)))), ".ci/certs/ca.pem") CA_CERTS = join(dirname(dirname(dirname(abspath(__file__)))), ".ci/certs/ca.pem")
@@ -47,14 +47,14 @@ def get_test_client(nowait=False, **kwargs):
kw = {"timeout": 30, "ca_certs": CA_CERTS} kw = {"timeout": 30, "ca_certs": CA_CERTS}
if "PYTHON_CONNECTION_CLASS" in os.environ: if "PYTHON_CONNECTION_CLASS" in os.environ:
from elasticsearch import connection from opensearch import connection
kw["connection_class"] = getattr( kw["connection_class"] = getattr(
connection, os.environ["PYTHON_CONNECTION_CLASS"] connection, os.environ["PYTHON_CONNECTION_CLASS"]
) )
kw.update(kwargs) kw.update(kwargs)
client = Elasticsearch(ELASTICSEARCH_URL, **kw) client = OpenSearch(OPENSEARCH_URL, **kw)
# wait for yellow status # wait for yellow status
for _ in range(1 if nowait else 100): for _ in range(1 if nowait else 100):
@@ -65,10 +65,10 @@ def get_test_client(nowait=False, **kwargs):
time.sleep(0.1) time.sleep(0.1)
else: else:
# timeout # timeout
raise SkipTest("Elasticsearch failed to start.") raise SkipTest("OpenSearch failed to start.")
class ElasticsearchTestCase(TestCase): class OpenSearchTestCase(TestCase):
@staticmethod @staticmethod
def _get_client(): def _get_client():
return get_test_client() return get_test_client()
@@ -27,17 +27,17 @@
from typing import Any, Tuple from typing import Any, Tuple
from unittest import TestCase from unittest import TestCase
from ..client import Elasticsearch from ..client import OpenSearch
ELASTICSEARCH_URL: str OPENSEARCH_URL: str
CA_CERTS: str CA_CERTS: str
def get_test_client(nowait: bool = ..., **kwargs: Any) -> Elasticsearch: ... def get_test_client(nowait: bool = ..., **kwargs: Any) -> OpenSearch: ...
def _get_version(version_string: str) -> Tuple[int, ...]: ... def _get_version(version_string: str) -> Tuple[int, ...]: ...
class ElasticsearchTestCase(TestCase): class OpenSearchTestCase(TestCase):
@staticmethod @staticmethod
def _get_client() -> Elasticsearch: ... def _get_client() -> OpenSearch: ...
@classmethod @classmethod
def setup_class(cls) -> None: ... def setup_class(cls) -> None: ...
def teardown_method(self, _: Any) -> None: ... def teardown_method(self, _: Any) -> None: ...
@@ -165,9 +165,9 @@ class Deserializer(object):
else: else:
# split out 'charset' and 'compatible-width' options # split out 'charset' and 'compatible-width' options
mimetype = mimetype.partition(";")[0].strip() mimetype = mimetype.partition(";")[0].strip()
# Treat 'application/vnd.elasticsearch+json' # Treat 'application/vnd.opensearch+json'
# as application/json for compatibility. # as application/json for compatibility.
if mimetype == "application/vnd.elasticsearch+json": if mimetype == "application/vnd.opensearch+json":
mimetype = "application/json" mimetype = "application/json"
try: try:
deserializer = self.serializers[mimetype] deserializer = self.serializers[mimetype]
@@ -48,7 +48,7 @@ def get_host_info(node_info, host):
`None` is returned this node will be skipped. `None` is returned this node will be skipped.
Useful for filtering nodes (by proximity for example) or if additional Useful for filtering nodes (by proximity for example) or if additional
information needs to be provided for the :class:`~elasticsearch.Connection` information needs to be provided for the :class:`~opensearch.Connection`
class. By default master only nodes are filtered out since they shouldn't class. By default master only nodes are filtered out since they shouldn't
typically be used for API operations. typically be used for API operations.
@@ -94,8 +94,8 @@ class Transport(object):
""" """
:arg hosts: list of dictionaries, each containing keyword arguments to :arg hosts: list of dictionaries, each containing keyword arguments to
create a `connection_class` instance create a `connection_class` instance
:arg connection_class: subclass of :class:`~elasticsearch.Connection` to use :arg connection_class: subclass of :class:`~opensearch.Connection` to use
:arg connection_pool_class: subclass of :class:`~elasticsearch.ConnectionPool` to use :arg connection_pool_class: subclass of :class:`~opensearch.ConnectionPool` to use
:arg host_info_callback: callback responsible for taking the node information from :arg host_info_callback: callback responsible for taking the node information from
`/_cluster/nodes`, along with already extracted information, and `/_cluster/nodes`, along with already extracted information, and
producing a list of arguments (same as `hosts` parameter) producing a list of arguments (same as `hosts` parameter)
@@ -209,7 +209,7 @@ class Transport(object):
def add_connection(self, host): def add_connection(self, host):
""" """
Create a new :class:`~elasticsearch.Connection` instance and add it to the pool. Create a new :class:`~opensearch.Connection` instance and add it to the pool.
:arg host: kwargs that will be used to create the instance :arg host: kwargs that will be used to create the instance
""" """
@@ -220,7 +220,7 @@ class Transport(object):
""" """
Instantiate all the connections and create new connection pool to hold them. Instantiate all the connections and create new connection pool to hold them.
Tries to identify unchanged hosts and re-use existing Tries to identify unchanged hosts and re-use existing
:class:`~elasticsearch.Connection` instances. :class:`~opensearch.Connection` instances.
:arg hosts: same as `__init__` :arg hosts: same as `__init__`
""" """
@@ -252,8 +252,8 @@ class Transport(object):
def get_connection(self): def get_connection(self):
""" """
Retrieve a :class:`~elasticsearch.Connection` instance from the Retrieve a :class:`~opensearch.Connection` instance from the
:class:`~elasticsearch.ConnectionPool` instance. :class:`~opensearch.ConnectionPool` instance.
""" """
if self.sniffer_timeout: if self.sniffer_timeout:
if time.time() >= self.last_sniff + self.sniffer_timeout: if time.time() >= self.last_sniff + self.sniffer_timeout:
@@ -357,7 +357,7 @@ class Transport(object):
Mark a connection as dead (failed) in the connection pool. If sniffing Mark a connection as dead (failed) in the connection pool. If sniffing
on failure is enabled this will initiate the sniffing process. on failure is enabled this will initiate the sniffing process.
:arg connection: instance of :class:`~elasticsearch.Connection` that failed :arg connection: instance of :class:`~opensearch.Connection` that failed
""" """
# mark as dead even when sniffing to avoid hitting this host during the sniff process # mark as dead even when sniffing to avoid hitting this host during the sniff process
self.connection_pool.mark_dead(connection) self.connection_pool.mark_dead(connection)
@@ -379,9 +379,9 @@ class Transport(object):
:arg method: HTTP method to use :arg method: HTTP method to use
:arg url: absolute url (without host) to target :arg url: absolute url (without host) to target
:arg headers: dictionary of headers, will be handed over to the :arg headers: dictionary of headers, will be handed over to the
underlying :class:`~elasticsearch.Connection` class underlying :class:`~opensearch.Connection` class
:arg params: dictionary of query parameters, will be handed over to the :arg params: dictionary of query parameters, will be handed over to the
underlying :class:`~elasticsearch.Connection` class for serialization underlying :class:`~opensearch.Connection` class for serialization
:arg body: body of the request, will be serialized using serializer and :arg body: body of the request, will be serialized using serializer and
passed to the connection passed to the connection
""" """

Some files were not shown because too many files have changed in this diff Show More