Check required parameters for empty values.

Fixes #138, thanks robhudson!
This commit is contained in:
Honza Král
2014-12-02 00:13:01 +01:00
parent 9b37be87f1
commit 5173d5b741
6 changed files with 136 additions and 4 deletions
+1
View File
@@ -10,6 +10,7 @@ Changelog
`retry_on_timeout=True`)
* Implemented url parsing according to RFC-1738
* added support for proper SSL certificate handling
* Required parameters are now checked for non-empty values
1.2.0 (2014-08-03)
------------------
+63 -1
View File
@@ -10,7 +10,7 @@ from .cluster import ClusterClient
from .cat import CatClient
from .nodes import NodesClient
from .snapshot import SnapshotClient
from .utils import query_params, _make_path
from .utils import query_params, _make_path, SKIP_IN_PATH
logger = logging.getLogger('elasticsearch')
@@ -249,6 +249,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (index, doc_type, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT' if id else 'POST',
_make_path(index, doc_type, id), params=params, body=body)
return data
@@ -272,6 +275,9 @@ class Elasticsearch(object):
performing the operation
:arg routing: Specific routing value
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
try:
self.transport.perform_request('HEAD', _make_path(index, doc_type, id), params=params)
except NotFoundError:
@@ -308,6 +314,9 @@ class Elasticsearch(object):
:arg version_type: Explicit version number for concurrency control
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, id),
params=params)
return data
@@ -339,6 +348,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Explicit version number for concurrency control
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, id, '_source'),
params=params)
return data
@@ -369,6 +381,8 @@ class Elasticsearch(object):
performing the operation
:arg routing: Specific routing value
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, '_mget'),
params=params, body=body)
return data
@@ -401,6 +415,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Explicit version number for concurrency control
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('POST', _make_path(index, doc_type, id, '_update'),
params=params, body=body)
return data
@@ -578,6 +595,9 @@ class Elasticsearch(object):
:arg source: The URL-encoded query definition (instead of using the
request body)
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, id, '_explain'),
params=params, body=body)
return data
@@ -631,6 +651,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE', _make_path(index, doc_type, id), params=params)
return data
@@ -682,6 +705,8 @@ class Elasticsearch(object):
:arg replication: Explicitly set the replication type (default: sync)
:arg timeout: Explicit operation timeout
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('POST', _make_path(index, doc_type, '_bulk'),
params=params, body=self._bulk_body(body))
return data
@@ -699,6 +724,8 @@ class Elasticsearch(object):
:arg doc_type: A comma-separated list of document types to use as default
:arg search_type: Search operation type
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, '_msearch'),
params=params, body=self._bulk_body(body))
return data
@@ -736,6 +763,8 @@ class Elasticsearch(object):
request body)
:arg timeout: Explicit operation timeout
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('DELETE', _make_path(index, doc_type, '_query'),
params=params, body=body)
return data
@@ -763,6 +792,8 @@ class Elasticsearch(object):
:arg routing: Specific routing value
:arg source: The URL-encoded request definition (instead of using request body)
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('POST', _make_path(index, '_suggest'),
params=params, body=body)
return data
@@ -803,6 +834,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (index, doc_type):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index,
doc_type, id, '_percolate'), params=params, body=body)
return data
@@ -829,6 +863,8 @@ class Elasticsearch(object):
:arg ignore_unavailable: Whether specified concrete indices should be
ignored when unavailable (missing or closed)
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('GET', _make_path(index,
doc_type, '_mpercolate'), params=params, body=self._bulk_body(body))
return data
@@ -868,6 +904,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (index, doc_type):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index,
doc_type, id, '_percolate', 'count'), params=params, body=body)
return data
@@ -915,6 +954,9 @@ class Elasticsearch(object):
against (default: the same type as the document)
:arg stop_words: A list of stop words to be ignored
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index, doc_type, id, '_mlt'),
params=params, body=body)
return data
@@ -953,6 +995,9 @@ class Elasticsearch(object):
:arg term_statistics: Specifies if total term frequency and document
frequency should be returned., default False
"""
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index,
doc_type, id, '_termvectors'), params=params, body=body)
return data
@@ -960,6 +1005,9 @@ class Elasticsearch(object):
@query_params('field_statistics', 'fields', 'offsets', 'parent', 'payloads',
'positions', 'preference', 'realtime', 'routing', 'term_statistics')
def termvector(self, index, doc_type, id, body=None, params=None):
for param in (index, doc_type, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path(index,
doc_type, id, '_termvector'), params=params, body=body)
return data
@@ -1069,6 +1117,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (lang, id, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path('_scripts',
lang, id), params=params, body=body)
return data
@@ -1084,6 +1135,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (lang, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path('_scripts',
lang, id), params=params)
return data
@@ -1099,6 +1153,9 @@ class Elasticsearch(object):
:arg version: Explicit version number for concurrency control
:arg version_type: Specific version type
"""
for param in (lang, id):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE',
_make_path('_scripts', lang, id), params=params)
return data
@@ -1112,6 +1169,9 @@ class Elasticsearch(object):
:arg id: Template ID
:arg body: The document
"""
for param in (id, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path('_search',
'template', id), params=params, body=body)
return data
@@ -1125,6 +1185,8 @@ class Elasticsearch(object):
:arg id: Template ID
:arg body: The document
"""
if id in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'id'.")
_, data = self.transport.perform_request('GET', _make_path('_search',
'template', id), params=params, body=body)
return data
+46 -1
View File
@@ -1,4 +1,4 @@
from .utils import NamespacedClient, query_params, _make_path
from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
from ..exceptions import NotFoundError
class IndicesClient(NamespacedClient):
@@ -92,6 +92,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit operation timeout
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('PUT', _make_path(index),
params=params, body=body)
return data
@@ -112,6 +114,8 @@ class IndicesClient(NamespacedClient):
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('GET', _make_path(index,
feature), params=params)
return data
@@ -134,6 +138,8 @@ class IndicesClient(NamespacedClient):
:arg ignore_unavailable: Whether specified concrete indices should be ignored
when unavailable (missing or closed)
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('POST', _make_path(index, '_open'),
params=params)
return data
@@ -158,6 +164,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit operation timeout
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('POST', _make_path(index, '_close'),
params=params)
return data
@@ -173,6 +181,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit operation timeout
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
_, data = self.transport.perform_request('DELETE', _make_path(index),
params=params)
return data
@@ -195,6 +205,8 @@ class IndicesClient(NamespacedClient):
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
if index in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'index'.")
try:
self.transport.perform_request('HEAD', _make_path(index), params=params)
except NotFoundError:
@@ -223,6 +235,9 @@ class IndicesClient(NamespacedClient):
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
for param in (index, doc_type):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
try:
self.transport.perform_request('HEAD', _make_path(index, doc_type), params=params)
except NotFoundError:
@@ -253,6 +268,9 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit operation timeout
"""
for param in (doc_type, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path(index, '_mapping', doc_type),
params=params, body=body)
return data
@@ -303,6 +321,8 @@ class IndicesClient(NamespacedClient):
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
if field in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'field'.")
_, data = self.transport.perform_request('GET', _make_path(index, '_mapping', doc_type, 'field', field),
params=params)
return data
@@ -320,6 +340,9 @@ class IndicesClient(NamespacedClient):
specified indices.
:arg master_timeout: Specify timeout for connection to master
"""
for param in (index, doc_type):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE', _make_path(index, '_mapping', doc_type),
params=params)
return data
@@ -338,6 +361,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit timestamp for the document
"""
if name in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'name'.")
_, data = self.transport.perform_request('PUT', _make_path(index, '_alias', name),
params=params, body=body)
return data
@@ -420,6 +445,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Request timeout
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('POST', '/_aliases',
params=params, body=body)
return data
@@ -437,6 +464,9 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit timestamp for the document
"""
for param in (index, name):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE', _make_path(index, '_alias', name),
params=params)
return data
@@ -458,6 +488,9 @@ class IndicesClient(NamespacedClient):
:arg timeout: Explicit operation timeout
:arg flat_settings: Return settings in flat format (default: false)
"""
for param in (name, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path('_template', name),
params=params, body=body)
return data
@@ -472,6 +505,8 @@ class IndicesClient(NamespacedClient):
:arg local: Return local information, do not retrieve the state from
master node (default: false)
"""
if name in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'name'.")
try:
self.transport.perform_request('HEAD', _make_path('_template', name),
params=params)
@@ -504,6 +539,8 @@ class IndicesClient(NamespacedClient):
:arg master_timeout: Specify timeout for connection to master
:arg timeout: Explicit operation timeout
"""
if name in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'name'.")
_, data = self.transport.perform_request('DELETE', _make_path('_template', name),
params=params)
return data
@@ -552,6 +589,8 @@ class IndicesClient(NamespacedClient):
ignored when unavailable (missing or closed)
:arg master_timeout: Specify timeout for connection to master
"""
if body in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'body'.")
_, data = self.transport.perform_request('PUT', _make_path(index, '_settings'),
params=params, body=body)
return data
@@ -583,6 +622,9 @@ class IndicesClient(NamespacedClient):
to warm
:arg master_timeout: Specify timeout for connection to master
"""
for param in (name, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
if doc_type and not index:
index = '_all'
_, data = self.transport.perform_request('PUT', _make_path(index, doc_type, '_warmer', name),
@@ -627,6 +669,9 @@ class IndicesClient(NamespacedClient):
wildcards); use `_all` to delete all warmers in the specified indices.
:arg master_timeout: Specify timeout for connection to master
"""
for param in (index, name):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE', _make_path(index, '_warmer', name),
params=params)
return data
+20 -1
View File
@@ -1,4 +1,4 @@
from .utils import NamespacedClient, query_params, _make_path
from .utils import NamespacedClient, query_params, _make_path, SKIP_IN_PATH
class SnapshotClient(NamespacedClient):
@query_params('master_timeout', 'wait_for_completion')
@@ -15,6 +15,9 @@ class SnapshotClient(NamespacedClient):
:arg wait_for_completion: Should this request wait until the operation
has completed before returning, default False
"""
for param in (repository, snapshot):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path('_snapshot',
repository, snapshot), params=params, body=body)
return data
@@ -30,6 +33,9 @@ class SnapshotClient(NamespacedClient):
:arg master_timeout: Explicit operation timeout for connection to master
node
"""
for param in (repository, snapshot):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('DELETE',
_make_path('_snapshot', repository, snapshot), params=params)
return data
@@ -45,6 +51,9 @@ class SnapshotClient(NamespacedClient):
:arg master_timeout: Explicit operation timeout for connection to master
node
"""
for param in (repository, snapshot):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('GET', _make_path('_snapshot',
repository, snapshot), params=params)
return data
@@ -60,6 +69,8 @@ class SnapshotClient(NamespacedClient):
node
:arg timeout: Explicit operation timeout
"""
if repository in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'repository'.")
_, data = self.transport.perform_request('DELETE',
_make_path('_snapshot', repository), params=params)
return data
@@ -92,6 +103,9 @@ class SnapshotClient(NamespacedClient):
node
:arg timeout: Explicit operation timeout
"""
for param in (repository, body):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('PUT', _make_path('_snapshot',
repository), params=params, body=body)
return data
@@ -110,6 +124,9 @@ class SnapshotClient(NamespacedClient):
:arg wait_for_completion: Should this request wait until the operation
has completed before returning, default False
"""
for param in (repository, snapshot):
if param in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument.")
_, data = self.transport.perform_request('POST', _make_path('_snapshot',
repository, snapshot, '_restore'), params=params, body=body)
return data
@@ -143,6 +160,8 @@ class SnapshotClient(NamespacedClient):
node
:arg timeout: Explicit operation timeout
"""
if repository in SKIP_IN_PATH:
raise ValueError("Empty value passed for a required argument 'repository'.")
_, data = self.transport.perform_request('POST', _make_path('_snapshot',
repository, '_verify'), params=params)
return data
+1 -1
View File
@@ -5,7 +5,7 @@ from functools import wraps
from ..compat import string_types, quote_plus
# parts of URL to be omitted
SKIP_IN_PATH = (None, b'', [], ())
SKIP_IN_PATH = (None, '', b'', [], ())
def _escape(value):
"""
@@ -12,3 +12,8 @@ class TestIndices(ElasticsearchTestCase):
def test_exists_index(self):
self.client.indices.exists('second.index,third/index')
self.assert_url_called('HEAD', '/second.index,third%2Findex')
def test_passing_empty_value_for_required_param_raises_exception(self):
self.assertRaises(ValueError, self.client.indices.exists, index=None)
self.assertRaises(ValueError, self.client.indices.exists, index=[])
self.assertRaises(ValueError, self.client.indices.exists, index='')