Files
opensearch-pyd/elasticsearch/client.py
T

105 lines
3.2 KiB
Python

from functools import wraps
try:
# PY2
from urllib import quote_plus
except ImportError:
# PY3
from urllib.parse import quote_plus
from .transport import Transport
from .exceptions import NotFoundError
def _normalize_hosts(hosts):
"""
Helper function to transform hosts argument to
:class:`~elasticsearch.Elasticsearch` to a list of dicts.
"""
# if hosts are empty, just defer to defaults down the line
if hosts is None:
return [{}]
out = []
# normalize hosts to dicts
for i, host in enumerate(hosts):
if isinstance(host, (type(''), type(u''))):
h = {"host": host}
if ':' in host:
# TODO: detect auth urls
host, port = host.rsplit(':', 1)
if port.isdigit():
port = int(port)
h = {"host": host, "port": port}
out.append(h)
else:
out.append(host)
return out
def _normalize_list(list_or_string):
"""
for index and type arguments in url, identify if it's a string or a
sequence and produce a working representation (comma separated string).
"""
if isinstance(list_or_string, (type(''), type(u''))):
return quote_plus(list_or_string)
return quote_plus(','.join(list_or_string))
# parameters that apply to all methods
GLOBAL_PARAMS = ('pretty', )
def query_params(*es_query_params):
"""
Decorator that pops all accepted parameters from method's kwargs and puts
them in the params argument.
"""
def _wrapper(func):
@wraps(func)
def _wrapped(*args, **kwargs):
params = kwargs.pop('params', {})
for p in es_query_params + GLOBAL_PARAMS:
if p in kwargs:
params[p] = kwargs.pop(p)
return func(*args, params=params, **kwargs)
return _wrapped
return _wrapper
class NamespacedClient(object):
def __init__(self, client):
self.client = client
@property
def transport(self):
return self.client.transport
class ClusterClient(NamespacedClient):
pass
class InidicesClient(NamespacedClient):
pass
class Elasticsearch(object):
"""
Elasticsearch low-level client. Provides a straightforward mapping from
Python to ES REST endpoints.
"""
def __init__(self, hosts=None, **kwargs):
"""
:arg hosts: list of nodes we should connect to. Node should be a
dictionary ({"host": "localhost", "port": 9200}), the entire dictionary
will be passed to the :class:`~elasticsearch.Connection` class as
kwargs, or a string in the format ot ``host[:port]`` which will be
translated to a dictionary automatically. If no value is given the
:class:`~elasticsearch.Connection` class defaults will be used.
:arg kwargs: any additional arguments will be passed on to the
:class:`~elasticsearch.Transport` class and, subsequently, to the
:class:`~elasticsearch.Connection` instances.
"""
self.transport = Transport(_normalize_hosts(hosts), **kwargs)
# namespaced clients for compatibility with API names
self.indices = InidicesClient(self)
self.cluster = ClusterClient(self)