From 4ccb8c1cd804d03b1647706b46c7eb9bb0369f40 Mon Sep 17 00:00:00 2001 From: cloudant-sdks-automation <71659186+cloudant-sdks-automation@users.noreply.github.com> Date: Thu, 29 Oct 2026 14:48:05 +0000 Subject: [PATCH] feat(generated): add WireMock stub for POST /{db}/_index_info Generated SDK source code using: - Generator version 3.117.2 - Specification version 1.0.0-dev0.1.41 - Automation (cloudant-sdks) version bf0dbc2 --- ibmcloudant/cloudant_v1.py | 6447 ++++++++++++++------------ stubs/gen-its-mappings.json | 97 + test/integration/test_cloudant_v1.py | 188 +- test/unit/test_cloudant_v1.py | 2770 ++++++----- 4 files changed, 5432 insertions(+), 4070 deletions(-) diff --git a/ibmcloudant/cloudant_v1.py b/ibmcloudant/cloudant_v1.py index aeb6ecf8..f6719a11 100644 --- a/ibmcloudant/cloudant_v1.py +++ b/ibmcloudant/cloudant_v1.py @@ -3187,561 +3187,488 @@ def post_design_docs_queries( return response ######################### - # Views + # Design Documents ######################### - def post_view( + def head_up_information( self, - db: str, - ddoc: str, - view: str, - *, - att_encoding_info: Optional[bool] = None, - attachments: Optional[bool] = None, - conflicts: Optional[bool] = None, - descending: Optional[bool] = None, - include_docs: Optional[bool] = None, - inclusive_end: Optional[bool] = None, - limit: Optional[int] = None, - skip: Optional[int] = None, - update_seq: Optional[bool] = None, - end_key: Optional[object] = None, - end_key_doc_id: Optional[str] = None, - group: Optional[bool] = None, - group_level: Optional[int] = None, - key: Optional[object] = None, - keys: Optional[List[object]] = None, - reduce: Optional[bool] = None, - stable: Optional[bool] = None, - start_key: Optional[object] = None, - start_key_doc_id: Optional[str] = None, - update: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a MapReduce view. + Retrieve HTTP headers about whether the server is up. - This operation queries the specified MapReduce view of the specified design - document. By default, the map and reduce functions of the view are run to update - the view before returning the response. The advantage of using the HTTP `POST` - method is that the query is submitted as a JSON object in the request body. This - avoids the limitations of passing query options as URL query parameters of a `GET` - request. + Retrieves the HTTP headers about whether the server is up. + + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse + """ + + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='head_up_information', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + + url = '/_up' + request = self.prepare_request( + method='HEAD', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def get_active_tasks( + self, + **kwargs, + ) -> DetailedResponse: + """ + Retrieve list of running tasks. + + Lists running tasks, including the task type, name, status, and process ID. The + result includes a JSON array of the currently running tasks, with each task + described as a single object. Depending on the operation type, the set of response + object fields might be different. + + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `List[ActiveTask]` result + """ + + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='get_active_tasks', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + url = '/_active_tasks' + request = self.prepare_request( + method='GET', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def get_activity_tracker_events( + self, + **kwargs, + ) -> DetailedResponse: + """ + Retrieve activity tracking events information. + + Check event types sent to IBM Cloud Activity Tracker Event Routing for the IBM + Cloudant instance. + + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `ActivityTrackerEvents` object + """ + + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='get_activity_tracker_events', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + url = '/_api/v2/user/activity_tracker/events' + request = self.prepare_request( + method='GET', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def post_activity_tracker_events( + self, + types: List[str], + **kwargs, + ) -> DetailedResponse: + """ + Modify activity tracking events configuration. + + Configure event types sent to IBM Cloud Activity Tracker Event Routing for the IBM + Cloudant instance. + + :param List[str] types: An array of event types sent to IBM Cloud Activity + Tracker Event Routing for the IBM Cloudant instance. "management" is a + required element of this array. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `Ok` object + """ + + if types is None: + raise ValueError('types must be provided') + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='post_activity_tracker_events', + ) + headers.update(sdk_headers) + + data = { + 'types': types, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + url = '/_api/v2/user/activity_tracker/events' + request = self.prepare_request( + method='POST', + url=url, + headers=headers, + data=data, + ) + + response = self.send(request, **kwargs) + return response + + def get_capacity_databases_information( + self, + **kwargs, + ) -> DetailedResponse: + """ + Retrieve maximum allowed database count. + + Retrieves the maximum number of databases currently allowed in the instance. + + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `CapacityDatabasesInformation` object + """ + + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='get_capacity_databases_information', + ) + headers.update(sdk_headers) + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + url = '/_api/v2/user/capacity/databases' + request = self.prepare_request( + method='GET', + url=url, + headers=headers, + ) + + response = self.send(request, **kwargs) + return response + + def get_current_databases_information( + self, + **kwargs, + ) -> DetailedResponse: + """ + Retrieve current database count. + + Retrieves the current number of databases that exist in the instance. - :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. - :param bool att_encoding_info: (optional) Parameter to specify whether to - include the encoding information for compressed attachments. This only - applies when requesting documents in the response. - :param bool attachments: (optional) Parameter to specify whether to include - attachment content in included document content or only the attachment - metadata. This only applies when requesting documents in the response. - :param bool conflicts: (optional) Parameter to specify whether to include a - list of conflicted revisions in each returned document. This only applies - when requesting documents in the response. - :param bool descending: (optional) Parameter to specify whether to return - the documents in descending by key order. - :param bool include_docs: (optional) Parameter to specify whether to - include the full content of the documents in the response. - :param bool inclusive_end: (optional) Parameter to specify whether to - include the specified end key in the result. - :param int limit: (optional) Parameter to specify the number of returned - documents to limit the result to. - :param int skip: (optional) Parameter to specify the number of records - before starting to return the results. - :param bool update_seq: (optional) Parameter to specify whether to include - in the response an update_seq value indicating the sequence id of the - database the view reflects. - :param object end_key: (optional) Schema for any JSON type. - :param str end_key_doc_id: (optional) Stop returning rows at the specified - document ID. No effect if using `group` or not providing end key. - :param bool group: (optional) Parameter to specify whether to group reduced - results by key. Valid only if a reduce function defined in the view. If the - view emits key in JSON array format, then it is possible to reduce groups - further based on the number of array elements with the `group_level` - parameter. - :param int group_level: (optional) Parameter to specify a group level to be - used. Only applicable if the view uses keys that are JSON arrays. Implies - group is `true`. Group level groups the reduced results by the specified - number of array elements. If unset, results are grouped by the entire array - key, returning a reduced value for each complete key. - :param object key: (optional) Parameter to specify to return only rows that - match the specified key. String representation of any JSON type that - matches the key type emitted by the view function. - :param List[object] keys: (optional) Parameter to specify returning only - rows that match any of the specified keys. A JSON array of keys that match - the key type emitted by the view function. - :param bool reduce: (optional) Parameter to specify whether to use the - reduce function in a map-reduce view. Default is true when a reduce - function is defined. - A default `reduce` view type can be disabled to behave like a - `map` by setting `reduce=false` explicitly. - Be aware that `include_docs=true` is only for `map` views. Reduced views do - not include document IDs in view rows. - :param bool stable: (optional) Query parameter to specify whether use the - same replica of the index on each request. The default value `false` - contacts all replicas and returns the result from the first, fastest, - responder. Setting it to `true` when used in conjunction with - `update=false` may improve consistency at the expense of increased latency - and decreased throughput if the selected replica is not the fastest of the - available replicas. - **Note:** In general setting `true` is discouraged and is strictly not - recommended when using `update=true`. - :param object start_key: (optional) Schema for any JSON type. - :param str start_key_doc_id: (optional) Start returning rows at the - specified document ID. No effect if using `group` or not providing start - key. - :param str update: (optional) Parameter to specify whether or not the view - in question should be updated prior to responding to the user. - * `true` - Return results after the view is updated. - * `false` - Return results without updating the view. - * `lazy` - Return the view results without waiting for an update, but - update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ViewResult` object + :rtype: DetailedResponse with `dict` result representing a `CurrentDatabasesInformation` object """ - if not db: - raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_view', + operation_id='get_current_databases_information', ) headers.update(sdk_headers) - data = { - 'att_encoding_info': att_encoding_info, - 'attachments': attachments, - 'conflicts': conflicts, - 'descending': descending, - 'include_docs': include_docs, - 'inclusive_end': inclusive_end, - 'limit': limit, - 'skip': skip, - 'update_seq': update_seq, - 'end_key': end_key, - 'end_key_doc_id': end_key_doc_id, - 'group': group, - 'group_level': group_level, - 'key': key, - 'keys': keys, - 'reduce': reduce, - 'stable': stable, - 'start_key': start_key, - 'start_key_doc_id': start_key_doc_id, - 'update': update, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, ddoc, view) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) + url = '/_api/v2/user/current/databases' request = self.prepare_request( - method='POST', + method='GET', url=url, headers=headers, - data=data, ) response = self.send(request, **kwargs) return response - def post_view_as_stream( + def get_current_throughput_information( self, - db: str, - ddoc: str, - view: str, - *, - att_encoding_info: Optional[bool] = None, - attachments: Optional[bool] = None, - conflicts: Optional[bool] = None, - descending: Optional[bool] = None, - include_docs: Optional[bool] = None, - inclusive_end: Optional[bool] = None, - limit: Optional[int] = None, - skip: Optional[int] = None, - update_seq: Optional[bool] = None, - end_key: Optional[object] = None, - end_key_doc_id: Optional[str] = None, - group: Optional[bool] = None, - group_level: Optional[int] = None, - key: Optional[object] = None, - keys: Optional[List[object]] = None, - reduce: Optional[bool] = None, - stable: Optional[bool] = None, - start_key: Optional[object] = None, - start_key_doc_id: Optional[str] = None, - update: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a MapReduce view as stream. + Retrieve the current provisioned throughput capacity consumption. - This operation queries the specified MapReduce view of the specified design - document. By default, the map and reduce functions of the view are run to update - the view before returning the response. The advantage of using the HTTP `POST` - method is that the query is submitted as a JSON object in the request body. This - avoids the limitations of passing query options as URL query parameters of a `GET` - request. + View the current consumption of provisioned throughput capacity for an IBM + Cloudant instance. The current consumption shows the quantities of reads, writes, + and global queries conducted against the instance for a given second. - :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. - :param bool att_encoding_info: (optional) Parameter to specify whether to - include the encoding information for compressed attachments. This only - applies when requesting documents in the response. - :param bool attachments: (optional) Parameter to specify whether to include - attachment content in included document content or only the attachment - metadata. This only applies when requesting documents in the response. - :param bool conflicts: (optional) Parameter to specify whether to include a - list of conflicted revisions in each returned document. This only applies - when requesting documents in the response. - :param bool descending: (optional) Parameter to specify whether to return - the documents in descending by key order. - :param bool include_docs: (optional) Parameter to specify whether to - include the full content of the documents in the response. - :param bool inclusive_end: (optional) Parameter to specify whether to - include the specified end key in the result. - :param int limit: (optional) Parameter to specify the number of returned - documents to limit the result to. - :param int skip: (optional) Parameter to specify the number of records - before starting to return the results. - :param bool update_seq: (optional) Parameter to specify whether to include - in the response an update_seq value indicating the sequence id of the - database the view reflects. - :param object end_key: (optional) Schema for any JSON type. - :param str end_key_doc_id: (optional) Stop returning rows at the specified - document ID. No effect if using `group` or not providing end key. - :param bool group: (optional) Parameter to specify whether to group reduced - results by key. Valid only if a reduce function defined in the view. If the - view emits key in JSON array format, then it is possible to reduce groups - further based on the number of array elements with the `group_level` - parameter. - :param int group_level: (optional) Parameter to specify a group level to be - used. Only applicable if the view uses keys that are JSON arrays. Implies - group is `true`. Group level groups the reduced results by the specified - number of array elements. If unset, results are grouped by the entire array - key, returning a reduced value for each complete key. - :param object key: (optional) Parameter to specify to return only rows that - match the specified key. String representation of any JSON type that - matches the key type emitted by the view function. - :param List[object] keys: (optional) Parameter to specify returning only - rows that match any of the specified keys. A JSON array of keys that match - the key type emitted by the view function. - :param bool reduce: (optional) Parameter to specify whether to use the - reduce function in a map-reduce view. Default is true when a reduce - function is defined. - A default `reduce` view type can be disabled to behave like a - `map` by setting `reduce=false` explicitly. - Be aware that `include_docs=true` is only for `map` views. Reduced views do - not include document IDs in view rows. - :param bool stable: (optional) Query parameter to specify whether use the - same replica of the index on each request. The default value `false` - contacts all replicas and returns the result from the first, fastest, - responder. Setting it to `true` when used in conjunction with - `update=false` may improve consistency at the expense of increased latency - and decreased throughput if the selected replica is not the fastest of the - available replicas. - **Note:** In general setting `true` is discouraged and is strictly not - recommended when using `update=true`. - :param object start_key: (optional) Schema for any JSON type. - :param str start_key_doc_id: (optional) Start returning rows at the - specified document ID. No effect if using `group` or not providing start - key. - :param str update: (optional) Parameter to specify whether or not the view - in question should be updated prior to responding to the user. - * `true` - Return results after the view is updated. - * `false` - Return results without updating the view. - * `lazy` - Return the view results without waiting for an update, but - update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `CurrentThroughputInformation` object """ - if not db: - raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_view_as_stream', + operation_id='get_current_throughput_information', ) headers.update(sdk_headers) - data = { - 'att_encoding_info': att_encoding_info, - 'attachments': attachments, - 'conflicts': conflicts, - 'descending': descending, - 'include_docs': include_docs, - 'inclusive_end': inclusive_end, - 'limit': limit, - 'skip': skip, - 'update_seq': update_seq, - 'end_key': end_key, - 'end_key_doc_id': end_key_doc_id, - 'group': group, - 'group_level': group_level, - 'key': key, - 'keys': keys, - 'reduce': reduce, - 'stable': stable, - 'start_key': start_key, - 'start_key_doc_id': start_key_doc_id, - 'update': update, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, ddoc, view) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) + url = '/_api/v2/user/current/throughput' request = self.prepare_request( - method='POST', + method='GET', url=url, headers=headers, - data=data, ) - response = self.send(request, stream=True, **kwargs) + response = self.send(request, **kwargs) return response - def post_view_queries( + def get_membership_information( self, - db: str, - ddoc: str, - view: str, - queries: List['ViewQuery'], **kwargs, ) -> DetailedResponse: """ - Multi-query a MapReduce view. - - This operation runs multiple specified view queries against the view function from - the specified design document. + Retrieve cluster membership information. - :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. - :param List[ViewQuery] queries: An array of query objects with fields for - the parameters of each individual view query to be executed. The field - names and their meaning are the same as the query parameters of a regular - view request. - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ViewQueriesResult` object - """ + Displays the nodes that are part of the cluster as `cluster_nodes`. The field, + `all_nodes`, displays all nodes this node knows about, including the ones that are + part of the cluster. This endpoint is useful when you set up a cluster. + + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `MembershipInformation` object + """ - if not db: - raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') - if queries is None: - raise ValueError('queries must be provided') - queries = [convert_model(x) for x in queries] headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_view_queries', + operation_id='get_membership_information', ) headers.update(sdk_headers) - data = { - 'queries': queries, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, ddoc, view) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_view/{view}/queries'.format(**path_param_dict) + url = '/_membership' request = self.prepare_request( - method='POST', + method='GET', url=url, headers=headers, - data=data, ) response = self.send(request, **kwargs) return response - def post_view_queries_as_stream( + def get_up_information( self, - db: str, - ddoc: str, - view: str, - queries: List['ViewQuery'], **kwargs, ) -> DetailedResponse: """ - Multi-query a MapReduce view as stream. + Retrieve information about whether the server is up. - This operation runs multiple specified view queries against the view function from - the specified design document. + Confirms that the server is up, running, and ready to respond to requests. If the + cluster is unavailable the endpoint returns a `503` response code. + **Tip:** The authentication for this endpoint is only enforced when using IAM. - :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. - :param List[ViewQuery] queries: An array of query objects with fields for - the parameters of each individual view query to be executed. The field - names and their meaning are the same as the query parameters of a regular - view request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `UpInformation` object """ - if not db: - raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') - if queries is None: - raise ValueError('queries must be provided') - queries = [convert_model(x) for x in queries] headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_view_queries_as_stream', + operation_id='get_up_information', ) headers.update(sdk_headers) - data = { - 'queries': queries, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, ddoc, view) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_view/{view}/queries'.format(**path_param_dict) + url = '/_up' request = self.prepare_request( - method='POST', + method='GET', url=url, headers=headers, - data=data, ) - response = self.send(request, stream=True, **kwargs) + response = self.send(request, **kwargs) return response - ######################### - # Queries - ######################### - - def get_partition_information( + def post_index_info( self, db: str, - partition_key: str, + *, + att_encoding_info: Optional[bool] = None, + attachments: Optional[bool] = None, + conflicts: Optional[bool] = None, + descending: Optional[bool] = None, + include_docs: Optional[bool] = None, + inclusive_end: Optional[bool] = None, + limit: Optional[int] = None, + skip: Optional[int] = None, + update_seq: Optional[bool] = None, + end_key: Optional[str] = None, + key: Optional[str] = None, + keys: Optional[List[str]] = None, + start_key: Optional[str] = None, + type: Optional[List[str]] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve information about a database partition. + Retrieve index status for all design documents. - Given a partition key, return the database name, sizes, partition, doc count, and - doc delete count. + **EXPERIMENTAL** Returns index status grouped by type for all design documents in + the database or a filtered subset. Results are grouped into `view_indexes` and + `search_indexes`. Each entry identifies the index by its design document and, for + search indexes, its `name`. Use a `keys` array in the request body to select + design documents by ID. Use this endpoint to verify whether a database's indexes + are fully built, for example before switching traffic to a replica. :param str db: Path parameter to specify the database name. - :param str partition_key: Path parameter to specify the database partition - key. + :param bool att_encoding_info: (optional) Parameter to specify whether to + include the encoding information for compressed attachments. This only + applies when requesting documents in the response. + :param bool attachments: (optional) Parameter to specify whether to include + attachment content in included document content or only the attachment + metadata. This only applies when requesting documents in the response. + :param bool conflicts: (optional) Parameter to specify whether to include a + list of conflicted revisions in each returned document. This only applies + when requesting documents in the response. + :param bool descending: (optional) Parameter to specify whether to return + the documents in descending by key order. + :param bool include_docs: (optional) Parameter to specify whether to + include the full content of the documents in the response. + :param bool inclusive_end: (optional) Parameter to specify whether to + include the specified end key in the result. + :param int limit: (optional) Parameter to specify the number of returned + documents to limit the result to. + :param int skip: (optional) Parameter to specify the number of records + before starting to return the results. + :param bool update_seq: (optional) Parameter to specify whether to include + in the response an update_seq value indicating the sequence id of the + database the view reflects. + :param str end_key: (optional) Schema for a document ID. + :param str key: (optional) Schema for a document ID. + :param List[str] keys: (optional) Schema for a list of document IDs. + :param str start_key: (optional) Schema for a document ID. + :param List[str] type: (optional) Index types to filter results by. If + omitted, the response includes all index types. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `PartitionInformation` object + :rtype: DetailedResponse with `dict` result representing a `IndexInfoResult` object """ if not db: raise ValueError('db must be provided') - if not partition_key: - raise ValueError('partition_key must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_partition_information', + operation_id='post_index_info', ) headers.update(sdk_headers) + data = { + 'att_encoding_info': att_encoding_info, + 'attachments': attachments, + 'conflicts': conflicts, + 'descending': descending, + 'include_docs': include_docs, + 'inclusive_end': inclusive_end, + 'limit': limit, + 'skip': skip, + 'update_seq': update_seq, + 'end_key': end_key, + 'key': key, + 'keys': keys, + 'start_key': start_key, + 'type': type, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}'.format(**path_param_dict) + url = '/{db}/_index_info'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='POST', url=url, headers=headers, + data=data, ) response = self.send(request, **kwargs) return response - def post_partition_all_docs( + ######################### + # Views + ######################### + + def post_view( self, db: str, - partition_key: str, + ddoc: str, + view: str, *, att_encoding_info: Optional[bool] = None, attachments: Optional[bool] = None, @@ -3752,25 +3679,35 @@ def post_partition_all_docs( limit: Optional[int] = None, skip: Optional[int] = None, update_seq: Optional[bool] = None, - end_key: Optional[str] = None, - key: Optional[str] = None, - keys: Optional[List[str]] = None, - start_key: Optional[str] = None, + end_key: Optional[object] = None, + end_key_doc_id: Optional[str] = None, + group: Optional[bool] = None, + group_level: Optional[int] = None, + key: Optional[object] = None, + keys: Optional[List[object]] = None, + reduce: Optional[bool] = None, + stable: Optional[bool] = None, + start_key: Optional[object] = None, + start_key_doc_id: Optional[str] = None, + update: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a list of all documents in a database partition. + Query a MapReduce view. - Queries the primary index (all document IDs). The results that match the query - parameters are returned in a JSON object, including a list of matching documents - with basic contents, such as the ID and revision. When no query parameters are - specified, results for all documents in the database partition are returned. - Optionally, document content or additional metadata can be included in the - response. + This operation queries the specified MapReduce view of the specified design + document. By default, the map and reduce functions of the view are run to update + the view before returning the response. The advantage of using the HTTP `POST` + method is that the query is submitted as a JSON object in the request body. This + avoids the limitations of passing query options as URL query parameters of a `GET` + request. :param str db: Path parameter to specify the database name. - :param str partition_key: Path parameter to specify the database partition - key. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str view: Path parameter to specify the map reduce view function + name. :param bool att_encoding_info: (optional) Parameter to specify whether to include the encoding information for compressed attachments. This only applies when requesting documents in the response. @@ -3793,24 +3730,67 @@ def post_partition_all_docs( :param bool update_seq: (optional) Parameter to specify whether to include in the response an update_seq value indicating the sequence id of the database the view reflects. - :param str end_key: (optional) Schema for a document ID. - :param str key: (optional) Schema for a document ID. - :param List[str] keys: (optional) Schema for a list of document IDs. - :param str start_key: (optional) Schema for a document ID. + :param object end_key: (optional) Schema for any JSON type. + :param str end_key_doc_id: (optional) Stop returning rows at the specified + document ID. No effect if using `group` or not providing end key. + :param bool group: (optional) Parameter to specify whether to group reduced + results by key. Valid only if a reduce function defined in the view. If the + view emits key in JSON array format, then it is possible to reduce groups + further based on the number of array elements with the `group_level` + parameter. + :param int group_level: (optional) Parameter to specify a group level to be + used. Only applicable if the view uses keys that are JSON arrays. Implies + group is `true`. Group level groups the reduced results by the specified + number of array elements. If unset, results are grouped by the entire array + key, returning a reduced value for each complete key. + :param object key: (optional) Parameter to specify to return only rows that + match the specified key. String representation of any JSON type that + matches the key type emitted by the view function. + :param List[object] keys: (optional) Parameter to specify returning only + rows that match any of the specified keys. A JSON array of keys that match + the key type emitted by the view function. + :param bool reduce: (optional) Parameter to specify whether to use the + reduce function in a map-reduce view. Default is true when a reduce + function is defined. + A default `reduce` view type can be disabled to behave like a + `map` by setting `reduce=false` explicitly. + Be aware that `include_docs=true` is only for `map` views. Reduced views do + not include document IDs in view rows. + :param bool stable: (optional) Query parameter to specify whether use the + same replica of the index on each request. The default value `false` + contacts all replicas and returns the result from the first, fastest, + responder. Setting it to `true` when used in conjunction with + `update=false` may improve consistency at the expense of increased latency + and decreased throughput if the selected replica is not the fastest of the + available replicas. + **Note:** In general setting `true` is discouraged and is strictly not + recommended when using `update=true`. + :param object start_key: (optional) Schema for any JSON type. + :param str start_key_doc_id: (optional) Start returning rows at the + specified document ID. No effect if using `group` or not providing start + key. + :param str update: (optional) Parameter to specify whether or not the view + in question should be updated prior to responding to the user. + * `true` - Return results after the view is updated. + * `false` - Return results without updating the view. + * `lazy` - Return the view results without waiting for an update, but + update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `AllDocsResult` object + :rtype: DetailedResponse with `dict` result representing a `ViewResult` object """ if not db: raise ValueError('db must be provided') - if not partition_key: - raise ValueError('partition_key must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not view: + raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_all_docs', + operation_id='post_view', ) headers.update(sdk_headers) @@ -3825,9 +3805,16 @@ def post_partition_all_docs( 'skip': skip, 'update_seq': update_seq, 'end_key': end_key, + 'end_key_doc_id': end_key_doc_id, + 'group': group, + 'group_level': group_level, 'key': key, 'keys': keys, + 'reduce': reduce, + 'stable': stable, 'start_key': start_key, + 'start_key_doc_id': start_key_doc_id, + 'update': update, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -3838,10 +3825,10 @@ def post_partition_all_docs( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, ddoc, view) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_all_docs'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -3852,10 +3839,11 @@ def post_partition_all_docs( response = self.send(request, **kwargs) return response - def post_partition_all_docs_as_stream( + def post_view_as_stream( self, db: str, - partition_key: str, + ddoc: str, + view: str, *, att_encoding_info: Optional[bool] = None, attachments: Optional[bool] = None, @@ -3866,25 +3854,35 @@ def post_partition_all_docs_as_stream( limit: Optional[int] = None, skip: Optional[int] = None, update_seq: Optional[bool] = None, - end_key: Optional[str] = None, - key: Optional[str] = None, - keys: Optional[List[str]] = None, - start_key: Optional[str] = None, + end_key: Optional[object] = None, + end_key_doc_id: Optional[str] = None, + group: Optional[bool] = None, + group_level: Optional[int] = None, + key: Optional[object] = None, + keys: Optional[List[object]] = None, + reduce: Optional[bool] = None, + stable: Optional[bool] = None, + start_key: Optional[object] = None, + start_key_doc_id: Optional[str] = None, + update: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a list of all documents in a database partition as stream. + Query a MapReduce view as stream. - Queries the primary index (all document IDs). The results that match the query - parameters are returned in a JSON object, including a list of matching documents - with basic contents, such as the ID and revision. When no query parameters are - specified, results for all documents in the database partition are returned. - Optionally, document content or additional metadata can be included in the - response. + This operation queries the specified MapReduce view of the specified design + document. By default, the map and reduce functions of the view are run to update + the view before returning the response. The advantage of using the HTTP `POST` + method is that the query is submitted as a JSON object in the request body. This + avoids the limitations of passing query options as URL query parameters of a `GET` + request. :param str db: Path parameter to specify the database name. - :param str partition_key: Path parameter to specify the database partition - key. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str view: Path parameter to specify the map reduce view function + name. :param bool att_encoding_info: (optional) Parameter to specify whether to include the encoding information for compressed attachments. This only applies when requesting documents in the response. @@ -3907,10 +3905,51 @@ def post_partition_all_docs_as_stream( :param bool update_seq: (optional) Parameter to specify whether to include in the response an update_seq value indicating the sequence id of the database the view reflects. - :param str end_key: (optional) Schema for a document ID. - :param str key: (optional) Schema for a document ID. - :param List[str] keys: (optional) Schema for a list of document IDs. - :param str start_key: (optional) Schema for a document ID. + :param object end_key: (optional) Schema for any JSON type. + :param str end_key_doc_id: (optional) Stop returning rows at the specified + document ID. No effect if using `group` or not providing end key. + :param bool group: (optional) Parameter to specify whether to group reduced + results by key. Valid only if a reduce function defined in the view. If the + view emits key in JSON array format, then it is possible to reduce groups + further based on the number of array elements with the `group_level` + parameter. + :param int group_level: (optional) Parameter to specify a group level to be + used. Only applicable if the view uses keys that are JSON arrays. Implies + group is `true`. Group level groups the reduced results by the specified + number of array elements. If unset, results are grouped by the entire array + key, returning a reduced value for each complete key. + :param object key: (optional) Parameter to specify to return only rows that + match the specified key. String representation of any JSON type that + matches the key type emitted by the view function. + :param List[object] keys: (optional) Parameter to specify returning only + rows that match any of the specified keys. A JSON array of keys that match + the key type emitted by the view function. + :param bool reduce: (optional) Parameter to specify whether to use the + reduce function in a map-reduce view. Default is true when a reduce + function is defined. + A default `reduce` view type can be disabled to behave like a + `map` by setting `reduce=false` explicitly. + Be aware that `include_docs=true` is only for `map` views. Reduced views do + not include document IDs in view rows. + :param bool stable: (optional) Query parameter to specify whether use the + same replica of the index on each request. The default value `false` + contacts all replicas and returns the result from the first, fastest, + responder. Setting it to `true` when used in conjunction with + `update=false` may improve consistency at the expense of increased latency + and decreased throughput if the selected replica is not the fastest of the + available replicas. + **Note:** In general setting `true` is discouraged and is strictly not + recommended when using `update=true`. + :param object start_key: (optional) Schema for any JSON type. + :param str start_key_doc_id: (optional) Start returning rows at the + specified document ID. No effect if using `group` or not providing start + key. + :param str update: (optional) Parameter to specify whether or not the view + in question should be updated prior to responding to the user. + * `true` - Return results after the view is updated. + * `false` - Return results without updating the view. + * `lazy` - Return the view results without waiting for an update, but + update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. :rtype: DetailedResponse with `BinaryIO` result @@ -3918,13 +3957,15 @@ def post_partition_all_docs_as_stream( if not db: raise ValueError('db must be provided') - if not partition_key: - raise ValueError('partition_key must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not view: + raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_all_docs_as_stream', + operation_id='post_view_as_stream', ) headers.update(sdk_headers) @@ -3939,9 +3980,16 @@ def post_partition_all_docs_as_stream( 'skip': skip, 'update_seq': update_seq, 'end_key': end_key, + 'end_key_doc_id': end_key_doc_id, + 'group': group, + 'group_level': group_level, 'key': key, 'keys': keys, + 'reduce': reduce, + 'stable': stable, 'start_key': start_key, + 'start_key_doc_id': start_key_doc_id, + 'update': update, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -3952,10 +4000,10 @@ def post_partition_all_docs_as_stream( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, ddoc, view) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_all_docs'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -3966,116 +4014,126 @@ def post_partition_all_docs_as_stream( response = self.send(request, stream=True, **kwargs) return response - def post_partition_search( + def post_view_queries( self, db: str, - partition_key: str, ddoc: str, - index: str, - query: str, - *, - bookmark: Optional[str] = None, - highlight_fields: Optional[List[str]] = None, - highlight_number: Optional[int] = None, - highlight_post_tag: Optional[str] = None, - highlight_pre_tag: Optional[str] = None, - highlight_size: Optional[int] = None, - include_docs: Optional[bool] = None, - include_fields: Optional[List[str]] = None, - limit: Optional[int] = None, - sort: Optional[List[str]] = None, - stale: Optional[str] = None, + view: str, + queries: List['ViewQuery'], **kwargs, ) -> DetailedResponse: """ - Query a database partition search index. + Multi-query a MapReduce view. - Partitioned Search indexes, which are defined in design documents, allow partition - databases to be queried by using Lucene Query Parser Syntax. Search indexes are - defined by an index function, similar to a map function in MapReduce views. The - index function decides what data to index and store in the index. - Before using read the - [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) - to understand the limitations and appropriate use cases. + This operation runs multiple specified view queries against the view function from + the specified design document. :param str db: Path parameter to specify the database name. - :param str partition_key: Path parameter to specify the database partition - key. :param str ddoc: Path parameter to specify the design document name. The design document name is the design document ID excluding the `_design/` prefix. - :param str index: Path parameter to specify the index name. - :param str query: The Lucene query to execute. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param List[str] highlight_fields: (optional) Specifies which fields to - highlight. If specified, the result object contains a highlights field with - an entry for each specified field. - :param int highlight_number: (optional) Number of fragments that are - returned in highlights. If the search term occurs less often than the - number of fragments that are specified, longer fragments are returned. - :param str highlight_post_tag: (optional) A string that is inserted after - the highlighted word in the highlights output. - :param str highlight_pre_tag: (optional) A string that is inserted before - the highlighted word in the highlights output. - :param int highlight_size: (optional) Number of characters in each fragment - for highlights. - :param bool include_docs: (optional) Include the full content of the - documents in the return. - :param List[str] include_fields: (optional) A JSON array of field names to - include in search results. Any fields that are included must be indexed - with the store:true option. The default is all fields. - :param int limit: (optional) Limit the number of the returned documents to - the specified number. - :param List[str] sort: (optional) Specifies the sort order of the results. - In a grouped search (when group_field is used), this parameter specifies - the sort order within a group. The default sort order is relevance. A JSON - string of the form "fieldname<type>" or "-fieldname<type>" for - descending order, where fieldname is the name of a string or number field, - and type is either a number, a string, or a JSON array of strings. The type - part is optional, and defaults to number. Some examples are "foo", "-foo", - "bar<string>", "-foo<number>" and ["-foo<number>", - "bar<string>"]. String fields that are used for sorting must not be - analyzed fields. Fields that are used for sorting must be indexed by the - same indexer that is used for the search query. - :param str stale: (optional) Do not wait for the index to finish building - to return results. + :param str view: Path parameter to specify the map reduce view function + name. + :param List[ViewQuery] queries: An array of query objects with fields for + the parameters of each individual view query to be executed. The field + names and their meaning are the same as the query parameters of a regular + view request. + :param dict headers: A `dict` containing the request headers + :return: A `DetailedResponse` containing the result, headers and HTTP status code. + :rtype: DetailedResponse with `dict` result representing a `ViewQueriesResult` object + """ + + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not view: + raise ValueError('view must be provided') + if queries is None: + raise ValueError('queries must be provided') + queries = [convert_model(x) for x in queries] + headers = {} + sdk_headers = get_sdk_headers( + service_name=self.DEFAULT_SERVICE_NAME, + service_version='V1', + operation_id='post_view_queries', + ) + headers.update(sdk_headers) + + data = { + 'queries': queries, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + + if 'headers' in kwargs: + headers.update(kwargs.get('headers')) + del kwargs['headers'] + headers['Accept'] = 'application/json' + + path_param_keys = ['db', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, ddoc, view) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_design/{ddoc}/_view/{view}/queries'.format(**path_param_dict) + request = self.prepare_request( + method='POST', + url=url, + headers=headers, + data=data, + ) + + response = self.send(request, **kwargs) + return response + + def post_view_queries_as_stream( + self, + db: str, + ddoc: str, + view: str, + queries: List['ViewQuery'], + **kwargs, + ) -> DetailedResponse: + """ + Multi-query a MapReduce view as stream. + + This operation runs multiple specified view queries against the view function from + the specified design document. + + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str view: Path parameter to specify the map reduce view function + name. + :param List[ViewQuery] queries: An array of query objects with fields for + the parameters of each individual view query to be executed. The field + names and their meaning are the same as the query parameters of a regular + view request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SearchResult` object + :rtype: DetailedResponse with `BinaryIO` result """ if not db: raise ValueError('db must be provided') - if not partition_key: - raise ValueError('partition_key must be provided') if not ddoc: raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') - if query is None: - raise ValueError('query must be provided') + if not view: + raise ValueError('view must be provided') + if queries is None: + raise ValueError('queries must be provided') + queries = [convert_model(x) for x in queries] headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_search', + operation_id='post_view_queries_as_stream', ) headers.update(sdk_headers) data = { - 'query': query, - 'bookmark': bookmark, - 'highlight_fields': highlight_fields, - 'highlight_number': highlight_number, - 'highlight_post_tag': highlight_post_tag, - 'highlight_pre_tag': highlight_pre_tag, - 'highlight_size': highlight_size, - 'include_docs': include_docs, - 'include_fields': include_fields, - 'limit': limit, - 'sort': sort, - 'stale': stale, + 'queries': queries, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -4086,10 +4144,10 @@ def post_partition_search( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, partition_key, ddoc, index) + path_param_keys = ['db', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, ddoc, view) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_view/{view}/queries'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -4097,149 +4155,67 @@ def post_partition_search( data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - def post_partition_search_as_stream( + ######################### + # Queries + ######################### + + def get_partition_information( self, db: str, partition_key: str, - ddoc: str, - index: str, - query: str, - *, - bookmark: Optional[str] = None, - highlight_fields: Optional[List[str]] = None, - highlight_number: Optional[int] = None, - highlight_post_tag: Optional[str] = None, - highlight_pre_tag: Optional[str] = None, - highlight_size: Optional[int] = None, - include_docs: Optional[bool] = None, - include_fields: Optional[List[str]] = None, - limit: Optional[int] = None, - sort: Optional[List[str]] = None, - stale: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a database partition search index as stream. + Retrieve information about a database partition. - Partitioned Search indexes, which are defined in design documents, allow partition - databases to be queried by using Lucene Query Parser Syntax. Search indexes are - defined by an index function, similar to a map function in MapReduce views. The - index function decides what data to index and store in the index. - Before using read the - [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) - to understand the limitations and appropriate use cases. + Given a partition key, return the database name, sizes, partition, doc count, and + doc delete count. :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str index: Path parameter to specify the index name. - :param str query: The Lucene query to execute. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param List[str] highlight_fields: (optional) Specifies which fields to - highlight. If specified, the result object contains a highlights field with - an entry for each specified field. - :param int highlight_number: (optional) Number of fragments that are - returned in highlights. If the search term occurs less often than the - number of fragments that are specified, longer fragments are returned. - :param str highlight_post_tag: (optional) A string that is inserted after - the highlighted word in the highlights output. - :param str highlight_pre_tag: (optional) A string that is inserted before - the highlighted word in the highlights output. - :param int highlight_size: (optional) Number of characters in each fragment - for highlights. - :param bool include_docs: (optional) Include the full content of the - documents in the return. - :param List[str] include_fields: (optional) A JSON array of field names to - include in search results. Any fields that are included must be indexed - with the store:true option. The default is all fields. - :param int limit: (optional) Limit the number of the returned documents to - the specified number. - :param List[str] sort: (optional) Specifies the sort order of the results. - In a grouped search (when group_field is used), this parameter specifies - the sort order within a group. The default sort order is relevance. A JSON - string of the form "fieldname<type>" or "-fieldname<type>" for - descending order, where fieldname is the name of a string or number field, - and type is either a number, a string, or a JSON array of strings. The type - part is optional, and defaults to number. Some examples are "foo", "-foo", - "bar<string>", "-foo<number>" and ["-foo<number>", - "bar<string>"]. String fields that are used for sorting must not be - analyzed fields. Fields that are used for sorting must be indexed by the - same indexer that is used for the search query. - :param str stale: (optional) Do not wait for the index to finish building - to return results. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `PartitionInformation` object """ if not db: raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') - if query is None: - raise ValueError('query must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_search_as_stream', + operation_id='get_partition_information', ) headers.update(sdk_headers) - data = { - 'query': query, - 'bookmark': bookmark, - 'highlight_fields': highlight_fields, - 'highlight_number': highlight_number, - 'highlight_post_tag': highlight_post_tag, - 'highlight_pre_tag': highlight_pre_tag, - 'highlight_size': highlight_size, - 'include_docs': include_docs, - 'include_fields': include_fields, - 'limit': limit, - 'sort': sort, - 'stale': stale, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, partition_key, ddoc, index) + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}'.format(**path_param_dict) request = self.prepare_request( - method='POST', + method='GET', url=url, headers=headers, - data=data, ) - response = self.send(request, stream=True, **kwargs) + response = self.send(request, **kwargs) return response - def post_partition_view( + def post_partition_all_docs( self, db: str, partition_key: str, - ddoc: str, - view: str, *, att_encoding_info: Optional[bool] = None, attachments: Optional[bool] = None, @@ -4250,38 +4226,25 @@ def post_partition_view( limit: Optional[int] = None, skip: Optional[int] = None, update_seq: Optional[bool] = None, - end_key: Optional[object] = None, - end_key_doc_id: Optional[str] = None, - group: Optional[bool] = None, - group_level: Optional[int] = None, - key: Optional[object] = None, - keys: Optional[List[object]] = None, - reduce: Optional[bool] = None, - start_key: Optional[object] = None, - start_key_doc_id: Optional[str] = None, - update: Optional[str] = None, + end_key: Optional[str] = None, + key: Optional[str] = None, + keys: Optional[List[str]] = None, + start_key: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a database partition MapReduce view function. + Query a list of all documents in a database partition. - Runs the specified view function from the specified design document. Unlike `GET - /{db}/_design/{ddoc}/_view/{view}` for accessing views, the POST method supports - the specification of explicit keys to be retrieved from the view results. The - remainder of the POST view functionality is identical to the `GET - /{db}/_design/{ddoc}/_view/{view}` API. - Before using read the - [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) - to understand the limitations and appropriate use cases. + Queries the primary index (all document IDs). The results that match the query + parameters are returned in a JSON object, including a list of matching documents + with basic contents, such as the ID and revision. When no query parameters are + specified, results for all documents in the database partition are returned. + Optionally, document content or additional metadata can be included in the + response. :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. :param bool att_encoding_info: (optional) Parameter to specify whether to include the encoding information for compressed attachments. This only applies when requesting documents in the response. @@ -4289,75 +4252,39 @@ def post_partition_view( attachment content in included document content or only the attachment metadata. This only applies when requesting documents in the response. :param bool conflicts: (optional) Parameter to specify whether to include a - list of conflicted revisions in each returned document. This only applies - when requesting documents in the response. - :param bool descending: (optional) Parameter to specify whether to return - the documents in descending by key order. - :param bool include_docs: (optional) Parameter to specify whether to - include the full content of the documents in the response. - :param bool inclusive_end: (optional) Parameter to specify whether to - include the specified end key in the result. - :param int limit: (optional) Parameter to specify the number of returned - documents to limit the result to. - :param int skip: (optional) Parameter to specify the number of records - before starting to return the results. - :param bool update_seq: (optional) Parameter to specify whether to include - in the response an update_seq value indicating the sequence id of the - database the view reflects. - :param object end_key: (optional) Schema for any JSON type. - :param str end_key_doc_id: (optional) Stop returning rows at the specified - document ID. No effect if using `group` or not providing end key. - :param bool group: (optional) Parameter to specify whether to group reduced - results by key. Valid only if a reduce function defined in the view. If the - view emits key in JSON array format, then it is possible to reduce groups - further based on the number of array elements with the `group_level` - parameter. - :param int group_level: (optional) Parameter to specify a group level to be - used. Only applicable if the view uses keys that are JSON arrays. Implies - group is `true`. Group level groups the reduced results by the specified - number of array elements. If unset, results are grouped by the entire array - key, returning a reduced value for each complete key. - :param object key: (optional) Parameter to specify to return only rows that - match the specified key. String representation of any JSON type that - matches the key type emitted by the view function. - :param List[object] keys: (optional) Parameter to specify returning only - rows that match any of the specified keys. A JSON array of keys that match - the key type emitted by the view function. - :param bool reduce: (optional) Parameter to specify whether to use the - reduce function in a map-reduce view. Default is true when a reduce - function is defined. - A default `reduce` view type can be disabled to behave like a - `map` by setting `reduce=false` explicitly. - Be aware that `include_docs=true` is only for `map` views. Reduced views do - not include document IDs in view rows. - :param object start_key: (optional) Schema for any JSON type. - :param str start_key_doc_id: (optional) Start returning rows at the - specified document ID. No effect if using `group` or not providing start - key. - :param str update: (optional) Parameter to specify whether or not the view - in question should be updated prior to responding to the user. - * `true` - Return results after the view is updated. - * `false` - Return results without updating the view. - * `lazy` - Return the view results without waiting for an update, but - update them immediately after the request. + list of conflicted revisions in each returned document. This only applies + when requesting documents in the response. + :param bool descending: (optional) Parameter to specify whether to return + the documents in descending by key order. + :param bool include_docs: (optional) Parameter to specify whether to + include the full content of the documents in the response. + :param bool inclusive_end: (optional) Parameter to specify whether to + include the specified end key in the result. + :param int limit: (optional) Parameter to specify the number of returned + documents to limit the result to. + :param int skip: (optional) Parameter to specify the number of records + before starting to return the results. + :param bool update_seq: (optional) Parameter to specify whether to include + in the response an update_seq value indicating the sequence id of the + database the view reflects. + :param str end_key: (optional) Schema for a document ID. + :param str key: (optional) Schema for a document ID. + :param List[str] keys: (optional) Schema for a list of document IDs. + :param str start_key: (optional) Schema for a document ID. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ViewResult` object + :rtype: DetailedResponse with `dict` result representing a `AllDocsResult` object """ if not db: raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_view', + operation_id='post_partition_all_docs', ) headers.update(sdk_headers) @@ -4372,15 +4299,9 @@ def post_partition_view( 'skip': skip, 'update_seq': update_seq, 'end_key': end_key, - 'end_key_doc_id': end_key_doc_id, - 'group': group, - 'group_level': group_level, 'key': key, 'keys': keys, - 'reduce': reduce, 'start_key': start_key, - 'start_key_doc_id': start_key_doc_id, - 'update': update, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -4391,10 +4312,10 @@ def post_partition_view( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, partition_key, ddoc, view) + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_all_docs'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -4405,12 +4326,10 @@ def post_partition_view( response = self.send(request, **kwargs) return response - def post_partition_view_as_stream( + def post_partition_all_docs_as_stream( self, db: str, partition_key: str, - ddoc: str, - view: str, *, att_encoding_info: Optional[bool] = None, attachments: Optional[bool] = None, @@ -4421,38 +4340,25 @@ def post_partition_view_as_stream( limit: Optional[int] = None, skip: Optional[int] = None, update_seq: Optional[bool] = None, - end_key: Optional[object] = None, - end_key_doc_id: Optional[str] = None, - group: Optional[bool] = None, - group_level: Optional[int] = None, - key: Optional[object] = None, - keys: Optional[List[object]] = None, - reduce: Optional[bool] = None, - start_key: Optional[object] = None, - start_key_doc_id: Optional[str] = None, - update: Optional[str] = None, + end_key: Optional[str] = None, + key: Optional[str] = None, + keys: Optional[List[str]] = None, + start_key: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a database partition MapReduce view function as stream. + Query a list of all documents in a database partition as stream. - Runs the specified view function from the specified design document. Unlike `GET - /{db}/_design/{ddoc}/_view/{view}` for accessing views, the POST method supports - the specification of explicit keys to be retrieved from the view results. The - remainder of the POST view functionality is identical to the `GET - /{db}/_design/{ddoc}/_view/{view}` API. - Before using read the - [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) - to understand the limitations and appropriate use cases. + Queries the primary index (all document IDs). The results that match the query + parameters are returned in a JSON object, including a list of matching documents + with basic contents, such as the ID and revision. When no query parameters are + specified, results for all documents in the database partition are returned. + Optionally, document content or additional metadata can be included in the + response. :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str view: Path parameter to specify the map reduce view function - name. :param bool att_encoding_info: (optional) Parameter to specify whether to include the encoding information for compressed attachments. This only applies when requesting documents in the response. @@ -4475,42 +4381,10 @@ def post_partition_view_as_stream( :param bool update_seq: (optional) Parameter to specify whether to include in the response an update_seq value indicating the sequence id of the database the view reflects. - :param object end_key: (optional) Schema for any JSON type. - :param str end_key_doc_id: (optional) Stop returning rows at the specified - document ID. No effect if using `group` or not providing end key. - :param bool group: (optional) Parameter to specify whether to group reduced - results by key. Valid only if a reduce function defined in the view. If the - view emits key in JSON array format, then it is possible to reduce groups - further based on the number of array elements with the `group_level` - parameter. - :param int group_level: (optional) Parameter to specify a group level to be - used. Only applicable if the view uses keys that are JSON arrays. Implies - group is `true`. Group level groups the reduced results by the specified - number of array elements. If unset, results are grouped by the entire array - key, returning a reduced value for each complete key. - :param object key: (optional) Parameter to specify to return only rows that - match the specified key. String representation of any JSON type that - matches the key type emitted by the view function. - :param List[object] keys: (optional) Parameter to specify returning only - rows that match any of the specified keys. A JSON array of keys that match - the key type emitted by the view function. - :param bool reduce: (optional) Parameter to specify whether to use the - reduce function in a map-reduce view. Default is true when a reduce - function is defined. - A default `reduce` view type can be disabled to behave like a - `map` by setting `reduce=false` explicitly. - Be aware that `include_docs=true` is only for `map` views. Reduced views do - not include document IDs in view rows. - :param object start_key: (optional) Schema for any JSON type. - :param str start_key_doc_id: (optional) Start returning rows at the - specified document ID. No effect if using `group` or not providing start - key. - :param str update: (optional) Parameter to specify whether or not the view - in question should be updated prior to responding to the user. - * `true` - Return results after the view is updated. - * `false` - Return results without updating the view. - * `lazy` - Return the view results without waiting for an update, but - update them immediately after the request. + :param str end_key: (optional) Schema for a document ID. + :param str key: (optional) Schema for a document ID. + :param List[str] keys: (optional) Schema for a list of document IDs. + :param str start_key: (optional) Schema for a document ID. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. :rtype: DetailedResponse with `BinaryIO` result @@ -4520,15 +4394,11 @@ def post_partition_view_as_stream( raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not view: - raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_view_as_stream', + operation_id='post_partition_all_docs_as_stream', ) headers.update(sdk_headers) @@ -4543,15 +4413,9 @@ def post_partition_view_as_stream( 'skip': skip, 'update_seq': update_seq, 'end_key': end_key, - 'end_key_doc_id': end_key_doc_id, - 'group': group, - 'group_level': group_level, 'key': key, 'keys': keys, - 'reduce': reduce, 'start_key': start_key, - 'start_key_doc_id': start_key_doc_id, - 'update': update, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -4562,10 +4426,10 @@ def post_partition_view_as_stream( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key', 'ddoc', 'view'] - path_param_values = self.encode_path_vars(db, partition_key, ddoc, view) + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_all_docs'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -4576,147 +4440,116 @@ def post_partition_view_as_stream( response = self.send(request, stream=True, **kwargs) return response - def post_partition_explain( + def post_partition_search( self, db: str, partition_key: str, - selector: dict, + ddoc: str, + index: str, + query: str, *, - allow_fallback: Optional[bool] = None, bookmark: Optional[str] = None, - conflicts: Optional[bool] = None, - execution_stats: Optional[bool] = None, - fields: Optional[List[str]] = None, + highlight_fields: Optional[List[str]] = None, + highlight_number: Optional[int] = None, + highlight_post_tag: Optional[str] = None, + highlight_pre_tag: Optional[str] = None, + highlight_size: Optional[int] = None, + include_docs: Optional[bool] = None, + include_fields: Optional[List[str]] = None, limit: Optional[int] = None, - skip: Optional[int] = None, - sort: Optional[List[dict]] = None, - stable: Optional[bool] = None, - update: Optional[str] = None, - use_index: Optional[List[str]] = None, + sort: Optional[List[str]] = None, + stale: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve information about which partition index is used for a query. + Query a database partition search index. - Shows which index is being used by the query. Parameters are the same as the - [`/{db}/_partition/{partition_key}/_find` endpoint](#postpartitionfind-queries). + Partitioned Search indexes, which are defined in design documents, allow partition + databases to be queried by using Lucene Query Parser Syntax. Search indexes are + defined by an index function, similar to a map function in MapReduce views. The + index function decides what data to index and store in the index. + Before using read the + [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) + to understand the limitations and appropriate use cases. :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param dict selector: JSON object describing criteria used to select - documents. The selector specifies fields in the document, and provides an - expression to evaluate with the field content or other data. - The selector object must: - * Be structured as valid JSON. - * Contain a valid query expression. - Using a selector is significantly more efficient than using a JavaScript - filter function, and is the recommended option if filtering on document - attributes only. - Elementary selector syntax requires you to specify one or more fields, and - the corresponding values required for those fields. You can create more - complex selector expressions by combining operators. - Operators are identified by the use of a dollar sign `$` prefix in the name - field. - There are two core types of operators in the selector syntax: - * Combination operators: applied at the topmost level of selection. They - are used to combine selectors. A combination operator takes a single - argument. The argument is either another selector, or an array of - selectors. - * Condition operators: are specific to a field, and are used to evaluate - the value stored in that field. For instance, the basic `$eq` operator - matches when the specified field contains a value that is equal to the - supplied argument. - It is important for query performance to use appropriate selectors: - * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and - `$lte` (but not `$ne`) can be used as the basis of a query. You should - include at least one of these in a selector. - * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be - answered from an index. For query selectors use these operators in - conjunction with equality operators or create and use a partial index to - reduce the number of documents that will need to be scanned. - See [the Cloudant - Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a - list of all available combination and conditional operators. - For further reference see [selector - syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). - :param bool allow_fallback: (optional) Whether to allow fallback to other - indexes. Default is true. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. + :param str query: The Lucene query to execute. :param str bookmark: (optional) Opaque bookmark token used when paginating results. - :param bool conflicts: (optional) A boolean value that indicates whether or - not to include information about existing conflicts in the document. - :param bool execution_stats: (optional) Use this option to find information - about the query that was run. This information includes total key lookups, - total document lookups (when `include_docs=true` is used), and total quorum - document lookups (when each document replica is fetched). - :param List[str] fields: (optional) JSON array that uses the field syntax. - Use this parameter to specify which fields of a document must be returned. - If it is omitted or empty, the entire document is returned. - :param int limit: (optional) Maximum number of results returned. The `type: - text` indexes are limited to 200 results when queried. - :param int skip: (optional) Skip the first 'n' results, where 'n' is the - value that is specified. - :param List[dict] sort: (optional) The sort field contains a list of pairs, - each mapping a field name to a sort direction (asc or desc). The first - field name and direction pair is the topmost level of sort. The second - pair, if provided, is the next level of sort. The field can be any field, - using dotted notation if desired for sub-document fields. - For example in JSON: - `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` - When sorting with multiple fields, ensure that there is an index already - defined with all the sort fields in the same order and each object in the - sort array has a single key or at least one of the sort fields is included - in the selector. All sorting fields must use the same sort direction, - either all ascending or all descending. - :param bool stable: (optional) Whether or not the view results should be - returned from a "stable" set of shards. - :param str update: (optional) Whether to update the index prior to - returning the result. - :param List[str] use_index: (optional) Use this option to identify a - specific index to answer the query, rather than letting the IBM Cloudant - query planner choose an index. Specified as a two element array of design - document id followed by index name, for example `["my_design_doc", - "my_index"]`. - It’s recommended to specify indexes explicitly in your queries to prevent - existing queries being affected by new indexes that might get added later. - If the specified index doesn't exist or can't answer the query then the - server ignores the value and answers using another index or a full scan of - all documents. To change this behavior set `allow_fallback` to `false` and - the server responds instead with a `400` status code if the requested index - is unsuitable to answer the query. + :param List[str] highlight_fields: (optional) Specifies which fields to + highlight. If specified, the result object contains a highlights field with + an entry for each specified field. + :param int highlight_number: (optional) Number of fragments that are + returned in highlights. If the search term occurs less often than the + number of fragments that are specified, longer fragments are returned. + :param str highlight_post_tag: (optional) A string that is inserted after + the highlighted word in the highlights output. + :param str highlight_pre_tag: (optional) A string that is inserted before + the highlighted word in the highlights output. + :param int highlight_size: (optional) Number of characters in each fragment + for highlights. + :param bool include_docs: (optional) Include the full content of the + documents in the return. + :param List[str] include_fields: (optional) A JSON array of field names to + include in search results. Any fields that are included must be indexed + with the store:true option. The default is all fields. + :param int limit: (optional) Limit the number of the returned documents to + the specified number. + :param List[str] sort: (optional) Specifies the sort order of the results. + In a grouped search (when group_field is used), this parameter specifies + the sort order within a group. The default sort order is relevance. A JSON + string of the form "fieldname<type>" or "-fieldname<type>" for + descending order, where fieldname is the name of a string or number field, + and type is either a number, a string, or a JSON array of strings. The type + part is optional, and defaults to number. Some examples are "foo", "-foo", + "bar<string>", "-foo<number>" and ["-foo<number>", + "bar<string>"]. String fields that are used for sorting must not be + analyzed fields. Fields that are used for sorting must be indexed by the + same indexer that is used for the search query. + :param str stale: (optional) Do not wait for the index to finish building + to return results. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ExplainResult` object + :rtype: DetailedResponse with `dict` result representing a `SearchResult` object """ if not db: raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if selector is None: - raise ValueError('selector must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') + if query is None: + raise ValueError('query must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_explain', + operation_id='post_partition_search', ) headers.update(sdk_headers) data = { - 'selector': selector, - 'allow_fallback': allow_fallback, + 'query': query, 'bookmark': bookmark, - 'conflicts': conflicts, - 'execution_stats': execution_stats, - 'fields': fields, + 'highlight_fields': highlight_fields, + 'highlight_number': highlight_number, + 'highlight_post_tag': highlight_post_tag, + 'highlight_pre_tag': highlight_pre_tag, + 'highlight_size': highlight_size, + 'include_docs': include_docs, + 'include_fields': include_fields, 'limit': limit, - 'skip': skip, 'sort': sort, - 'stable': stable, - 'update': update, - 'use_index': use_index, + 'stale': stale, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -4727,10 +4560,10 @@ def post_partition_explain( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db', 'partition_key', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, partition_key, ddoc, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_explain'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -4741,40 +4574,34 @@ def post_partition_explain( response = self.send(request, **kwargs) return response - def post_partition_find( + def post_partition_search_as_stream( self, db: str, partition_key: str, - selector: dict, + ddoc: str, + index: str, + query: str, *, - allow_fallback: Optional[bool] = None, bookmark: Optional[str] = None, - conflicts: Optional[bool] = None, - execution_stats: Optional[bool] = None, - fields: Optional[List[str]] = None, + highlight_fields: Optional[List[str]] = None, + highlight_number: Optional[int] = None, + highlight_post_tag: Optional[str] = None, + highlight_pre_tag: Optional[str] = None, + highlight_size: Optional[int] = None, + include_docs: Optional[bool] = None, + include_fields: Optional[List[str]] = None, limit: Optional[int] = None, - skip: Optional[int] = None, - sort: Optional[List[dict]] = None, - stable: Optional[bool] = None, - update: Optional[str] = None, - use_index: Optional[List[str]] = None, + sort: Optional[List[str]] = None, + stale: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Query a database partition index by using selector syntax. + Query a database partition search index as stream. - Query documents by using a declarative JSON querying syntax. It's best practice to - create an appropriate index for all fields in selector by using the `_index` - endpoint. - Queries without an appropriate backing index by default fallback to using the - built-in `_all_docs` index. This isn't recommended because it has a significant - performance impact causing a full scan of the partition with each request. In this - case the response body includes a warning field recommending the creation of an - index. - To avoid the fallback behavior set the `allow_fallback` option to `false` and the - server responds with a `400` status code if no suitable index exists. If you want - to use only a specific index for your query set - `allow_fallback` to `false` and set the `use_index` option. + Partitioned Search indexes, which are defined in design documents, allow partition + databases to be queried by using Lucene Query Parser Syntax. Search indexes are + defined by an index function, similar to a map function in MapReduce views. The + index function decides what data to index and store in the index. Before using read the [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) to understand the limitations and appropriate use cases. @@ -4782,119 +4609,81 @@ def post_partition_find( :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param dict selector: JSON object describing criteria used to select - documents. The selector specifies fields in the document, and provides an - expression to evaluate with the field content or other data. - The selector object must: - * Be structured as valid JSON. - * Contain a valid query expression. - Using a selector is significantly more efficient than using a JavaScript - filter function, and is the recommended option if filtering on document - attributes only. - Elementary selector syntax requires you to specify one or more fields, and - the corresponding values required for those fields. You can create more - complex selector expressions by combining operators. - Operators are identified by the use of a dollar sign `$` prefix in the name - field. - There are two core types of operators in the selector syntax: - * Combination operators: applied at the topmost level of selection. They - are used to combine selectors. A combination operator takes a single - argument. The argument is either another selector, or an array of - selectors. - * Condition operators: are specific to a field, and are used to evaluate - the value stored in that field. For instance, the basic `$eq` operator - matches when the specified field contains a value that is equal to the - supplied argument. - It is important for query performance to use appropriate selectors: - * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and - `$lte` (but not `$ne`) can be used as the basis of a query. You should - include at least one of these in a selector. - * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be - answered from an index. For query selectors use these operators in - conjunction with equality operators or create and use a partial index to - reduce the number of documents that will need to be scanned. - See [the Cloudant - Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a - list of all available combination and conditional operators. - For further reference see [selector - syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). - :param bool allow_fallback: (optional) Whether to allow fallback to other - indexes. Default is true. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. + :param str query: The Lucene query to execute. :param str bookmark: (optional) Opaque bookmark token used when paginating results. - :param bool conflicts: (optional) A boolean value that indicates whether or - not to include information about existing conflicts in the document. - :param bool execution_stats: (optional) Use this option to find information - about the query that was run. This information includes total key lookups, - total document lookups (when `include_docs=true` is used), and total quorum - document lookups (when each document replica is fetched). - :param List[str] fields: (optional) JSON array that uses the field syntax. - Use this parameter to specify which fields of a document must be returned. - If it is omitted or empty, the entire document is returned. - :param int limit: (optional) Maximum number of results returned. The `type: - text` indexes are limited to 200 results when queried. - :param int skip: (optional) Skip the first 'n' results, where 'n' is the - value that is specified. - :param List[dict] sort: (optional) The sort field contains a list of pairs, - each mapping a field name to a sort direction (asc or desc). The first - field name and direction pair is the topmost level of sort. The second - pair, if provided, is the next level of sort. The field can be any field, - using dotted notation if desired for sub-document fields. - For example in JSON: - `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` - When sorting with multiple fields, ensure that there is an index already - defined with all the sort fields in the same order and each object in the - sort array has a single key or at least one of the sort fields is included - in the selector. All sorting fields must use the same sort direction, - either all ascending or all descending. - :param bool stable: (optional) Whether or not the view results should be - returned from a "stable" set of shards. - :param str update: (optional) Whether to update the index prior to - returning the result. - :param List[str] use_index: (optional) Use this option to identify a - specific index to answer the query, rather than letting the IBM Cloudant - query planner choose an index. Specified as a two element array of design - document id followed by index name, for example `["my_design_doc", - "my_index"]`. - It’s recommended to specify indexes explicitly in your queries to prevent - existing queries being affected by new indexes that might get added later. - If the specified index doesn't exist or can't answer the query then the - server ignores the value and answers using another index or a full scan of - all documents. To change this behavior set `allow_fallback` to `false` and - the server responds instead with a `400` status code if the requested index - is unsuitable to answer the query. + :param List[str] highlight_fields: (optional) Specifies which fields to + highlight. If specified, the result object contains a highlights field with + an entry for each specified field. + :param int highlight_number: (optional) Number of fragments that are + returned in highlights. If the search term occurs less often than the + number of fragments that are specified, longer fragments are returned. + :param str highlight_post_tag: (optional) A string that is inserted after + the highlighted word in the highlights output. + :param str highlight_pre_tag: (optional) A string that is inserted before + the highlighted word in the highlights output. + :param int highlight_size: (optional) Number of characters in each fragment + for highlights. + :param bool include_docs: (optional) Include the full content of the + documents in the return. + :param List[str] include_fields: (optional) A JSON array of field names to + include in search results. Any fields that are included must be indexed + with the store:true option. The default is all fields. + :param int limit: (optional) Limit the number of the returned documents to + the specified number. + :param List[str] sort: (optional) Specifies the sort order of the results. + In a grouped search (when group_field is used), this parameter specifies + the sort order within a group. The default sort order is relevance. A JSON + string of the form "fieldname<type>" or "-fieldname<type>" for + descending order, where fieldname is the name of a string or number field, + and type is either a number, a string, or a JSON array of strings. The type + part is optional, and defaults to number. Some examples are "foo", "-foo", + "bar<string>", "-foo<number>" and ["-foo<number>", + "bar<string>"]. String fields that are used for sorting must not be + analyzed fields. Fields that are used for sorting must be indexed by the + same indexer that is used for the search query. + :param str stale: (optional) Do not wait for the index to finish building + to return results. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `FindResult` object + :rtype: DetailedResponse with `BinaryIO` result """ if not db: raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if selector is None: - raise ValueError('selector must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') + if query is None: + raise ValueError('query must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_find', + operation_id='post_partition_search_as_stream', ) headers.update(sdk_headers) data = { - 'selector': selector, - 'allow_fallback': allow_fallback, + 'query': query, 'bookmark': bookmark, - 'conflicts': conflicts, - 'execution_stats': execution_stats, - 'fields': fields, - 'limit': limit, - 'skip': skip, - 'sort': sort, - 'stable': stable, - 'update': update, - 'use_index': use_index, + 'highlight_fields': highlight_fields, + 'highlight_number': highlight_number, + 'highlight_post_tag': highlight_post_tag, + 'highlight_pre_tag': highlight_pre_tag, + 'highlight_size': highlight_size, + 'include_docs': include_docs, + 'include_fields': include_fields, + 'limit': limit, + 'sort': sort, + 'stale': stale, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -4905,10 +4694,10 @@ def post_partition_find( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db', 'partition_key', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, partition_key, ddoc, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_find'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -4916,43 +4705,45 @@ def post_partition_find( data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - def post_partition_find_as_stream( + def post_partition_view( self, db: str, partition_key: str, - selector: dict, + ddoc: str, + view: str, *, - allow_fallback: Optional[bool] = None, - bookmark: Optional[str] = None, + att_encoding_info: Optional[bool] = None, + attachments: Optional[bool] = None, conflicts: Optional[bool] = None, - execution_stats: Optional[bool] = None, - fields: Optional[List[str]] = None, + descending: Optional[bool] = None, + include_docs: Optional[bool] = None, + inclusive_end: Optional[bool] = None, limit: Optional[int] = None, skip: Optional[int] = None, - sort: Optional[List[dict]] = None, - stable: Optional[bool] = None, + update_seq: Optional[bool] = None, + end_key: Optional[object] = None, + end_key_doc_id: Optional[str] = None, + group: Optional[bool] = None, + group_level: Optional[int] = None, + key: Optional[object] = None, + keys: Optional[List[object]] = None, + reduce: Optional[bool] = None, + start_key: Optional[object] = None, + start_key_doc_id: Optional[str] = None, update: Optional[str] = None, - use_index: Optional[List[str]] = None, **kwargs, ) -> DetailedResponse: """ - Query a database partition index by using selector syntax as stream. + Query a database partition MapReduce view function. - Query documents by using a declarative JSON querying syntax. It's best practice to - create an appropriate index for all fields in selector by using the `_index` - endpoint. - Queries without an appropriate backing index by default fallback to using the - built-in `_all_docs` index. This isn't recommended because it has a significant - performance impact causing a full scan of the partition with each request. In this - case the response body includes a warning field recommending the creation of an - index. - To avoid the fallback behavior set the `allow_fallback` option to `false` and the - server responds with a `400` status code if no suitable index exists. If you want - to use only a specific index for your query set - `allow_fallback` to `false` and set the `use_index` option. + Runs the specified view function from the specified design document. Unlike `GET + /{db}/_design/{ddoc}/_view/{view}` for accessing views, the POST method supports + the specification of explicit keys to be retrieved from the view results. The + remainder of the POST view functionality is identical to the `GET + /{db}/_design/{ddoc}/_view/{view}` API. Before using read the [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) to understand the limitations and appropriate use cases. @@ -4960,119 +4751,110 @@ def post_partition_find_as_stream( :param str db: Path parameter to specify the database name. :param str partition_key: Path parameter to specify the database partition key. - :param dict selector: JSON object describing criteria used to select - documents. The selector specifies fields in the document, and provides an - expression to evaluate with the field content or other data. - The selector object must: - * Be structured as valid JSON. - * Contain a valid query expression. - Using a selector is significantly more efficient than using a JavaScript - filter function, and is the recommended option if filtering on document - attributes only. - Elementary selector syntax requires you to specify one or more fields, and - the corresponding values required for those fields. You can create more - complex selector expressions by combining operators. - Operators are identified by the use of a dollar sign `$` prefix in the name - field. - There are two core types of operators in the selector syntax: - * Combination operators: applied at the topmost level of selection. They - are used to combine selectors. A combination operator takes a single - argument. The argument is either another selector, or an array of - selectors. - * Condition operators: are specific to a field, and are used to evaluate - the value stored in that field. For instance, the basic `$eq` operator - matches when the specified field contains a value that is equal to the - supplied argument. - It is important for query performance to use appropriate selectors: - * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and - `$lte` (but not `$ne`) can be used as the basis of a query. You should - include at least one of these in a selector. - * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be - answered from an index. For query selectors use these operators in - conjunction with equality operators or create and use a partial index to - reduce the number of documents that will need to be scanned. - See [the Cloudant - Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a - list of all available combination and conditional operators. - For further reference see [selector - syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). - :param bool allow_fallback: (optional) Whether to allow fallback to other - indexes. Default is true. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param bool conflicts: (optional) A boolean value that indicates whether or - not to include information about existing conflicts in the document. - :param bool execution_stats: (optional) Use this option to find information - about the query that was run. This information includes total key lookups, - total document lookups (when `include_docs=true` is used), and total quorum - document lookups (when each document replica is fetched). - :param List[str] fields: (optional) JSON array that uses the field syntax. - Use this parameter to specify which fields of a document must be returned. - If it is omitted or empty, the entire document is returned. - :param int limit: (optional) Maximum number of results returned. The `type: - text` indexes are limited to 200 results when queried. - :param int skip: (optional) Skip the first 'n' results, where 'n' is the - value that is specified. - :param List[dict] sort: (optional) The sort field contains a list of pairs, - each mapping a field name to a sort direction (asc or desc). The first - field name and direction pair is the topmost level of sort. The second - pair, if provided, is the next level of sort. The field can be any field, - using dotted notation if desired for sub-document fields. - For example in JSON: - `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` - When sorting with multiple fields, ensure that there is an index already - defined with all the sort fields in the same order and each object in the - sort array has a single key or at least one of the sort fields is included - in the selector. All sorting fields must use the same sort direction, - either all ascending or all descending. - :param bool stable: (optional) Whether or not the view results should be - returned from a "stable" set of shards. - :param str update: (optional) Whether to update the index prior to - returning the result. - :param List[str] use_index: (optional) Use this option to identify a - specific index to answer the query, rather than letting the IBM Cloudant - query planner choose an index. Specified as a two element array of design - document id followed by index name, for example `["my_design_doc", - "my_index"]`. - It’s recommended to specify indexes explicitly in your queries to prevent - existing queries being affected by new indexes that might get added later. - If the specified index doesn't exist or can't answer the query then the - server ignores the value and answers using another index or a full scan of - all documents. To change this behavior set `allow_fallback` to `false` and - the server responds instead with a `400` status code if the requested index - is unsuitable to answer the query. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str view: Path parameter to specify the map reduce view function + name. + :param bool att_encoding_info: (optional) Parameter to specify whether to + include the encoding information for compressed attachments. This only + applies when requesting documents in the response. + :param bool attachments: (optional) Parameter to specify whether to include + attachment content in included document content or only the attachment + metadata. This only applies when requesting documents in the response. + :param bool conflicts: (optional) Parameter to specify whether to include a + list of conflicted revisions in each returned document. This only applies + when requesting documents in the response. + :param bool descending: (optional) Parameter to specify whether to return + the documents in descending by key order. + :param bool include_docs: (optional) Parameter to specify whether to + include the full content of the documents in the response. + :param bool inclusive_end: (optional) Parameter to specify whether to + include the specified end key in the result. + :param int limit: (optional) Parameter to specify the number of returned + documents to limit the result to. + :param int skip: (optional) Parameter to specify the number of records + before starting to return the results. + :param bool update_seq: (optional) Parameter to specify whether to include + in the response an update_seq value indicating the sequence id of the + database the view reflects. + :param object end_key: (optional) Schema for any JSON type. + :param str end_key_doc_id: (optional) Stop returning rows at the specified + document ID. No effect if using `group` or not providing end key. + :param bool group: (optional) Parameter to specify whether to group reduced + results by key. Valid only if a reduce function defined in the view. If the + view emits key in JSON array format, then it is possible to reduce groups + further based on the number of array elements with the `group_level` + parameter. + :param int group_level: (optional) Parameter to specify a group level to be + used. Only applicable if the view uses keys that are JSON arrays. Implies + group is `true`. Group level groups the reduced results by the specified + number of array elements. If unset, results are grouped by the entire array + key, returning a reduced value for each complete key. + :param object key: (optional) Parameter to specify to return only rows that + match the specified key. String representation of any JSON type that + matches the key type emitted by the view function. + :param List[object] keys: (optional) Parameter to specify returning only + rows that match any of the specified keys. A JSON array of keys that match + the key type emitted by the view function. + :param bool reduce: (optional) Parameter to specify whether to use the + reduce function in a map-reduce view. Default is true when a reduce + function is defined. + A default `reduce` view type can be disabled to behave like a + `map` by setting `reduce=false` explicitly. + Be aware that `include_docs=true` is only for `map` views. Reduced views do + not include document IDs in view rows. + :param object start_key: (optional) Schema for any JSON type. + :param str start_key_doc_id: (optional) Start returning rows at the + specified document ID. No effect if using `group` or not providing start + key. + :param str update: (optional) Parameter to specify whether or not the view + in question should be updated prior to responding to the user. + * `true` - Return results after the view is updated. + * `false` - Return results without updating the view. + * `lazy` - Return the view results without waiting for an update, but + update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `ViewResult` object """ if not db: raise ValueError('db must be provided') if not partition_key: raise ValueError('partition_key must be provided') - if selector is None: - raise ValueError('selector must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not view: + raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_partition_find_as_stream', + operation_id='post_partition_view', ) headers.update(sdk_headers) data = { - 'selector': selector, - 'allow_fallback': allow_fallback, - 'bookmark': bookmark, + 'att_encoding_info': att_encoding_info, + 'attachments': attachments, 'conflicts': conflicts, - 'execution_stats': execution_stats, - 'fields': fields, + 'descending': descending, + 'include_docs': include_docs, + 'inclusive_end': inclusive_end, 'limit': limit, 'skip': skip, - 'sort': sort, - 'stable': stable, + 'update_seq': update_seq, + 'end_key': end_key, + 'end_key_doc_id': end_key_doc_id, + 'group': group, + 'group_level': group_level, + 'key': key, + 'keys': keys, + 'reduce': reduce, + 'start_key': start_key, + 'start_key_doc_id': start_key_doc_id, 'update': update, - 'use_index': use_index, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -5083,10 +4865,10 @@ def post_partition_find_as_stream( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'partition_key'] - path_param_values = self.encode_path_vars(db, partition_key) + path_param_keys = ['db', 'partition_key', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, partition_key, ddoc, view) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_partition/{partition_key}/_find'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -5094,157 +4876,156 @@ def post_partition_find_as_stream( data=data, ) - response = self.send(request, stream=True, **kwargs) + response = self.send(request, **kwargs) return response - ######################### - # Queries - ######################### - - def post_explain( + def post_partition_view_as_stream( self, db: str, - selector: dict, + partition_key: str, + ddoc: str, + view: str, *, - allow_fallback: Optional[bool] = None, - bookmark: Optional[str] = None, + att_encoding_info: Optional[bool] = None, + attachments: Optional[bool] = None, conflicts: Optional[bool] = None, - execution_stats: Optional[bool] = None, - fields: Optional[List[str]] = None, + descending: Optional[bool] = None, + include_docs: Optional[bool] = None, + inclusive_end: Optional[bool] = None, limit: Optional[int] = None, skip: Optional[int] = None, - sort: Optional[List[dict]] = None, - stable: Optional[bool] = None, + update_seq: Optional[bool] = None, + end_key: Optional[object] = None, + end_key_doc_id: Optional[str] = None, + group: Optional[bool] = None, + group_level: Optional[int] = None, + key: Optional[object] = None, + keys: Optional[List[object]] = None, + reduce: Optional[bool] = None, + start_key: Optional[object] = None, + start_key_doc_id: Optional[str] = None, update: Optional[str] = None, - use_index: Optional[List[str]] = None, - r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve information about which index is used for a query. + Query a database partition MapReduce view function as stream. - Shows which index is being used by the query. Parameters are the same as the - [`_find` endpoint](#postfind). + Runs the specified view function from the specified design document. Unlike `GET + /{db}/_design/{ddoc}/_view/{view}` for accessing views, the POST method supports + the specification of explicit keys to be retrieved from the view results. The + remainder of the POST view functionality is identical to the `GET + /{db}/_design/{ddoc}/_view/{view}` API. + Before using read the + [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) + to understand the limitations and appropriate use cases. :param str db: Path parameter to specify the database name. - :param dict selector: JSON object describing criteria used to select - documents. The selector specifies fields in the document, and provides an - expression to evaluate with the field content or other data. - The selector object must: - * Be structured as valid JSON. - * Contain a valid query expression. - Using a selector is significantly more efficient than using a JavaScript - filter function, and is the recommended option if filtering on document - attributes only. - Elementary selector syntax requires you to specify one or more fields, and - the corresponding values required for those fields. You can create more - complex selector expressions by combining operators. - Operators are identified by the use of a dollar sign `$` prefix in the name - field. - There are two core types of operators in the selector syntax: - * Combination operators: applied at the topmost level of selection. They - are used to combine selectors. A combination operator takes a single - argument. The argument is either another selector, or an array of - selectors. - * Condition operators: are specific to a field, and are used to evaluate - the value stored in that field. For instance, the basic `$eq` operator - matches when the specified field contains a value that is equal to the - supplied argument. - It is important for query performance to use appropriate selectors: - * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and - `$lte` (but not `$ne`) can be used as the basis of a query. You should - include at least one of these in a selector. - * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be - answered from an index. For query selectors use these operators in - conjunction with equality operators or create and use a partial index to - reduce the number of documents that will need to be scanned. - See [the Cloudant - Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a - list of all available combination and conditional operators. - For further reference see [selector - syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). - :param bool allow_fallback: (optional) Whether to allow fallback to other - indexes. Default is true. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param bool conflicts: (optional) A boolean value that indicates whether or - not to include information about existing conflicts in the document. - :param bool execution_stats: (optional) Use this option to find information - about the query that was run. This information includes total key lookups, - total document lookups (when `include_docs=true` is used), and total quorum - document lookups (when each document replica is fetched). - :param List[str] fields: (optional) JSON array that uses the field syntax. - Use this parameter to specify which fields of a document must be returned. - If it is omitted or empty, the entire document is returned. - :param int limit: (optional) Maximum number of results returned. The `type: - text` indexes are limited to 200 results when queried. - :param int skip: (optional) Skip the first 'n' results, where 'n' is the - value that is specified. - :param List[dict] sort: (optional) The sort field contains a list of pairs, - each mapping a field name to a sort direction (asc or desc). The first - field name and direction pair is the topmost level of sort. The second - pair, if provided, is the next level of sort. The field can be any field, - using dotted notation if desired for sub-document fields. - For example in JSON: - `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` - When sorting with multiple fields, ensure that there is an index already - defined with all the sort fields in the same order and each object in the - sort array has a single key or at least one of the sort fields is included - in the selector. All sorting fields must use the same sort direction, - either all ascending or all descending. - :param bool stable: (optional) Whether or not the view results should be - returned from a "stable" set of shards. - :param str update: (optional) Whether to update the index prior to - returning the result. - :param List[str] use_index: (optional) Use this option to identify a - specific index to answer the query, rather than letting the IBM Cloudant - query planner choose an index. Specified as a two element array of design - document id followed by index name, for example `["my_design_doc", - "my_index"]`. - It’s recommended to specify indexes explicitly in your queries to prevent - existing queries being affected by new indexes that might get added later. - If the specified index doesn't exist or can't answer the query then the - server ignores the value and answers using another index or a full scan of - all documents. To change this behavior set `allow_fallback` to `false` and - the server responds instead with a `400` status code if the requested index - is unsuitable to answer the query. - :param int r: (optional) The read quorum that is needed for the result. The - value defaults to 1, in which case the document that was found in the index - is returned. If set to a higher value, each document is read from at least - that many replicas before it is returned in the results. The request will - take more time than using only the document that is stored locally with the - index. + :param str partition_key: Path parameter to specify the database partition + key. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str view: Path parameter to specify the map reduce view function + name. + :param bool att_encoding_info: (optional) Parameter to specify whether to + include the encoding information for compressed attachments. This only + applies when requesting documents in the response. + :param bool attachments: (optional) Parameter to specify whether to include + attachment content in included document content or only the attachment + metadata. This only applies when requesting documents in the response. + :param bool conflicts: (optional) Parameter to specify whether to include a + list of conflicted revisions in each returned document. This only applies + when requesting documents in the response. + :param bool descending: (optional) Parameter to specify whether to return + the documents in descending by key order. + :param bool include_docs: (optional) Parameter to specify whether to + include the full content of the documents in the response. + :param bool inclusive_end: (optional) Parameter to specify whether to + include the specified end key in the result. + :param int limit: (optional) Parameter to specify the number of returned + documents to limit the result to. + :param int skip: (optional) Parameter to specify the number of records + before starting to return the results. + :param bool update_seq: (optional) Parameter to specify whether to include + in the response an update_seq value indicating the sequence id of the + database the view reflects. + :param object end_key: (optional) Schema for any JSON type. + :param str end_key_doc_id: (optional) Stop returning rows at the specified + document ID. No effect if using `group` or not providing end key. + :param bool group: (optional) Parameter to specify whether to group reduced + results by key. Valid only if a reduce function defined in the view. If the + view emits key in JSON array format, then it is possible to reduce groups + further based on the number of array elements with the `group_level` + parameter. + :param int group_level: (optional) Parameter to specify a group level to be + used. Only applicable if the view uses keys that are JSON arrays. Implies + group is `true`. Group level groups the reduced results by the specified + number of array elements. If unset, results are grouped by the entire array + key, returning a reduced value for each complete key. + :param object key: (optional) Parameter to specify to return only rows that + match the specified key. String representation of any JSON type that + matches the key type emitted by the view function. + :param List[object] keys: (optional) Parameter to specify returning only + rows that match any of the specified keys. A JSON array of keys that match + the key type emitted by the view function. + :param bool reduce: (optional) Parameter to specify whether to use the + reduce function in a map-reduce view. Default is true when a reduce + function is defined. + A default `reduce` view type can be disabled to behave like a + `map` by setting `reduce=false` explicitly. + Be aware that `include_docs=true` is only for `map` views. Reduced views do + not include document IDs in view rows. + :param object start_key: (optional) Schema for any JSON type. + :param str start_key_doc_id: (optional) Start returning rows at the + specified document ID. No effect if using `group` or not providing start + key. + :param str update: (optional) Parameter to specify whether or not the view + in question should be updated prior to responding to the user. + * `true` - Return results after the view is updated. + * `false` - Return results without updating the view. + * `lazy` - Return the view results without waiting for an update, but + update them immediately after the request. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ExplainResult` object + :rtype: DetailedResponse with `BinaryIO` result """ if not db: raise ValueError('db must be provided') - if selector is None: - raise ValueError('selector must be provided') + if not partition_key: + raise ValueError('partition_key must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not view: + raise ValueError('view must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_explain', + operation_id='post_partition_view_as_stream', ) headers.update(sdk_headers) data = { - 'selector': selector, - 'allow_fallback': allow_fallback, - 'bookmark': bookmark, + 'att_encoding_info': att_encoding_info, + 'attachments': attachments, 'conflicts': conflicts, - 'execution_stats': execution_stats, - 'fields': fields, + 'descending': descending, + 'include_docs': include_docs, + 'inclusive_end': inclusive_end, 'limit': limit, 'skip': skip, - 'sort': sort, - 'stable': stable, + 'update_seq': update_seq, + 'end_key': end_key, + 'end_key_doc_id': end_key_doc_id, + 'group': group, + 'group_level': group_level, + 'key': key, + 'keys': keys, + 'reduce': reduce, + 'start_key': start_key, + 'start_key_doc_id': start_key_doc_id, 'update': update, - 'use_index': use_index, - 'r': r, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -5255,10 +5036,10 @@ def post_explain( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['db', 'partition_key', 'ddoc', 'view'] + path_param_values = self.encode_path_vars(db, partition_key, ddoc, view) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_explain'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_design/{ddoc}/_view/{view}'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -5266,12 +5047,13 @@ def post_explain( data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - def post_find( + def post_partition_explain( self, db: str, + partition_key: str, selector: dict, *, allow_fallback: Optional[bool] = None, @@ -5285,26 +5067,17 @@ def post_find( stable: Optional[bool] = None, update: Optional[str] = None, use_index: Optional[List[str]] = None, - r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Query an index by using selector syntax. + Retrieve information about which partition index is used for a query. - Query documents by using a declarative JSON querying syntax. It's best practice to - create an appropriate index for all fields in selector by using the `_index` - endpoint. - Queries without an appropriate backing index by default fallback to using the - built-in `_all_docs` index. This isn't recommended because it has a significant - performance impact causing a full scan of the database with each request. In this - case the response body includes a warning field recommending the creation of an - index. - To avoid the fallback behavior set the `allow_fallback` option to `false` and the - server responds with a `400` status code if no suitable index exists. If you want - to use only a specific index for your query set - `allow_fallback` to `false` and set the `use_index` option. + Shows which index is being used by the query. Parameters are the same as the + [`/{db}/_partition/{partition_key}/_find` endpoint](#postpartitionfind-queries). :param str db: Path parameter to specify the database name. + :param str partition_key: Path parameter to specify the database partition + key. :param dict selector: JSON object describing criteria used to select documents. The selector specifies fields in the document, and provides an expression to evaluate with the field content or other data. @@ -5386,26 +5159,22 @@ def post_find( all documents. To change this behavior set `allow_fallback` to `false` and the server responds instead with a `400` status code if the requested index is unsuitable to answer the query. - :param int r: (optional) The read quorum that is needed for the result. The - value defaults to 1, in which case the document that was found in the index - is returned. If set to a higher value, each document is read from at least - that many replicas before it is returned in the results. The request will - take more time than using only the document that is stored locally with the - index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `FindResult` object + :rtype: DetailedResponse with `dict` result representing a `ExplainResult` object """ if not db: raise ValueError('db must be provided') + if not partition_key: + raise ValueError('partition_key must be provided') if selector is None: raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_find', + operation_id='post_partition_explain', ) headers.update(sdk_headers) @@ -5422,7 +5191,6 @@ def post_find( 'stable': stable, 'update': update, 'use_index': use_index, - 'r': r, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -5433,10 +5201,10 @@ def post_find( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_find'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_explain'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -5447,9 +5215,10 @@ def post_find( response = self.send(request, **kwargs) return response - def post_find_as_stream( + def post_partition_find( self, db: str, + partition_key: str, selector: dict, *, allow_fallback: Optional[bool] = None, @@ -5463,26 +5232,30 @@ def post_find_as_stream( stable: Optional[bool] = None, update: Optional[str] = None, use_index: Optional[List[str]] = None, - r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Query an index by using selector syntax as stream. + Query a database partition index by using selector syntax. Query documents by using a declarative JSON querying syntax. It's best practice to create an appropriate index for all fields in selector by using the `_index` endpoint. Queries without an appropriate backing index by default fallback to using the built-in `_all_docs` index. This isn't recommended because it has a significant - performance impact causing a full scan of the database with each request. In this + performance impact causing a full scan of the partition with each request. In this case the response body includes a warning field recommending the creation of an index. To avoid the fallback behavior set the `allow_fallback` option to `false` and the server responds with a `400` status code if no suitable index exists. If you want to use only a specific index for your query set `allow_fallback` to `false` and set the `use_index` option. + Before using read the + [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) + to understand the limitations and appropriate use cases. :param str db: Path parameter to specify the database name. + :param str partition_key: Path parameter to specify the database partition + key. :param dict selector: JSON object describing criteria used to select documents. The selector specifies fields in the document, and provides an expression to evaluate with the field content or other data. @@ -5564,26 +5337,22 @@ def post_find_as_stream( all documents. To change this behavior set `allow_fallback` to `false` and the server responds instead with a `400` status code if the requested index is unsuitable to answer the query. - :param int r: (optional) The read quorum that is needed for the result. The - value defaults to 1, in which case the document that was found in the index - is returned. If set to a higher value, each document is read from at least - that many replicas before it is returned in the results. The request will - take more time than using only the document that is stored locally with the - index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `FindResult` object """ if not db: raise ValueError('db must be provided') + if not partition_key: + raise ValueError('partition_key must be provided') if selector is None: raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_find_as_stream', + operation_id='post_partition_find', ) headers.update(sdk_headers) @@ -5600,7 +5369,6 @@ def post_find_as_stream( 'stable': stable, 'update': update, 'use_index': use_index, - 'r': r, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -5611,10 +5379,10 @@ def post_find_as_stream( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_find'.format(**path_param_dict) + url = '/{db}/_partition/{partition_key}/_find'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -5622,233 +5390,163 @@ def post_find_as_stream( data=data, ) - response = self.send(request, stream=True, **kwargs) - return response - - def get_indexes_information( - self, - db: str, - **kwargs, - ) -> DetailedResponse: - """ - Retrieve information about all indexes. - - When you make a GET request to `/db/_index`, you get a list of all the indexes - using `"language":"query"` in the database and the primary index. In addition to - the information available through this API, the indexes are stored in the - `indexes` property of their respective design documents. - - :param str db: Path parameter to specify the database name. - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `IndexesInformation` object - """ - - if not db: - raise ValueError('db must be provided') - headers = {} - sdk_headers = get_sdk_headers( - service_name=self.DEFAULT_SERVICE_NAME, - service_version='V1', - operation_id='get_indexes_information', - ) - headers.update(sdk_headers) - - if 'headers' in kwargs: - headers.update(kwargs.get('headers')) - del kwargs['headers'] - headers['Accept'] = 'application/json' - - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_index'.format(**path_param_dict) - request = self.prepare_request( - method='GET', - url=url, - headers=headers, - ) - response = self.send(request, **kwargs) return response - def post_index( + def post_partition_find_as_stream( self, db: str, - index: 'IndexDefinition', + partition_key: str, + selector: dict, *, - ddoc: Optional[str] = None, - name: Optional[str] = None, - partitioned: Optional[bool] = None, - type: Optional[str] = None, - **kwargs, - ) -> DetailedResponse: - """ - Create a new index on a database. - - Create a new index on a database. - - :param str db: Path parameter to specify the database name. - :param IndexDefinition index: Schema for a `json` or `text` query index - definition. Indexes of type `text` have additional configuration properties - that do not apply to `json` indexes, these are: - * `default_analyzer` - the default text analyzer to use - * `default_field` - whether to index the text in all document fields and - what analyzer to use for that purpose. - :param str ddoc: (optional) Specifies the design document name in which the - index will be created. The design document name is the design document ID - excluding the `_design/` prefix. - :param str name: (optional) name. - :param bool partitioned: (optional) The default value is `true` for - databases with `partitioned: true` and `false` otherwise. For databases - with `partitioned: false` if this option is specified the value must be - `false`. - :param str type: (optional) Schema for the type of an index. - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `IndexResult` object - """ - - if not db: - raise ValueError('db must be provided') - if index is None: - raise ValueError('index must be provided') - index = convert_model(index) - headers = {} - sdk_headers = get_sdk_headers( - service_name=self.DEFAULT_SERVICE_NAME, - service_version='V1', - operation_id='post_index', - ) - headers.update(sdk_headers) - - data = { - 'index': index, - 'ddoc': ddoc, - 'name': name, - 'partitioned': partitioned, - 'type': type, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - - if 'headers' in kwargs: - headers.update(kwargs.get('headers')) - del kwargs['headers'] - headers['Accept'] = 'application/json' - - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_index'.format(**path_param_dict) - request = self.prepare_request( - method='POST', - url=url, - headers=headers, - data=data, - ) - - response = self.send(request, **kwargs) - return response - - def delete_index( - self, - db: str, - ddoc: str, - type: str, - index: str, + allow_fallback: Optional[bool] = None, + bookmark: Optional[str] = None, + conflicts: Optional[bool] = None, + execution_stats: Optional[bool] = None, + fields: Optional[List[str]] = None, + limit: Optional[int] = None, + skip: Optional[int] = None, + sort: Optional[List[dict]] = None, + stable: Optional[bool] = None, + update: Optional[str] = None, + use_index: Optional[List[str]] = None, **kwargs, ) -> DetailedResponse: """ - Delete an index. + Query a database partition index by using selector syntax as stream. - Delete the index functions from the design document and index files on the server. + Query documents by using a declarative JSON querying syntax. It's best practice to + create an appropriate index for all fields in selector by using the `_index` + endpoint. + Queries without an appropriate backing index by default fallback to using the + built-in `_all_docs` index. This isn't recommended because it has a significant + performance impact causing a full scan of the partition with each request. In this + case the response body includes a warning field recommending the creation of an + index. + To avoid the fallback behavior set the `allow_fallback` option to `false` and the + server responds with a `400` status code if no suitable index exists. If you want + to use only a specific index for your query set + `allow_fallback` to `false` and set the `use_index` option. + Before using read the + [FAQs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-database-partitioning#partition-querying) + to understand the limitations and appropriate use cases. :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str type: Path parameter to specify the index type. - :param str index: Path parameter to specify the index name. + :param str partition_key: Path parameter to specify the database partition + key. + :param dict selector: JSON object describing criteria used to select + documents. The selector specifies fields in the document, and provides an + expression to evaluate with the field content or other data. + The selector object must: + * Be structured as valid JSON. + * Contain a valid query expression. + Using a selector is significantly more efficient than using a JavaScript + filter function, and is the recommended option if filtering on document + attributes only. + Elementary selector syntax requires you to specify one or more fields, and + the corresponding values required for those fields. You can create more + complex selector expressions by combining operators. + Operators are identified by the use of a dollar sign `$` prefix in the name + field. + There are two core types of operators in the selector syntax: + * Combination operators: applied at the topmost level of selection. They + are used to combine selectors. A combination operator takes a single + argument. The argument is either another selector, or an array of + selectors. + * Condition operators: are specific to a field, and are used to evaluate + the value stored in that field. For instance, the basic `$eq` operator + matches when the specified field contains a value that is equal to the + supplied argument. + It is important for query performance to use appropriate selectors: + * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and + `$lte` (but not `$ne`) can be used as the basis of a query. You should + include at least one of these in a selector. + * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be + answered from an index. For query selectors use these operators in + conjunction with equality operators or create and use a partial index to + reduce the number of documents that will need to be scanned. + See [the Cloudant + Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a + list of all available combination and conditional operators. + For further reference see [selector + syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). + :param bool allow_fallback: (optional) Whether to allow fallback to other + indexes. Default is true. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param bool conflicts: (optional) A boolean value that indicates whether or + not to include information about existing conflicts in the document. + :param bool execution_stats: (optional) Use this option to find information + about the query that was run. This information includes total key lookups, + total document lookups (when `include_docs=true` is used), and total quorum + document lookups (when each document replica is fetched). + :param List[str] fields: (optional) JSON array that uses the field syntax. + Use this parameter to specify which fields of a document must be returned. + If it is omitted or empty, the entire document is returned. + :param int limit: (optional) Maximum number of results returned. The `type: + text` indexes are limited to 200 results when queried. + :param int skip: (optional) Skip the first 'n' results, where 'n' is the + value that is specified. + :param List[dict] sort: (optional) The sort field contains a list of pairs, + each mapping a field name to a sort direction (asc or desc). The first + field name and direction pair is the topmost level of sort. The second + pair, if provided, is the next level of sort. The field can be any field, + using dotted notation if desired for sub-document fields. + For example in JSON: + `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` + When sorting with multiple fields, ensure that there is an index already + defined with all the sort fields in the same order and each object in the + sort array has a single key or at least one of the sort fields is included + in the selector. All sorting fields must use the same sort direction, + either all ascending or all descending. + :param bool stable: (optional) Whether or not the view results should be + returned from a "stable" set of shards. + :param str update: (optional) Whether to update the index prior to + returning the result. + :param List[str] use_index: (optional) Use this option to identify a + specific index to answer the query, rather than letting the IBM Cloudant + query planner choose an index. Specified as a two element array of design + document id followed by index name, for example `["my_design_doc", + "my_index"]`. + It’s recommended to specify indexes explicitly in your queries to prevent + existing queries being affected by new indexes that might get added later. + If the specified index doesn't exist or can't answer the query then the + server ignores the value and answers using another index or a full scan of + all documents. To change this behavior set `allow_fallback` to `false` and + the server responds instead with a `400` status code if the requested index + is unsuitable to answer the query. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Ok` object + :rtype: DetailedResponse with `BinaryIO` result """ if not db: raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not type: - raise ValueError('type must be provided') - if not index: - raise ValueError('index must be provided') - headers = {} - sdk_headers = get_sdk_headers( - service_name=self.DEFAULT_SERVICE_NAME, - service_version='V1', - operation_id='delete_index', - ) - headers.update(sdk_headers) - - if 'headers' in kwargs: - headers.update(kwargs.get('headers')) - del kwargs['headers'] - headers['Accept'] = 'application/json' - - path_param_keys = ['db', 'ddoc', 'type', 'index'] - path_param_values = self.encode_path_vars(db, ddoc, type, index) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_index/_design/{ddoc}/{type}/{index}'.format(**path_param_dict) - request = self.prepare_request( - method='DELETE', - url=url, - headers=headers, - ) - - response = self.send(request, **kwargs) - return response - - ######################### - # Searches - ######################### - - def post_search_analyze( - self, - analyzer: str, - text: str, - **kwargs, - ) -> DetailedResponse: - """ - Query tokenization of sample text. - - Returns the results of analyzer tokenization of the provided sample text. This - endpoint can be used for testing analyzer tokenization. - - :param str analyzer: The analyzer type that is being used at the - tokenization. - :param str text: The text to tokenize with the analyzer. - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SearchAnalyzeResult` object - """ - - if analyzer is None: - raise ValueError('analyzer must be provided') - if text is None: - raise ValueError('text must be provided') + if not partition_key: + raise ValueError('partition_key must be provided') + if selector is None: + raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_search_analyze', + operation_id='post_partition_find_as_stream', ) headers.update(sdk_headers) data = { - 'analyzer': analyzer, - 'text': text, + 'selector': selector, + 'allow_fallback': allow_fallback, + 'bookmark': bookmark, + 'conflicts': conflicts, + 'execution_stats': execution_stats, + 'fields': fields, + 'limit': limit, + 'skip': skip, + 'sort': sort, + 'stable': stable, + 'update': update, + 'use_index': use_index, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -5859,7 +5557,10 @@ def post_search_analyze( del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_search_analyze' + path_param_keys = ['db', 'partition_key'] + path_param_values = self.encode_path_vars(db, partition_key) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_partition/{partition_key}/_find'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -5867,154 +5568,157 @@ def post_search_analyze( data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - def post_search( + ######################### + # Queries + ######################### + + def post_explain( self, db: str, - ddoc: str, - index: str, - query: str, + selector: dict, *, + allow_fallback: Optional[bool] = None, bookmark: Optional[str] = None, - highlight_fields: Optional[List[str]] = None, - highlight_number: Optional[int] = None, - highlight_post_tag: Optional[str] = None, - highlight_pre_tag: Optional[str] = None, - highlight_size: Optional[int] = None, - include_docs: Optional[bool] = None, - include_fields: Optional[List[str]] = None, + conflicts: Optional[bool] = None, + execution_stats: Optional[bool] = None, + fields: Optional[List[str]] = None, limit: Optional[int] = None, - sort: Optional[List[str]] = None, - stale: Optional[str] = None, - counts: Optional[List[str]] = None, - drilldown: Optional[List[List[str]]] = None, - group_field: Optional[str] = None, - group_limit: Optional[int] = None, - group_sort: Optional[List[str]] = None, - ranges: Optional[dict] = None, + skip: Optional[int] = None, + sort: Optional[List[dict]] = None, + stable: Optional[bool] = None, + update: Optional[str] = None, + use_index: Optional[List[str]] = None, + r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Query a search index. + Retrieve information about which index is used for a query. - Search indexes, which are defined in design documents, allow databases to be - queried by using Lucene Query Parser Syntax. An index function defines a search - index, similar to a map function in MapReduce views. The index function decides - what data to index and what data to store in the index. The advantage of using the - HTTP `POST` method is that the query is submitted as a JSON object in the request - body. This avoids the limitations of passing query options as URL query parameters - of a `GET` request. + Shows which index is being used by the query. Parameters are the same as the + [`_find` endpoint](#postfind). :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str index: Path parameter to specify the index name. - :param str query: The Lucene query to execute. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param List[str] highlight_fields: (optional) Specifies which fields to - highlight. If specified, the result object contains a highlights field with - an entry for each specified field. - :param int highlight_number: (optional) Number of fragments that are - returned in highlights. If the search term occurs less often than the - number of fragments that are specified, longer fragments are returned. - :param str highlight_post_tag: (optional) A string that is inserted after - the highlighted word in the highlights output. - :param str highlight_pre_tag: (optional) A string that is inserted before - the highlighted word in the highlights output. - :param int highlight_size: (optional) Number of characters in each fragment - for highlights. - :param bool include_docs: (optional) Include the full content of the - documents in the return. - :param List[str] include_fields: (optional) A JSON array of field names to - include in search results. Any fields that are included must be indexed - with the store:true option. The default is all fields. - :param int limit: (optional) Limit the number of the returned documents to - the specified number. - :param List[str] sort: (optional) Specifies the sort order of the results. - In a grouped search (when group_field is used), this parameter specifies - the sort order within a group. The default sort order is relevance. A JSON - string of the form "fieldname<type>" or "-fieldname<type>" for - descending order, where fieldname is the name of a string or number field, - and type is either a number, a string, or a JSON array of strings. The type - part is optional, and defaults to number. Some examples are "foo", "-foo", - "bar<string>", "-foo<number>" and ["-foo<number>", - "bar<string>"]. String fields that are used for sorting must not be - analyzed fields. Fields that are used for sorting must be indexed by the - same indexer that is used for the search query. - :param str stale: (optional) Do not wait for the index to finish building - to return results. - :param List[str] counts: (optional) This field defines an array of names of - string fields, for which counts are requested. The response contains counts - for each unique value of this field name among the documents that match the - search query. Faceting must be enabled for this parameter to function. This - option is only available when making global queries. - :param List[List[str]] drilldown: (optional) Restrict results to documents - with a dimension equal to the specified label(s). The search matches only - documents containing the value that was provided in the named field. It - differs from using "fieldname:value" in the q parameter only in that the - values are not analyzed. Faceting must be enabled for this parameter to - function. - :param str group_field: (optional) Field by which to group search matches. - A string that contains the name of a string field. Fields containing other - data such as numbers, objects, or arrays cannot be used. This option is - only available when making global queries. - :param int group_limit: (optional) Maximum group count. This field can be - used only if group_field is specified. This option is only available when - making global queries. - :param List[str] group_sort: (optional) This field defines the order of the - groups in a search that uses group_field. The default sort order is - relevance. This field can have the same values as the sort field, so single - fields and arrays of fields are supported. This option is only available - when making global queries. - :param dict ranges: (optional) Object mapping faceted, numeric search field - names to the required ranges. Each key is a field name and each value is - another object defining the ranges by mapping range name keys to string - values describing the numeric ranges, for example "[0 TO 10]". This option - is only available when making global queries. + :param dict selector: JSON object describing criteria used to select + documents. The selector specifies fields in the document, and provides an + expression to evaluate with the field content or other data. + The selector object must: + * Be structured as valid JSON. + * Contain a valid query expression. + Using a selector is significantly more efficient than using a JavaScript + filter function, and is the recommended option if filtering on document + attributes only. + Elementary selector syntax requires you to specify one or more fields, and + the corresponding values required for those fields. You can create more + complex selector expressions by combining operators. + Operators are identified by the use of a dollar sign `$` prefix in the name + field. + There are two core types of operators in the selector syntax: + * Combination operators: applied at the topmost level of selection. They + are used to combine selectors. A combination operator takes a single + argument. The argument is either another selector, or an array of + selectors. + * Condition operators: are specific to a field, and are used to evaluate + the value stored in that field. For instance, the basic `$eq` operator + matches when the specified field contains a value that is equal to the + supplied argument. + It is important for query performance to use appropriate selectors: + * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and + `$lte` (but not `$ne`) can be used as the basis of a query. You should + include at least one of these in a selector. + * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be + answered from an index. For query selectors use these operators in + conjunction with equality operators or create and use a partial index to + reduce the number of documents that will need to be scanned. + See [the Cloudant + Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a + list of all available combination and conditional operators. + For further reference see [selector + syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). + :param bool allow_fallback: (optional) Whether to allow fallback to other + indexes. Default is true. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param bool conflicts: (optional) A boolean value that indicates whether or + not to include information about existing conflicts in the document. + :param bool execution_stats: (optional) Use this option to find information + about the query that was run. This information includes total key lookups, + total document lookups (when `include_docs=true` is used), and total quorum + document lookups (when each document replica is fetched). + :param List[str] fields: (optional) JSON array that uses the field syntax. + Use this parameter to specify which fields of a document must be returned. + If it is omitted or empty, the entire document is returned. + :param int limit: (optional) Maximum number of results returned. The `type: + text` indexes are limited to 200 results when queried. + :param int skip: (optional) Skip the first 'n' results, where 'n' is the + value that is specified. + :param List[dict] sort: (optional) The sort field contains a list of pairs, + each mapping a field name to a sort direction (asc or desc). The first + field name and direction pair is the topmost level of sort. The second + pair, if provided, is the next level of sort. The field can be any field, + using dotted notation if desired for sub-document fields. + For example in JSON: + `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` + When sorting with multiple fields, ensure that there is an index already + defined with all the sort fields in the same order and each object in the + sort array has a single key or at least one of the sort fields is included + in the selector. All sorting fields must use the same sort direction, + either all ascending or all descending. + :param bool stable: (optional) Whether or not the view results should be + returned from a "stable" set of shards. + :param str update: (optional) Whether to update the index prior to + returning the result. + :param List[str] use_index: (optional) Use this option to identify a + specific index to answer the query, rather than letting the IBM Cloudant + query planner choose an index. Specified as a two element array of design + document id followed by index name, for example `["my_design_doc", + "my_index"]`. + It’s recommended to specify indexes explicitly in your queries to prevent + existing queries being affected by new indexes that might get added later. + If the specified index doesn't exist or can't answer the query then the + server ignores the value and answers using another index or a full scan of + all documents. To change this behavior set `allow_fallback` to `false` and + the server responds instead with a `400` status code if the requested index + is unsuitable to answer the query. + :param int r: (optional) The read quorum that is needed for the result. The + value defaults to 1, in which case the document that was found in the index + is returned. If set to a higher value, each document is read from at least + that many replicas before it is returned in the results. The request will + take more time than using only the document that is stored locally with the + index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SearchResult` object + :rtype: DetailedResponse with `dict` result representing a `ExplainResult` object """ if not db: raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') - if query is None: - raise ValueError('query must be provided') + if selector is None: + raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_search', + operation_id='post_explain', ) headers.update(sdk_headers) data = { - 'query': query, + 'selector': selector, + 'allow_fallback': allow_fallback, 'bookmark': bookmark, - 'highlight_fields': highlight_fields, - 'highlight_number': highlight_number, - 'highlight_post_tag': highlight_post_tag, - 'highlight_pre_tag': highlight_pre_tag, - 'highlight_size': highlight_size, - 'include_docs': include_docs, - 'include_fields': include_fields, + 'conflicts': conflicts, + 'execution_stats': execution_stats, + 'fields': fields, 'limit': limit, + 'skip': skip, 'sort': sort, - 'stale': stale, - 'counts': counts, - 'drilldown': drilldown, - 'group_field': group_field, - 'group_limit': group_limit, - 'group_sort': group_sort, - 'ranges': ranges, + 'stable': stable, + 'update': update, + 'use_index': use_index, + 'r': r, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -6025,10 +5729,10 @@ def post_search( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, ddoc, index) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) + url = '/{db}/_explain'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -6039,151 +5743,160 @@ def post_search( response = self.send(request, **kwargs) return response - def post_search_as_stream( + def post_find( self, db: str, - ddoc: str, - index: str, - query: str, + selector: dict, *, + allow_fallback: Optional[bool] = None, bookmark: Optional[str] = None, - highlight_fields: Optional[List[str]] = None, - highlight_number: Optional[int] = None, - highlight_post_tag: Optional[str] = None, - highlight_pre_tag: Optional[str] = None, - highlight_size: Optional[int] = None, - include_docs: Optional[bool] = None, - include_fields: Optional[List[str]] = None, + conflicts: Optional[bool] = None, + execution_stats: Optional[bool] = None, + fields: Optional[List[str]] = None, limit: Optional[int] = None, - sort: Optional[List[str]] = None, - stale: Optional[str] = None, - counts: Optional[List[str]] = None, - drilldown: Optional[List[List[str]]] = None, - group_field: Optional[str] = None, - group_limit: Optional[int] = None, - group_sort: Optional[List[str]] = None, - ranges: Optional[dict] = None, + skip: Optional[int] = None, + sort: Optional[List[dict]] = None, + stable: Optional[bool] = None, + update: Optional[str] = None, + use_index: Optional[List[str]] = None, + r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Query a search index as stream. + Query an index by using selector syntax. - Search indexes, which are defined in design documents, allow databases to be - queried by using Lucene Query Parser Syntax. An index function defines a search - index, similar to a map function in MapReduce views. The index function decides - what data to index and what data to store in the index. The advantage of using the - HTTP `POST` method is that the query is submitted as a JSON object in the request - body. This avoids the limitations of passing query options as URL query parameters - of a `GET` request. + Query documents by using a declarative JSON querying syntax. It's best practice to + create an appropriate index for all fields in selector by using the `_index` + endpoint. + Queries without an appropriate backing index by default fallback to using the + built-in `_all_docs` index. This isn't recommended because it has a significant + performance impact causing a full scan of the database with each request. In this + case the response body includes a warning field recommending the creation of an + index. + To avoid the fallback behavior set the `allow_fallback` option to `false` and the + server responds with a `400` status code if no suitable index exists. If you want + to use only a specific index for your query set + `allow_fallback` to `false` and set the `use_index` option. :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str index: Path parameter to specify the index name. - :param str query: The Lucene query to execute. - :param str bookmark: (optional) Opaque bookmark token used when paginating - results. - :param List[str] highlight_fields: (optional) Specifies which fields to - highlight. If specified, the result object contains a highlights field with - an entry for each specified field. - :param int highlight_number: (optional) Number of fragments that are - returned in highlights. If the search term occurs less often than the - number of fragments that are specified, longer fragments are returned. - :param str highlight_post_tag: (optional) A string that is inserted after - the highlighted word in the highlights output. - :param str highlight_pre_tag: (optional) A string that is inserted before - the highlighted word in the highlights output. - :param int highlight_size: (optional) Number of characters in each fragment - for highlights. - :param bool include_docs: (optional) Include the full content of the - documents in the return. - :param List[str] include_fields: (optional) A JSON array of field names to - include in search results. Any fields that are included must be indexed - with the store:true option. The default is all fields. - :param int limit: (optional) Limit the number of the returned documents to - the specified number. - :param List[str] sort: (optional) Specifies the sort order of the results. - In a grouped search (when group_field is used), this parameter specifies - the sort order within a group. The default sort order is relevance. A JSON - string of the form "fieldname<type>" or "-fieldname<type>" for - descending order, where fieldname is the name of a string or number field, - and type is either a number, a string, or a JSON array of strings. The type - part is optional, and defaults to number. Some examples are "foo", "-foo", - "bar<string>", "-foo<number>" and ["-foo<number>", - "bar<string>"]. String fields that are used for sorting must not be - analyzed fields. Fields that are used for sorting must be indexed by the - same indexer that is used for the search query. - :param str stale: (optional) Do not wait for the index to finish building - to return results. - :param List[str] counts: (optional) This field defines an array of names of - string fields, for which counts are requested. The response contains counts - for each unique value of this field name among the documents that match the - search query. Faceting must be enabled for this parameter to function. This - option is only available when making global queries. - :param List[List[str]] drilldown: (optional) Restrict results to documents - with a dimension equal to the specified label(s). The search matches only - documents containing the value that was provided in the named field. It - differs from using "fieldname:value" in the q parameter only in that the - values are not analyzed. Faceting must be enabled for this parameter to - function. - :param str group_field: (optional) Field by which to group search matches. - A string that contains the name of a string field. Fields containing other - data such as numbers, objects, or arrays cannot be used. This option is - only available when making global queries. - :param int group_limit: (optional) Maximum group count. This field can be - used only if group_field is specified. This option is only available when - making global queries. - :param List[str] group_sort: (optional) This field defines the order of the - groups in a search that uses group_field. The default sort order is - relevance. This field can have the same values as the sort field, so single - fields and arrays of fields are supported. This option is only available - when making global queries. - :param dict ranges: (optional) Object mapping faceted, numeric search field - names to the required ranges. Each key is a field name and each value is - another object defining the ranges by mapping range name keys to string - values describing the numeric ranges, for example "[0 TO 10]". This option - is only available when making global queries. + :param dict selector: JSON object describing criteria used to select + documents. The selector specifies fields in the document, and provides an + expression to evaluate with the field content or other data. + The selector object must: + * Be structured as valid JSON. + * Contain a valid query expression. + Using a selector is significantly more efficient than using a JavaScript + filter function, and is the recommended option if filtering on document + attributes only. + Elementary selector syntax requires you to specify one or more fields, and + the corresponding values required for those fields. You can create more + complex selector expressions by combining operators. + Operators are identified by the use of a dollar sign `$` prefix in the name + field. + There are two core types of operators in the selector syntax: + * Combination operators: applied at the topmost level of selection. They + are used to combine selectors. A combination operator takes a single + argument. The argument is either another selector, or an array of + selectors. + * Condition operators: are specific to a field, and are used to evaluate + the value stored in that field. For instance, the basic `$eq` operator + matches when the specified field contains a value that is equal to the + supplied argument. + It is important for query performance to use appropriate selectors: + * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and + `$lte` (but not `$ne`) can be used as the basis of a query. You should + include at least one of these in a selector. + * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be + answered from an index. For query selectors use these operators in + conjunction with equality operators or create and use a partial index to + reduce the number of documents that will need to be scanned. + See [the Cloudant + Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a + list of all available combination and conditional operators. + For further reference see [selector + syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). + :param bool allow_fallback: (optional) Whether to allow fallback to other + indexes. Default is true. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param bool conflicts: (optional) A boolean value that indicates whether or + not to include information about existing conflicts in the document. + :param bool execution_stats: (optional) Use this option to find information + about the query that was run. This information includes total key lookups, + total document lookups (when `include_docs=true` is used), and total quorum + document lookups (when each document replica is fetched). + :param List[str] fields: (optional) JSON array that uses the field syntax. + Use this parameter to specify which fields of a document must be returned. + If it is omitted or empty, the entire document is returned. + :param int limit: (optional) Maximum number of results returned. The `type: + text` indexes are limited to 200 results when queried. + :param int skip: (optional) Skip the first 'n' results, where 'n' is the + value that is specified. + :param List[dict] sort: (optional) The sort field contains a list of pairs, + each mapping a field name to a sort direction (asc or desc). The first + field name and direction pair is the topmost level of sort. The second + pair, if provided, is the next level of sort. The field can be any field, + using dotted notation if desired for sub-document fields. + For example in JSON: + `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` + When sorting with multiple fields, ensure that there is an index already + defined with all the sort fields in the same order and each object in the + sort array has a single key or at least one of the sort fields is included + in the selector. All sorting fields must use the same sort direction, + either all ascending or all descending. + :param bool stable: (optional) Whether or not the view results should be + returned from a "stable" set of shards. + :param str update: (optional) Whether to update the index prior to + returning the result. + :param List[str] use_index: (optional) Use this option to identify a + specific index to answer the query, rather than letting the IBM Cloudant + query planner choose an index. Specified as a two element array of design + document id followed by index name, for example `["my_design_doc", + "my_index"]`. + It’s recommended to specify indexes explicitly in your queries to prevent + existing queries being affected by new indexes that might get added later. + If the specified index doesn't exist or can't answer the query then the + server ignores the value and answers using another index or a full scan of + all documents. To change this behavior set `allow_fallback` to `false` and + the server responds instead with a `400` status code if the requested index + is unsuitable to answer the query. + :param int r: (optional) The read quorum that is needed for the result. The + value defaults to 1, in which case the document that was found in the index + is returned. If set to a higher value, each document is read from at least + that many replicas before it is returned in the results. The request will + take more time than using only the document that is stored locally with the + index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `FindResult` object """ if not db: raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') - if query is None: - raise ValueError('query must be provided') + if selector is None: + raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_search_as_stream', + operation_id='post_find', ) headers.update(sdk_headers) data = { - 'query': query, + 'selector': selector, + 'allow_fallback': allow_fallback, 'bookmark': bookmark, - 'highlight_fields': highlight_fields, - 'highlight_number': highlight_number, - 'highlight_post_tag': highlight_post_tag, - 'highlight_pre_tag': highlight_pre_tag, - 'highlight_size': highlight_size, - 'include_docs': include_docs, - 'include_fields': include_fields, + 'conflicts': conflicts, + 'execution_stats': execution_stats, + 'fields': fields, 'limit': limit, + 'skip': skip, 'sort': sort, - 'stale': stale, - 'counts': counts, - 'drilldown': drilldown, - 'group_field': group_field, - 'group_limit': group_limit, - 'group_sort': group_sort, - 'ranges': ranges, + 'stable': stable, + 'update': update, + 'use_index': use_index, + 'r': r, } data = {k: v for (k, v) in data.items() if v is not None} data = json.dumps(data) @@ -6194,10 +5907,10 @@ def post_search_as_stream( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, ddoc, index) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) + url = '/{db}/_find'.format(**path_param_dict) request = self.prepare_request( method='POST', url=url, @@ -6205,167 +5918,227 @@ def post_search_as_stream( data=data, ) - response = self.send(request, stream=True, **kwargs) - return response - - def get_search_disk_size( - self, - db: str, - ddoc: str, - index: str, - **kwargs, - ) -> DetailedResponse: - """ - Retrieve information about the search index disk size. - - Retrieve size of the search index on disk. - - :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str index: Path parameter to specify the index name. - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SearchDiskSizeInformation` object - """ - - if not db: - raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') - headers = {} - sdk_headers = get_sdk_headers( - service_name=self.DEFAULT_SERVICE_NAME, - service_version='V1', - operation_id='get_search_disk_size', - ) - headers.update(sdk_headers) - - if 'headers' in kwargs: - headers.update(kwargs.get('headers')) - del kwargs['headers'] - headers['Accept'] = 'application/json' - - path_param_keys = ['db', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, ddoc, index) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_search_disk_size/{index}'.format(**path_param_dict) - request = self.prepare_request( - method='GET', - url=url, - headers=headers, - ) - response = self.send(request, **kwargs) return response - def get_search_info( + def post_find_as_stream( self, db: str, - ddoc: str, - index: str, + selector: dict, + *, + allow_fallback: Optional[bool] = None, + bookmark: Optional[str] = None, + conflicts: Optional[bool] = None, + execution_stats: Optional[bool] = None, + fields: Optional[List[str]] = None, + limit: Optional[int] = None, + skip: Optional[int] = None, + sort: Optional[List[dict]] = None, + stable: Optional[bool] = None, + update: Optional[str] = None, + use_index: Optional[List[str]] = None, + r: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve information about a search index. + Query an index by using selector syntax as stream. - Retrieve search index metadata information, such as the size of the index on disk. + Query documents by using a declarative JSON querying syntax. It's best practice to + create an appropriate index for all fields in selector by using the `_index` + endpoint. + Queries without an appropriate backing index by default fallback to using the + built-in `_all_docs` index. This isn't recommended because it has a significant + performance impact causing a full scan of the database with each request. In this + case the response body includes a warning field recommending the creation of an + index. + To avoid the fallback behavior set the `allow_fallback` option to `false` and the + server responds with a `400` status code if no suitable index exists. If you want + to use only a specific index for your query set + `allow_fallback` to `false` and set the `use_index` option. :param str db: Path parameter to specify the database name. - :param str ddoc: Path parameter to specify the design document name. The - design document name is the design document ID excluding the `_design/` - prefix. - :param str index: Path parameter to specify the index name. + :param dict selector: JSON object describing criteria used to select + documents. The selector specifies fields in the document, and provides an + expression to evaluate with the field content or other data. + The selector object must: + * Be structured as valid JSON. + * Contain a valid query expression. + Using a selector is significantly more efficient than using a JavaScript + filter function, and is the recommended option if filtering on document + attributes only. + Elementary selector syntax requires you to specify one or more fields, and + the corresponding values required for those fields. You can create more + complex selector expressions by combining operators. + Operators are identified by the use of a dollar sign `$` prefix in the name + field. + There are two core types of operators in the selector syntax: + * Combination operators: applied at the topmost level of selection. They + are used to combine selectors. A combination operator takes a single + argument. The argument is either another selector, or an array of + selectors. + * Condition operators: are specific to a field, and are used to evaluate + the value stored in that field. For instance, the basic `$eq` operator + matches when the specified field contains a value that is equal to the + supplied argument. + It is important for query performance to use appropriate selectors: + * Only equality operators such as `$eq`, `$gt`, `$gte`, `$lt`, and + `$lte` (but not `$ne`) can be used as the basis of a query. You should + include at least one of these in a selector. + * Some operators such as `$not`, `$or`, `$in`, and `$regex` cannot be + answered from an index. For query selectors use these operators in + conjunction with equality operators or create and use a partial index to + reduce the number of documents that will need to be scanned. + See [the Cloudant + Docs](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-operators) for a + list of all available combination and conditional operators. + For further reference see [selector + syntax](https://cloud.ibm.com/docs/Cloudant?topic=Cloudant-selector-syntax). + :param bool allow_fallback: (optional) Whether to allow fallback to other + indexes. Default is true. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param bool conflicts: (optional) A boolean value that indicates whether or + not to include information about existing conflicts in the document. + :param bool execution_stats: (optional) Use this option to find information + about the query that was run. This information includes total key lookups, + total document lookups (when `include_docs=true` is used), and total quorum + document lookups (when each document replica is fetched). + :param List[str] fields: (optional) JSON array that uses the field syntax. + Use this parameter to specify which fields of a document must be returned. + If it is omitted or empty, the entire document is returned. + :param int limit: (optional) Maximum number of results returned. The `type: + text` indexes are limited to 200 results when queried. + :param int skip: (optional) Skip the first 'n' results, where 'n' is the + value that is specified. + :param List[dict] sort: (optional) The sort field contains a list of pairs, + each mapping a field name to a sort direction (asc or desc). The first + field name and direction pair is the topmost level of sort. The second + pair, if provided, is the next level of sort. The field can be any field, + using dotted notation if desired for sub-document fields. + For example in JSON: + `[{"fieldName1": "desc"}, {"fieldName2.subFieldName1": "desc"}]` + When sorting with multiple fields, ensure that there is an index already + defined with all the sort fields in the same order and each object in the + sort array has a single key or at least one of the sort fields is included + in the selector. All sorting fields must use the same sort direction, + either all ascending or all descending. + :param bool stable: (optional) Whether or not the view results should be + returned from a "stable" set of shards. + :param str update: (optional) Whether to update the index prior to + returning the result. + :param List[str] use_index: (optional) Use this option to identify a + specific index to answer the query, rather than letting the IBM Cloudant + query planner choose an index. Specified as a two element array of design + document id followed by index name, for example `["my_design_doc", + "my_index"]`. + It’s recommended to specify indexes explicitly in your queries to prevent + existing queries being affected by new indexes that might get added later. + If the specified index doesn't exist or can't answer the query then the + server ignores the value and answers using another index or a full scan of + all documents. To change this behavior set `allow_fallback` to `false` and + the server responds instead with a `400` status code if the requested index + is unsuitable to answer the query. + :param int r: (optional) The read quorum that is needed for the result. The + value defaults to 1, in which case the document that was found in the index + is returned. If set to a higher value, each document is read from at least + that many replicas before it is returned in the results. The request will + take more time than using only the document that is stored locally with the + index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SearchInfoResult` object + :rtype: DetailedResponse with `BinaryIO` result """ if not db: raise ValueError('db must be provided') - if not ddoc: - raise ValueError('ddoc must be provided') - if not index: - raise ValueError('index must be provided') + if selector is None: + raise ValueError('selector must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_search_info', + operation_id='post_find_as_stream', ) headers.update(sdk_headers) + data = { + 'selector': selector, + 'allow_fallback': allow_fallback, + 'bookmark': bookmark, + 'conflicts': conflicts, + 'execution_stats': execution_stats, + 'fields': fields, + 'limit': limit, + 'skip': skip, + 'sort': sort, + 'stable': stable, + 'update': update, + 'use_index': use_index, + 'r': r, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'ddoc', 'index'] - path_param_values = self.encode_path_vars(db, ddoc, index) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_design/{ddoc}/_search_info/{index}'.format(**path_param_dict) + url = '/{db}/_find'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='POST', url=url, headers=headers, + data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - ######################### - # Replication - ######################### - - def head_replication_document( + def get_indexes_information( self, - doc_id: str, - *, - if_none_match: Optional[str] = None, + db: str, **kwargs, ) -> DetailedResponse: """ - Retrieve the HTTP headers for a persistent replication. + Retrieve information about all indexes. - Retrieves the HTTP headers containing minimal amount of information about the - specified replication document from the `_replicator` database. The method - supports the same query arguments as the `GET /_replicator/{doc_id}` method, but - only headers like content length and the revision (ETag header) are returned. + When you make a GET request to `/db/_index`, you get a list of all the indexes + using `"language":"query"` in the database and the primary index. In addition to + the information available through this API, the indexes are stored in the + `indexes` property of their respective design documents. - :param str doc_id: Path parameter to specify the ID of the stored - replication configuration in the `_replicator` database. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. + :param str db: Path parameter to specify the database name. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `dict` result representing a `IndexesInformation` object """ - if not doc_id: - raise ValueError('doc_id must be provided') - headers = { - 'If-None-Match': if_none_match, - } + if not db: + raise ValueError('db must be provided') + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_replication_document', + operation_id='get_indexes_information', ) headers.update(sdk_headers) if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['doc_id'] - path_param_values = self.encode_path_vars(doc_id) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_replicator/{doc_id}'.format(**path_param_dict) + url = '/{db}/_index'.format(**path_param_dict) request = self.prepare_request( - method='HEAD', + method='GET', url=url, headers=headers, ) @@ -6373,89 +6146,137 @@ def head_replication_document( response = self.send(request, **kwargs) return response - def head_scheduler_document( + def post_index( self, - doc_id: str, + db: str, + index: 'IndexDefinition', + *, + ddoc: Optional[str] = None, + name: Optional[str] = None, + partitioned: Optional[bool] = None, + type: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve HTTP headers for a replication scheduler document. + Create a new index on a database. - Retrieves the HTTP headers containing minimal amount of information about the - specified replication scheduler document. Since the response body is empty, using - the HEAD method is a lightweight way to check if the replication scheduler - document exists or not. + Create a new index on a database. - :param str doc_id: Path parameter to specify the document ID. + :param str db: Path parameter to specify the database name. + :param IndexDefinition index: Schema for a `json` or `text` query index + definition. Indexes of type `text` have additional configuration properties + that do not apply to `json` indexes, these are: + * `default_analyzer` - the default text analyzer to use + * `default_field` - whether to index the text in all document fields and + what analyzer to use for that purpose. + :param str ddoc: (optional) Specifies the design document name in which the + index will be created. The design document name is the design document ID + excluding the `_design/` prefix. + :param str name: (optional) name. + :param bool partitioned: (optional) The default value is `true` for + databases with `partitioned: true` and `false` otherwise. For databases + with `partitioned: false` if this option is specified the value must be + `false`. + :param str type: (optional) Schema for the type of an index. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `dict` result representing a `IndexResult` object """ - if not doc_id: - raise ValueError('doc_id must be provided') + if not db: + raise ValueError('db must be provided') + if index is None: + raise ValueError('index must be provided') + index = convert_model(index) headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_scheduler_document', + operation_id='post_index', ) headers.update(sdk_headers) + data = { + 'index': index, + 'ddoc': ddoc, + 'name': name, + 'partitioned': partitioned, + 'type': type, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['doc_id'] - path_param_values = self.encode_path_vars(doc_id) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_scheduler/docs/_replicator/{doc_id}'.format(**path_param_dict) + url = '/{db}/_index'.format(**path_param_dict) request = self.prepare_request( - method='HEAD', + method='POST', url=url, headers=headers, + data=data, ) response = self.send(request, **kwargs) return response - def head_scheduler_job( + def delete_index( self, - job_id: str, + db: str, + ddoc: str, + type: str, + index: str, **kwargs, ) -> DetailedResponse: """ - Retrieve the HTTP headers for a replication scheduler job. + Delete an index. - Returns the HTTP headers that contain a minimal amount of information about the - specified replication task. Only the header information is returned. + Delete the index functions from the design document and index files on the server. - :param str job_id: Path parameter to specify the replication job id. + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str type: Path parameter to specify the index type. + :param str index: Path parameter to specify the index name. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `dict` result representing a `Ok` object """ - if not job_id: - raise ValueError('job_id must be provided') + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not type: + raise ValueError('type must be provided') + if not index: + raise ValueError('index must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_scheduler_job', + operation_id='delete_index', ) headers.update(sdk_headers) if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['job_id'] - path_param_values = self.encode_path_vars(job_id) + path_param_keys = ['db', 'ddoc', 'type', 'index'] + path_param_values = self.encode_path_vars(db, ddoc, type, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_scheduler/jobs/{job_id}'.format(**path_param_dict) + url = '/{db}/_index/_design/{ddoc}/{type}/{index}'.format(**path_param_dict) request = self.prepare_request( - method='HEAD', + method='DELETE', url=url, headers=headers, ) @@ -6463,46 +6284,48 @@ def head_scheduler_job( response = self.send(request, **kwargs) return response - def post_replicator( + ######################### + # Searches + ######################### + + def post_search_analyze( self, - replication_document: 'ReplicationDocument', - *, - batch: Optional[str] = None, + analyzer: str, + text: str, **kwargs, ) -> DetailedResponse: """ - Create a persistent replication with a generated ID. + Query tokenization of sample text. - Creates or modifies a document in the `_replicator` database to start a new - replication or to edit an existing replication. + Returns the results of analyzer tokenization of the provided sample text. This + endpoint can be used for testing analyzer tokenization. - :param ReplicationDocument replication_document: HTTP request body for - replication operations. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. + :param str analyzer: The analyzer type that is being used at the + tokenization. + :param str text: The text to tokenize with the analyzer. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `SearchAnalyzeResult` object """ - if replication_document is None: - raise ValueError('replication_document must be provided') - if isinstance(replication_document, ReplicationDocument): - replication_document = convert_model(replication_document) + if analyzer is None: + raise ValueError('analyzer must be provided') + if text is None: + raise ValueError('text must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_replicator', + operation_id='post_search_analyze', ) headers.update(sdk_headers) - params = { - 'batch': batch, + data = { + 'analyzer': analyzer, + 'text': text, } - - data = json.dumps(replication_document) + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) headers['content-type'] = 'application/json' if 'headers' in kwargs: @@ -6510,367 +6333,513 @@ def post_replicator( del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_replicator' + url = '/_search_analyze' request = self.prepare_request( method='POST', url=url, headers=headers, - params=params, data=data, ) response = self.send(request, **kwargs) return response - def delete_replication_document( + def post_search( self, - doc_id: str, + db: str, + ddoc: str, + index: str, + query: str, *, - if_match: Optional[str] = None, - batch: Optional[str] = None, - rev: Optional[str] = None, + bookmark: Optional[str] = None, + highlight_fields: Optional[List[str]] = None, + highlight_number: Optional[int] = None, + highlight_post_tag: Optional[str] = None, + highlight_pre_tag: Optional[str] = None, + highlight_size: Optional[int] = None, + include_docs: Optional[bool] = None, + include_fields: Optional[List[str]] = None, + limit: Optional[int] = None, + sort: Optional[List[str]] = None, + stale: Optional[str] = None, + counts: Optional[List[str]] = None, + drilldown: Optional[List[List[str]]] = None, + group_field: Optional[str] = None, + group_limit: Optional[int] = None, + group_sort: Optional[List[str]] = None, + ranges: Optional[dict] = None, **kwargs, ) -> DetailedResponse: """ - Cancel a persistent replication. + Query a search index. - Cancels a replication by deleting the document that describes it from the - `_replicator` database. + Search indexes, which are defined in design documents, allow databases to be + queried by using Lucene Query Parser Syntax. An index function defines a search + index, similar to a map function in MapReduce views. The index function decides + what data to index and what data to store in the index. The advantage of using the + HTTP `POST` method is that the query is submitted as a JSON object in the request + body. This avoids the limitations of passing query options as URL query parameters + of a `GET` request. - :param str doc_id: Path parameter to specify the ID of the stored - replication configuration in the `_replicator` database. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. - :param str rev: (optional) Query parameter to specify a document revision. + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. + :param str query: The Lucene query to execute. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param List[str] highlight_fields: (optional) Specifies which fields to + highlight. If specified, the result object contains a highlights field with + an entry for each specified field. + :param int highlight_number: (optional) Number of fragments that are + returned in highlights. If the search term occurs less often than the + number of fragments that are specified, longer fragments are returned. + :param str highlight_post_tag: (optional) A string that is inserted after + the highlighted word in the highlights output. + :param str highlight_pre_tag: (optional) A string that is inserted before + the highlighted word in the highlights output. + :param int highlight_size: (optional) Number of characters in each fragment + for highlights. + :param bool include_docs: (optional) Include the full content of the + documents in the return. + :param List[str] include_fields: (optional) A JSON array of field names to + include in search results. Any fields that are included must be indexed + with the store:true option. The default is all fields. + :param int limit: (optional) Limit the number of the returned documents to + the specified number. + :param List[str] sort: (optional) Specifies the sort order of the results. + In a grouped search (when group_field is used), this parameter specifies + the sort order within a group. The default sort order is relevance. A JSON + string of the form "fieldname<type>" or "-fieldname<type>" for + descending order, where fieldname is the name of a string or number field, + and type is either a number, a string, or a JSON array of strings. The type + part is optional, and defaults to number. Some examples are "foo", "-foo", + "bar<string>", "-foo<number>" and ["-foo<number>", + "bar<string>"]. String fields that are used for sorting must not be + analyzed fields. Fields that are used for sorting must be indexed by the + same indexer that is used for the search query. + :param str stale: (optional) Do not wait for the index to finish building + to return results. + :param List[str] counts: (optional) This field defines an array of names of + string fields, for which counts are requested. The response contains counts + for each unique value of this field name among the documents that match the + search query. Faceting must be enabled for this parameter to function. This + option is only available when making global queries. + :param List[List[str]] drilldown: (optional) Restrict results to documents + with a dimension equal to the specified label(s). The search matches only + documents containing the value that was provided in the named field. It + differs from using "fieldname:value" in the q parameter only in that the + values are not analyzed. Faceting must be enabled for this parameter to + function. + :param str group_field: (optional) Field by which to group search matches. + A string that contains the name of a string field. Fields containing other + data such as numbers, objects, or arrays cannot be used. This option is + only available when making global queries. + :param int group_limit: (optional) Maximum group count. This field can be + used only if group_field is specified. This option is only available when + making global queries. + :param List[str] group_sort: (optional) This field defines the order of the + groups in a search that uses group_field. The default sort order is + relevance. This field can have the same values as the sort field, so single + fields and arrays of fields are supported. This option is only available + when making global queries. + :param dict ranges: (optional) Object mapping faceted, numeric search field + names to the required ranges. Each key is a field name and each value is + another object defining the ranges by mapping range name keys to string + values describing the numeric ranges, for example "[0 TO 10]". This option + is only available when making global queries. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `SearchResult` object """ - if not doc_id: - raise ValueError('doc_id must be provided') - headers = { - 'If-Match': if_match, - } + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') + if query is None: + raise ValueError('query must be provided') + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='delete_replication_document', + operation_id='post_search', ) headers.update(sdk_headers) - params = { - 'batch': batch, - 'rev': rev, + data = { + 'query': query, + 'bookmark': bookmark, + 'highlight_fields': highlight_fields, + 'highlight_number': highlight_number, + 'highlight_post_tag': highlight_post_tag, + 'highlight_pre_tag': highlight_pre_tag, + 'highlight_size': highlight_size, + 'include_docs': include_docs, + 'include_fields': include_fields, + 'limit': limit, + 'sort': sort, + 'stale': stale, + 'counts': counts, + 'drilldown': drilldown, + 'group_field': group_field, + 'group_limit': group_limit, + 'group_sort': group_sort, + 'ranges': ranges, } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['doc_id'] - path_param_values = self.encode_path_vars(doc_id) + path_param_keys = ['db', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, ddoc, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_replicator/{doc_id}'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) request = self.prepare_request( - method='DELETE', + method='POST', url=url, headers=headers, - params=params, + data=data, ) response = self.send(request, **kwargs) return response - def get_replication_document( + def post_search_as_stream( self, - doc_id: str, + db: str, + ddoc: str, + index: str, + query: str, *, - if_none_match: Optional[str] = None, - attachments: Optional[bool] = None, - att_encoding_info: Optional[bool] = None, - conflicts: Optional[bool] = None, - deleted_conflicts: Optional[bool] = None, - latest: Optional[bool] = None, - local_seq: Optional[bool] = None, - meta: Optional[bool] = None, - rev: Optional[str] = None, - revs: Optional[bool] = None, - revs_info: Optional[bool] = None, + bookmark: Optional[str] = None, + highlight_fields: Optional[List[str]] = None, + highlight_number: Optional[int] = None, + highlight_post_tag: Optional[str] = None, + highlight_pre_tag: Optional[str] = None, + highlight_size: Optional[int] = None, + include_docs: Optional[bool] = None, + include_fields: Optional[List[str]] = None, + limit: Optional[int] = None, + sort: Optional[List[str]] = None, + stale: Optional[str] = None, + counts: Optional[List[str]] = None, + drilldown: Optional[List[List[str]]] = None, + group_field: Optional[str] = None, + group_limit: Optional[int] = None, + group_sort: Optional[List[str]] = None, + ranges: Optional[dict] = None, **kwargs, ) -> DetailedResponse: - """ - Retrieve the configuration for a persistent replication. - - Retrieves a replication document from the `_replicator` database to view the - configuration of the replication. The status of the replication is no longer - recorded in the document but can be checked via the replication scheduler. - - :param str doc_id: Path parameter to specify the ID of the stored - replication configuration in the `_replicator` database. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. - :param bool attachments: (optional) Query parameter to specify whether to - include attachment content in the response. Note that when used with a - view-style query or changes feed this only applies when requesting - documents in the response. - :param bool att_encoding_info: (optional) Query parameter to specify - whether to include the encoding information for compressed attachments. - Note that when used with a view-style query or changes feed this only - applies when requesting documents in the response. - :param bool conflicts: (optional) Query parameter to specify whether to - include a list of conflicted revisions in each returned document. Note that - when used with a view-style query or changes feed this only applies when - requesting documents in the response. - :param bool deleted_conflicts: (optional) Query parameter to specify - whether to include a list of deleted conflicted revisions in the - `_deleted_conflicts` property of the returned document. - :param bool latest: (optional) Query parameter to specify whether to force - retrieving latest leaf revision, no matter what rev was requested. - :param bool local_seq: (optional) Query parameter to specify whether to - include the last update sequence for the document. - :param bool meta: (optional) Query parameter to specify whether to include - document meta information. Acts the same as specifying all of the - conflicts, deleted_conflicts and open_revs query parameters. - :param str rev: (optional) Query parameter to specify a document revision. - :param bool revs: (optional) Query parameter to specify whether to include - a list of all known document revisions. - :param bool revs_info: (optional) Query parameter to specify whether to - includes detailed information for all known document revisions. + """ + Query a search index as stream. + + Search indexes, which are defined in design documents, allow databases to be + queried by using Lucene Query Parser Syntax. An index function defines a search + index, similar to a map function in MapReduce views. The index function decides + what data to index and what data to store in the index. The advantage of using the + HTTP `POST` method is that the query is submitted as a JSON object in the request + body. This avoids the limitations of passing query options as URL query parameters + of a `GET` request. + + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. + :param str query: The Lucene query to execute. + :param str bookmark: (optional) Opaque bookmark token used when paginating + results. + :param List[str] highlight_fields: (optional) Specifies which fields to + highlight. If specified, the result object contains a highlights field with + an entry for each specified field. + :param int highlight_number: (optional) Number of fragments that are + returned in highlights. If the search term occurs less often than the + number of fragments that are specified, longer fragments are returned. + :param str highlight_post_tag: (optional) A string that is inserted after + the highlighted word in the highlights output. + :param str highlight_pre_tag: (optional) A string that is inserted before + the highlighted word in the highlights output. + :param int highlight_size: (optional) Number of characters in each fragment + for highlights. + :param bool include_docs: (optional) Include the full content of the + documents in the return. + :param List[str] include_fields: (optional) A JSON array of field names to + include in search results. Any fields that are included must be indexed + with the store:true option. The default is all fields. + :param int limit: (optional) Limit the number of the returned documents to + the specified number. + :param List[str] sort: (optional) Specifies the sort order of the results. + In a grouped search (when group_field is used), this parameter specifies + the sort order within a group. The default sort order is relevance. A JSON + string of the form "fieldname<type>" or "-fieldname<type>" for + descending order, where fieldname is the name of a string or number field, + and type is either a number, a string, or a JSON array of strings. The type + part is optional, and defaults to number. Some examples are "foo", "-foo", + "bar<string>", "-foo<number>" and ["-foo<number>", + "bar<string>"]. String fields that are used for sorting must not be + analyzed fields. Fields that are used for sorting must be indexed by the + same indexer that is used for the search query. + :param str stale: (optional) Do not wait for the index to finish building + to return results. + :param List[str] counts: (optional) This field defines an array of names of + string fields, for which counts are requested. The response contains counts + for each unique value of this field name among the documents that match the + search query. Faceting must be enabled for this parameter to function. This + option is only available when making global queries. + :param List[List[str]] drilldown: (optional) Restrict results to documents + with a dimension equal to the specified label(s). The search matches only + documents containing the value that was provided in the named field. It + differs from using "fieldname:value" in the q parameter only in that the + values are not analyzed. Faceting must be enabled for this parameter to + function. + :param str group_field: (optional) Field by which to group search matches. + A string that contains the name of a string field. Fields containing other + data such as numbers, objects, or arrays cannot be used. This option is + only available when making global queries. + :param int group_limit: (optional) Maximum group count. This field can be + used only if group_field is specified. This option is only available when + making global queries. + :param List[str] group_sort: (optional) This field defines the order of the + groups in a search that uses group_field. The default sort order is + relevance. This field can have the same values as the sort field, so single + fields and arrays of fields are supported. This option is only available + when making global queries. + :param dict ranges: (optional) Object mapping faceted, numeric search field + names to the required ranges. Each key is a field name and each value is + another object defining the ranges by mapping range name keys to string + values describing the numeric ranges, for example "[0 TO 10]". This option + is only available when making global queries. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ReplicationDocument` object + :rtype: DetailedResponse with `BinaryIO` result """ - if not doc_id: - raise ValueError('doc_id must be provided') - headers = { - 'If-None-Match': if_none_match, - } + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') + if query is None: + raise ValueError('query must be provided') + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_replication_document', + operation_id='post_search_as_stream', ) headers.update(sdk_headers) - params = { - 'attachments': attachments, - 'att_encoding_info': att_encoding_info, - 'conflicts': conflicts, - 'deleted_conflicts': deleted_conflicts, - 'latest': latest, - 'local_seq': local_seq, - 'meta': meta, - 'rev': rev, - 'revs': revs, - 'revs_info': revs_info, + data = { + 'query': query, + 'bookmark': bookmark, + 'highlight_fields': highlight_fields, + 'highlight_number': highlight_number, + 'highlight_post_tag': highlight_post_tag, + 'highlight_pre_tag': highlight_pre_tag, + 'highlight_size': highlight_size, + 'include_docs': include_docs, + 'include_fields': include_fields, + 'limit': limit, + 'sort': sort, + 'stale': stale, + 'counts': counts, + 'drilldown': drilldown, + 'group_field': group_field, + 'group_limit': group_limit, + 'group_sort': group_sort, + 'ranges': ranges, } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['doc_id'] - path_param_values = self.encode_path_vars(doc_id) + path_param_keys = ['db', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, ddoc, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_replicator/{doc_id}'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_search/{index}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='POST', url=url, headers=headers, - params=params, + data=data, ) - response = self.send(request, **kwargs) + response = self.send(request, stream=True, **kwargs) return response - def put_replication_document( + def get_search_disk_size( self, - doc_id: str, - replication_document: 'ReplicationDocument', - *, - if_match: Optional[str] = None, - batch: Optional[str] = None, - new_edits: Optional[bool] = None, - rev: Optional[str] = None, + db: str, + ddoc: str, + index: str, **kwargs, ) -> DetailedResponse: """ - Create or modify a persistent replication. + Retrieve information about the search index disk size. - Creates or modifies a document in the `_replicator` database to start a new - replication or to edit an existing replication. + Retrieve size of the search index on disk. - :param str doc_id: Path parameter to specify the ID of the stored - replication configuration in the `_replicator` database. - :param ReplicationDocument replication_document: HTTP request body for - replication operations. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. - :param bool new_edits: (optional) Query parameter to specify whether to - prevent insertion of conflicting document revisions. If false, a - well-formed _rev must be included in the document. False is used by the - replicator to insert documents into the target database even if that leads - to the creation of conflicts. - Avoid using this parameter, since this option applies document revisions - without checking for conflicts, so it is very easy to accidentally end up - with a large number of conflicts. - :param str rev: (optional) Query parameter to specify a document revision. + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `SearchDiskSizeInformation` object """ - if not doc_id: - raise ValueError('doc_id must be provided') - if replication_document is None: - raise ValueError('replication_document must be provided') - if isinstance(replication_document, ReplicationDocument): - replication_document = convert_model(replication_document) - headers = { - 'If-Match': if_match, - } + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_replication_document', + operation_id='get_search_disk_size', ) headers.update(sdk_headers) - params = { - 'batch': batch, - 'new_edits': new_edits, - 'rev': rev, - } - - data = json.dumps(replication_document) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['doc_id'] - path_param_values = self.encode_path_vars(doc_id) + path_param_keys = ['db', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, ddoc, index) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_replicator/{doc_id}'.format(**path_param_dict) + url = '/{db}/_design/{ddoc}/_search_disk_size/{index}'.format(**path_param_dict) request = self.prepare_request( - method='PUT', + method='GET', url=url, headers=headers, - params=params, - data=data, ) response = self.send(request, **kwargs) return response - def get_scheduler_docs( + def get_search_info( self, - *, - limit: Optional[int] = None, - skip: Optional[int] = None, - states: Optional[List[str]] = None, + db: str, + ddoc: str, + index: str, **kwargs, ) -> DetailedResponse: """ - Retrieve replication scheduler documents. + Retrieve information about a search index. - Lists replication documents, including information about all documents, even the - ones in a completed or failed state. For each document, the endpoint returns the - document ID, database, replication ID, source and target, and other information. + Retrieve search index metadata information, such as the size of the index on disk. - :param int limit: (optional) Query parameter to specify the number of - returned documents to limit the result to. - :param int skip: (optional) Query parameter to specify the number of - records before starting to return the results. - :param List[str] states: (optional) Query parameter to include only - replication documents in the specified states. String must be a - comma-delimited string. + :param str db: Path parameter to specify the database name. + :param str ddoc: Path parameter to specify the design document name. The + design document name is the design document ID excluding the `_design/` + prefix. + :param str index: Path parameter to specify the index name. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SchedulerDocsResult` object + :rtype: DetailedResponse with `dict` result representing a `SearchInfoResult` object """ + if not db: + raise ValueError('db must be provided') + if not ddoc: + raise ValueError('ddoc must be provided') + if not index: + raise ValueError('index must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_scheduler_docs', + operation_id='get_search_info', ) headers.update(sdk_headers) - params = { - 'limit': limit, - 'skip': skip, - 'states': convert_list(states), - } - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_scheduler/docs' + path_param_keys = ['db', 'ddoc', 'index'] + path_param_values = self.encode_path_vars(db, ddoc, index) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_design/{ddoc}/_search_info/{index}'.format(**path_param_dict) request = self.prepare_request( method='GET', url=url, headers=headers, - params=params, ) response = self.send(request, **kwargs) return response - def get_scheduler_document( + ######################### + # Replication + ######################### + + def head_replication_document( self, doc_id: str, + *, + if_none_match: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve a replication scheduler document. + Retrieve the HTTP headers for a persistent replication. - Retrieves information about a replication document from the replicator database. - The endpoint returns the document ID, database, replication ID, source and target, - and other information. + Retrieves the HTTP headers containing minimal amount of information about the + specified replication document from the `_replicator` database. The method + supports the same query arguments as the `GET /_replicator/{doc_id}` method, but + only headers like content length and the revision (ETag header) are returned. - :param str doc_id: Path parameter to specify the document ID. + :param str doc_id: Path parameter to specify the ID of the stored + replication configuration in the `_replicator` database. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SchedulerDocument` object + :rtype: DetailedResponse """ if not doc_id: raise ValueError('doc_id must be provided') - headers = {} + headers = { + 'If-None-Match': if_none_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_scheduler_document', + operation_id='head_replication_document', ) headers.update(sdk_headers) if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' path_param_keys = ['doc_id'] path_param_values = self.encode_path_vars(doc_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_scheduler/docs/_replicator/{doc_id}'.format(**path_param_dict) + url = '/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='HEAD', url=url, headers=headers, ) @@ -6878,74 +6847,67 @@ def get_scheduler_document( response = self.send(request, **kwargs) return response - def get_scheduler_jobs( + def head_scheduler_document( self, - *, - limit: Optional[int] = None, - skip: Optional[int] = None, + doc_id: str, **kwargs, ) -> DetailedResponse: """ - Retrieve replication scheduler jobs. + Retrieve HTTP headers for a replication scheduler document. - Retrieves information about replications that were created via `/_replicate` - endpoint, as well as those created from replication documents. It doesn't include - replications that completed or failed to start because replication documents were - malformed. Each job description includes source and target information, - replication ID, history of recent events, and other information. + Retrieves the HTTP headers containing minimal amount of information about the + specified replication scheduler document. Since the response body is empty, using + the HEAD method is a lightweight way to check if the replication scheduler + document exists or not. - :param int limit: (optional) Query parameter to specify the number of - returned jobs to limit the result to. - :param int skip: (optional) Query parameter to specify the number of - records before starting to return the results. + :param str doc_id: Path parameter to specify the document ID. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SchedulerJobsResult` object + :rtype: DetailedResponse """ + if not doc_id: + raise ValueError('doc_id must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_scheduler_jobs', + operation_id='head_scheduler_document', ) headers.update(sdk_headers) - params = { - 'limit': limit, - 'skip': skip, - } - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' - url = '/_scheduler/jobs' + path_param_keys = ['doc_id'] + path_param_values = self.encode_path_vars(doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/_scheduler/docs/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='HEAD', url=url, headers=headers, - params=params, ) response = self.send(request, **kwargs) return response - def get_scheduler_job( + def head_scheduler_job( self, job_id: str, **kwargs, ) -> DetailedResponse: """ - Retrieve a replication scheduler job. + Retrieve the HTTP headers for a replication scheduler job. - Retrieves the state of a single replication task based on its replication ID. + Returns the HTTP headers that contain a minimal amount of information about the + specified replication task. Only the header information is returned. :param str job_id: Path parameter to specify the replication job id. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SchedulerJob` object + :rtype: DetailedResponse """ if not job_id: @@ -6954,21 +6916,20 @@ def get_scheduler_job( sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_scheduler_job', + operation_id='head_scheduler_job', ) headers.update(sdk_headers) if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' path_param_keys = ['job_id'] path_param_values = self.encode_path_vars(job_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) url = '/_scheduler/jobs/{job_id}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='HEAD', url=url, headers=headers, ) @@ -6976,280 +6937,296 @@ def get_scheduler_job( response = self.send(request, **kwargs) return response - ######################### - # Authentication - ######################### - - def get_session_information( + def post_replicator( self, + replication_document: 'ReplicationDocument', + *, + batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve current session cookie information. + Create a persistent replication with a generated ID. - Retrieves information about the authenticated user's session. + Creates or modifies a document in the `_replicator` database to start a new + replication or to edit an existing replication. + :param ReplicationDocument replication_document: HTTP request body for + replication operations. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `SessionInformation` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ + if replication_document is None: + raise ValueError('replication_document must be provided') + if isinstance(replication_document, ReplicationDocument): + replication_document = convert_model(replication_document) headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_session_information', + operation_id='post_replicator', ) headers.update(sdk_headers) - if 'headers' in kwargs: - headers.update(kwargs.get('headers')) - del kwargs['headers'] - headers['Accept'] = 'application/json' - - url = '/_session' - request = self.prepare_request( - method='GET', - url=url, - headers=headers, - ) - - response = self.send(request, **kwargs) - return response - - ######################### - # Authorization - ######################### - - def post_api_keys( - self, - **kwargs, - ) -> DetailedResponse: - """ - Generates API keys for apps or persons to enable database access. - - Generates API keys to enable database access for a person or application, but - without creating a new IBM Cloudant account for that person or application. An API - key is a randomly generated username and password. The key is given the wanted - access permissions for a database. - - :param dict headers: A `dict` containing the request headers - :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ApiKeysResult` object - """ + params = { + 'batch': batch, + } - headers = {} - sdk_headers = get_sdk_headers( - service_name=self.DEFAULT_SERVICE_NAME, - service_version='V1', - operation_id='post_api_keys', - ) - headers.update(sdk_headers) + data = json.dumps(replication_document) + headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/api_keys' + url = '/_replicator' request = self.prepare_request( method='POST', url=url, headers=headers, + params=params, + data=data, ) response = self.send(request, **kwargs) return response - def put_cloudant_security_configuration( + def delete_replication_document( self, - db: str, - cloudant: dict, + doc_id: str, *, - admins: Optional['SecurityObject'] = None, - couchdb_auth_only: Optional[bool] = None, - members: Optional['SecurityObject'] = None, + if_match: Optional[str] = None, + batch: Optional[str] = None, + rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Modify only Cloudant related database permissions. + Cancel a persistent replication. - Modify only Cloudant related permissions to database. Be careful: by removing an - API key from the list, you remove the API key from the list of users that have - access to the database. - ### Note about nobody role - The `nobody` username applies to all unauthenticated connection attempts. For - example, if an application tries to read data from a database, but did not - identify itself, the task can continue only if the `nobody` user has the role - `_reader`. + Cancels a replication by deleting the document that describes it from the + `_replicator` database. - :param str db: Path parameter to specify the database name. - :param dict cloudant: Database permissions for Cloudant users, API keys or - both. - :param SecurityObject admins: (optional) Schema for names and roles to map - to a database permission. - :param bool couchdb_auth_only: (optional) Manage permissions using the - `_users` database only. - :param SecurityObject members: (optional) Schema for names and roles to map - to a database permission. + :param str doc_id: Path parameter to specify the ID of the stored + replication configuration in the `_replicator` database. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. + :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Ok` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ - if not db: - raise ValueError('db must be provided') - if cloudant is None: - raise ValueError('cloudant must be provided') - if admins is not None: - admins = convert_model(admins) - if members is not None: - members = convert_model(members) - headers = {} + if not doc_id: + raise ValueError('doc_id must be provided') + headers = { + 'If-Match': if_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_cloudant_security_configuration', + operation_id='delete_replication_document', ) headers.update(sdk_headers) - data = { - 'cloudant': cloudant, - 'admins': admins, - 'couchdb_auth_only': couchdb_auth_only, - 'members': members, + params = { + 'batch': batch, + 'rev': rev, } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['doc_id'] + path_param_values = self.encode_path_vars(doc_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/_api/v2/db/{db}/_security'.format(**path_param_dict) + url = '/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='PUT', + method='DELETE', url=url, headers=headers, - data=data, + params=params, ) response = self.send(request, **kwargs) return response - def get_security( + def get_replication_document( self, - db: str, + doc_id: str, + *, + if_none_match: Optional[str] = None, + attachments: Optional[bool] = None, + att_encoding_info: Optional[bool] = None, + conflicts: Optional[bool] = None, + deleted_conflicts: Optional[bool] = None, + latest: Optional[bool] = None, + local_seq: Optional[bool] = None, + meta: Optional[bool] = None, + rev: Optional[str] = None, + revs: Optional[bool] = None, + revs_info: Optional[bool] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve database permissions information. + Retrieve the configuration for a persistent replication. - See who has permission to read, write, and manage the database. The credentials - you use to log in to the dashboard automatically include `_admin` permissions to - all databases you create. Everyone and everything else, including users you share - databases with and API keys you create, must be given a permission level - explicitly. + Retrieves a replication document from the `_replicator` database to view the + configuration of the replication. The status of the replication is no longer + recorded in the document but can be checked via the replication scheduler. - :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the ID of the stored + replication configuration in the `_replicator` database. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. + :param bool attachments: (optional) Query parameter to specify whether to + include attachment content in the response. Note that when used with a + view-style query or changes feed this only applies when requesting + documents in the response. + :param bool att_encoding_info: (optional) Query parameter to specify + whether to include the encoding information for compressed attachments. + Note that when used with a view-style query or changes feed this only + applies when requesting documents in the response. + :param bool conflicts: (optional) Query parameter to specify whether to + include a list of conflicted revisions in each returned document. Note that + when used with a view-style query or changes feed this only applies when + requesting documents in the response. + :param bool deleted_conflicts: (optional) Query parameter to specify + whether to include a list of deleted conflicted revisions in the + `_deleted_conflicts` property of the returned document. + :param bool latest: (optional) Query parameter to specify whether to force + retrieving latest leaf revision, no matter what rev was requested. + :param bool local_seq: (optional) Query parameter to specify whether to + include the last update sequence for the document. + :param bool meta: (optional) Query parameter to specify whether to include + document meta information. Acts the same as specifying all of the + conflicts, deleted_conflicts and open_revs query parameters. + :param str rev: (optional) Query parameter to specify a document revision. + :param bool revs: (optional) Query parameter to specify whether to include + a list of all known document revisions. + :param bool revs_info: (optional) Query parameter to specify whether to + includes detailed information for all known document revisions. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Security` object + :rtype: DetailedResponse with `dict` result representing a `ReplicationDocument` object """ - if not db: - raise ValueError('db must be provided') - headers = {} + if not doc_id: + raise ValueError('doc_id must be provided') + headers = { + 'If-None-Match': if_none_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_security', + operation_id='get_replication_document', ) headers.update(sdk_headers) + params = { + 'attachments': attachments, + 'att_encoding_info': att_encoding_info, + 'conflicts': conflicts, + 'deleted_conflicts': deleted_conflicts, + 'latest': latest, + 'local_seq': local_seq, + 'meta': meta, + 'rev': rev, + 'revs': revs, + 'revs_info': revs_info, + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['doc_id'] + path_param_values = self.encode_path_vars(doc_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_security'.format(**path_param_dict) + url = '/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( method='GET', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - def put_security( + def put_replication_document( self, - db: str, + doc_id: str, + replication_document: 'ReplicationDocument', *, - admins: Optional['SecurityObject'] = None, - cloudant: Optional[dict] = None, - couchdb_auth_only: Optional[bool] = None, - members: Optional['SecurityObject'] = None, + if_match: Optional[str] = None, + batch: Optional[str] = None, + new_edits: Optional[bool] = None, + rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Modify database permissions. + Create or modify a persistent replication. - Modify who has permission to read, write, or manage a database. This endpoint can - be used to modify both Cloudant and CouchDB related permissions. Be careful: by - removing a Cloudant API key, a member or an admin from the list of users that have - access permissions, you remove it from the list of users that have access to the - database. - ### Note about nobody role - The `nobody` username applies to all unauthenticated connection attempts. For - example, if an application tries to read data from a database, but did not - identify itself, the task can continue only if the `nobody` user has the role - `_reader`. + Creates or modifies a document in the `_replicator` database to start a new + replication or to edit an existing replication. - :param str db: Path parameter to specify the database name. - :param SecurityObject admins: (optional) Schema for names and roles to map - to a database permission. - :param dict cloudant: (optional) Database permissions for Cloudant users, - API keys or both. - :param bool couchdb_auth_only: (optional) Manage permissions using the - `_users` database only. - :param SecurityObject members: (optional) Schema for names and roles to map - to a database permission. + :param str doc_id: Path parameter to specify the ID of the stored + replication configuration in the `_replicator` database. + :param ReplicationDocument replication_document: HTTP request body for + replication operations. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. + :param bool new_edits: (optional) Query parameter to specify whether to + prevent insertion of conflicting document revisions. If false, a + well-formed _rev must be included in the document. False is used by the + replicator to insert documents into the target database even if that leads + to the creation of conflicts. + Avoid using this parameter, since this option applies document revisions + without checking for conflicts, so it is very easy to accidentally end up + with a large number of conflicts. + :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Ok` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ - if not db: - raise ValueError('db must be provided') - if admins is not None: - admins = convert_model(admins) - if members is not None: - members = convert_model(members) - headers = {} + if not doc_id: + raise ValueError('doc_id must be provided') + if replication_document is None: + raise ValueError('replication_document must be provided') + if isinstance(replication_document, ReplicationDocument): + replication_document = convert_model(replication_document) + headers = { + 'If-Match': if_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_security', + operation_id='put_replication_document', ) headers.update(sdk_headers) - data = { - 'admins': admins, - 'cloudant': cloudant, - 'couchdb_auth_only': couchdb_auth_only, - 'members': members, + params = { + 'batch': batch, + 'new_edits': new_edits, + 'rev': rev, } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) + + data = json.dumps(replication_document) headers['content-type'] = 'application/json' if 'headers' in kwargs: @@ -7257,192 +7234,170 @@ def put_security( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['doc_id'] + path_param_values = self.encode_path_vars(doc_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_security'.format(**path_param_dict) + url = '/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( method='PUT', url=url, headers=headers, + params=params, data=data, ) response = self.send(request, **kwargs) return response - ######################### - # CORS - ######################### - - def get_cors_information( + def get_scheduler_docs( self, + *, + limit: Optional[int] = None, + skip: Optional[int] = None, + states: Optional[List[str]] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve CORS configuration information. + Retrieve replication scheduler documents. - Lists all Cross-origin resource sharing (CORS) configuration. CORS defines a way - in which the browser and the server interact to determine whether or not to allow - the request. + Lists replication documents, including information about all documents, even the + ones in a completed or failed state. For each document, the endpoint returns the + document ID, database, replication ID, source and target, and other information. + :param int limit: (optional) Query parameter to specify the number of + returned documents to limit the result to. + :param int skip: (optional) Query parameter to specify the number of + records before starting to return the results. + :param List[str] states: (optional) Query parameter to include only + replication documents in the specified states. String must be a + comma-delimited string. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `CorsInformation` object + :rtype: DetailedResponse with `dict` result representing a `SchedulerDocsResult` object """ headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_cors_information', + operation_id='get_scheduler_docs', ) headers.update(sdk_headers) + params = { + 'limit': limit, + 'skip': skip, + 'states': convert_list(states), + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/user/config/cors' + url = '/_scheduler/docs' request = self.prepare_request( method='GET', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - def put_cors_configuration( + def get_scheduler_document( self, - origins: List[str], - *, - allow_credentials: Optional[bool] = None, - enable_cors: Optional[bool] = None, + doc_id: str, **kwargs, ) -> DetailedResponse: """ - Modify CORS configuration. + Retrieve a replication scheduler document. - Sets the CORS configuration. The configuration applies to all databases and all - account level endpoints in your account. + Retrieves information about a replication document from the replicator database. + The endpoint returns the document ID, database, replication ID, source and target, + and other information. - :param List[str] origins: An array of strings that contain allowed origin - domains. You have to specify the full URL including the protocol. It is - recommended that only the HTTPS protocol is used. Subdomains count as - separate domains, so you have to specify all subdomains used. - :param bool allow_credentials: (optional) Boolean value to allow - authentication credentials. If set to true, browser requests must be done - by using withCredentials = true. - :param bool enable_cors: (optional) Boolean value to turn CORS on and off. + :param str doc_id: Path parameter to specify the document ID. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Ok` object + :rtype: DetailedResponse with `dict` result representing a `SchedulerDocument` object """ - - if origins is None: - raise ValueError('origins must be provided') + + if not doc_id: + raise ValueError('doc_id must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_cors_configuration', + operation_id='get_scheduler_document', ) headers.update(sdk_headers) - data = { - 'origins': origins, - 'allow_credentials': allow_credentials, - 'enable_cors': enable_cors, - } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/user/config/cors' + path_param_keys = ['doc_id'] + path_param_values = self.encode_path_vars(doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/_scheduler/docs/_replicator/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='PUT', + method='GET', url=url, headers=headers, - data=data, ) response = self.send(request, **kwargs) return response - ######################### - # Attachments - ######################### - - def head_attachment( + def get_scheduler_jobs( self, - db: str, - doc_id: str, - attachment_name: str, *, - if_match: Optional[str] = None, - if_none_match: Optional[str] = None, - rev: Optional[str] = None, + limit: Optional[int] = None, + skip: Optional[int] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve the HTTP headers for an attachment. + Retrieve replication scheduler jobs. - Returns the HTTP headers that contain a minimal amount of information about the - specified attachment. This method supports the same query arguments as the `GET - /{db}/{doc_id}/{attachment_name}` method, but only the header information - (including attachment size, encoding, and the MD5 hash as an ETag), is returned. + Retrieves information about replications that were created via `/_replicate` + endpoint, as well as those created from replication documents. It doesn't include + replications that completed or failed to start because replication documents were + malformed. Each job description includes source and target information, + replication ID, history of recent events, and other information. - :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str attachment_name: Path parameter to specify the attachment name. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. - :param str rev: (optional) Query parameter to specify a document revision. + :param int limit: (optional) Query parameter to specify the number of + returned jobs to limit the result to. + :param int skip: (optional) Query parameter to specify the number of + records before starting to return the results. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `dict` result representing a `SchedulerJobsResult` object """ - if not db: - raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - if not attachment_name: - raise ValueError('attachment_name must be provided') - headers = { - 'If-Match': if_match, - 'If-None-Match': if_none_match, - } + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_attachment', + operation_id='get_scheduler_jobs', ) headers.update(sdk_headers) params = { - 'rev': rev, + 'limit': limit, + 'skip': skip, } if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id', 'attachment_name'] - path_param_values = self.encode_path_vars(db, doc_id, attachment_name) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) + url = '/_scheduler/jobs' request = self.prepare_request( - method='HEAD', + method='GET', url=url, headers=headers, params=params, @@ -7451,556 +7406,432 @@ def head_attachment( response = self.send(request, **kwargs) return response - def delete_attachment( + def get_scheduler_job( self, - db: str, - doc_id: str, - attachment_name: str, - *, - if_match: Optional[str] = None, - rev: Optional[str] = None, - batch: Optional[str] = None, + job_id: str, **kwargs, ) -> DetailedResponse: """ - Delete an attachment. + Retrieve a replication scheduler job. - Deletes the attachment with the filename, `{attachment_name}`, from the specified - doc. You must supply the `rev` query parameter or `If-Match` header with the - current revision to delete the attachment. + Retrieves the state of a single replication task based on its replication ID. - :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str attachment_name: Path parameter to specify the attachment name. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str rev: (optional) Query parameter to specify a document revision. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. + :param str job_id: Path parameter to specify the replication job id. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `SchedulerJob` object """ - if not db: - raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - if not attachment_name: - raise ValueError('attachment_name must be provided') - headers = { - 'If-Match': if_match, - } + if not job_id: + raise ValueError('job_id must be provided') + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='delete_attachment', + operation_id='get_scheduler_job', ) headers.update(sdk_headers) - params = { - 'rev': rev, - 'batch': batch, - } - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id', 'attachment_name'] - path_param_values = self.encode_path_vars(db, doc_id, attachment_name) + path_param_keys = ['job_id'] + path_param_values = self.encode_path_vars(job_id) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) + url = '/_scheduler/jobs/{job_id}'.format(**path_param_dict) request = self.prepare_request( - method='DELETE', + method='GET', url=url, headers=headers, - params=params, ) response = self.send(request, **kwargs) return response - def get_attachment( + ######################### + # Authentication + ######################### + + def get_session_information( self, - db: str, - doc_id: str, - attachment_name: str, - *, - if_match: Optional[str] = None, - if_none_match: Optional[str] = None, - range: Optional[str] = None, - rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve an attachment. + Retrieve current session cookie information. - Returns the file attachment that is associated with the document. The raw data of - the associated attachment is returned, just as if you were accessing a static - file. The returned Content-Type header is the same as the content type set when - the document attachment was submitted to the database. + Retrieves information about the authenticated user's session. - :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str attachment_name: Path parameter to specify the attachment name. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. - :param str range: (optional) Header parameter to specify the byte range for - a request. This allows the implementation of resumable downloads and - skippable streams. This is available for all attachments inside CouchDB. - :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `BinaryIO` result + :rtype: DetailedResponse with `dict` result representing a `SessionInformation` object """ - if not db: - raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - if not attachment_name: - raise ValueError('attachment_name must be provided') - headers = { - 'If-Match': if_match, - 'If-None-Match': if_none_match, - 'Range': range, - } + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_attachment', + operation_id='get_session_information', ) headers.update(sdk_headers) - params = { - 'rev': rev, - } - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = '*/*' + headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id', 'attachment_name'] - path_param_values = self.encode_path_vars(db, doc_id, attachment_name) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) + url = '/_session' request = self.prepare_request( method='GET', url=url, headers=headers, - params=params, ) response = self.send(request, **kwargs) return response - def put_attachment( + ######################### + # Authorization + ######################### + + def post_api_keys( self, - db: str, - doc_id: str, - attachment_name: str, - attachment: BinaryIO, - content_type: str, - *, - if_match: Optional[str] = None, - rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Create or modify an attachment. + Generates API keys for apps or persons to enable database access. - Uploads the supplied content as an attachment to the specified document. The - attachment name that you provide must be a URL encoded string. You must supply the - Content-Type header, and for an existing document, you must also supply either the - `rev` query argument or the `If-Match` HTTP header. If you omit the revision, a - new, otherwise empty, document is created with the provided attachment, or a - conflict occurs. If the uploaded attachment uses an existing attachment name in - the remote database, it updates the corresponding stored content of the database. - Since you must supply the revision information to add an attachment to the - document, this serves as validation to update the existing attachment. + Generates API keys to enable database access for a person or application, but + without creating a new IBM Cloudant account for that person or application. An API + key is a randomly generated username and password. The key is given the wanted + access permissions for a database. - :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str attachment_name: Path parameter to specify the attachment name. - :param BinaryIO attachment: HTTP request body for attachment operations. - :param str content_type: Content-Type of the attachment. - :param str if_match: (optional) Header parameter for a conditional HTTP - request matching an ETag. - :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `ApiKeysResult` object """ - if not db: - raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - if not attachment_name: - raise ValueError('attachment_name must be provided') - if attachment is None: - raise ValueError('attachment must be provided') - if not content_type: - raise ValueError('content_type must be provided') - headers = { - 'Content-Type': content_type, - 'If-Match': if_match, - } + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_attachment', + operation_id='post_api_keys', ) headers.update(sdk_headers) - params = { - 'rev': rev, - } - - data = attachment - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id', 'attachment_name'] - path_param_values = self.encode_path_vars(db, doc_id, attachment_name) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) + url = '/_api/v2/api_keys' request = self.prepare_request( - method='PUT', + method='POST', url=url, headers=headers, - params=params, - data=data, ) response = self.send(request, **kwargs) return response - ######################### - # Local Documents - ######################### - - def head_local_document( + def put_cloudant_security_configuration( self, db: str, - doc_id: str, + cloudant: dict, *, - if_none_match: Optional[str] = None, + admins: Optional['SecurityObject'] = None, + couchdb_auth_only: Optional[bool] = None, + members: Optional['SecurityObject'] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve HTTP headers for a local document. + Modify only Cloudant related database permissions. - Retrieves the HTTP headers containing minimal amount of information about the - specified local document. Since the response body is empty, using the HEAD method - is a lightweight way to check if the local document exists or not. + Modify only Cloudant related permissions to database. Be careful: by removing an + API key from the list, you remove the API key from the list of users that have + access to the database. + ### Note about nobody role + The `nobody` username applies to all unauthenticated connection attempts. For + example, if an application tries to read data from a database, but did not + identify itself, the task can continue only if the `nobody` user has the role + `_reader`. :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. + :param dict cloudant: Database permissions for Cloudant users, API keys or + both. + :param SecurityObject admins: (optional) Schema for names and roles to map + to a database permission. + :param bool couchdb_auth_only: (optional) Manage permissions using the + `_users` database only. + :param SecurityObject members: (optional) Schema for names and roles to map + to a database permission. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `dict` result representing a `Ok` object """ if not db: raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - headers = { - 'If-None-Match': if_none_match, - } + if cloudant is None: + raise ValueError('cloudant must be provided') + if admins is not None: + admins = convert_model(admins) + if members is not None: + members = convert_model(members) + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_local_document', + operation_id='put_cloudant_security_configuration', ) headers.update(sdk_headers) + data = { + 'cloudant': cloudant, + 'admins': admins, + 'couchdb_auth_only': couchdb_auth_only, + 'members': members, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id'] - path_param_values = self.encode_path_vars(db, doc_id) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_local/{doc_id}'.format(**path_param_dict) + url = '/_api/v2/db/{db}/_security'.format(**path_param_dict) request = self.prepare_request( - method='HEAD', + method='PUT', url=url, headers=headers, + data=data, ) response = self.send(request, **kwargs) return response - def delete_local_document( + def get_security( self, db: str, - doc_id: str, - *, - batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Delete a local document. + Retrieve database permissions information. - Deletes the specified local document. The semantics are identical to deleting a - standard document in the specified database, except that the document is not - replicated. + See who has permission to read, write, and manage the database. The credentials + you use to log in to the dashboard automatically include `_admin` permissions to + all databases you create. Everyone and everything else, including users you share + databases with and API keys you create, must be given a permission level + explicitly. :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `Security` object """ if not db: raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='delete_local_document', + operation_id='get_security', ) headers.update(sdk_headers) - params = { - 'batch': batch, - } - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id'] - path_param_values = self.encode_path_vars(db, doc_id) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_local/{doc_id}'.format(**path_param_dict) + url = '/{db}/_security'.format(**path_param_dict) request = self.prepare_request( - method='DELETE', + method='GET', url=url, headers=headers, - params=params, ) response = self.send(request, **kwargs) return response - def get_local_document( + def put_security( self, db: str, - doc_id: str, *, - accept: Optional[str] = None, - if_none_match: Optional[str] = None, - attachments: Optional[bool] = None, - att_encoding_info: Optional[bool] = None, - local_seq: Optional[bool] = None, + admins: Optional['SecurityObject'] = None, + cloudant: Optional[dict] = None, + couchdb_auth_only: Optional[bool] = None, + members: Optional['SecurityObject'] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve a local document. + Modify database permissions. - Retrieves the specified local document. The semantics are identical to accessing a - standard document in the specified database, except that the document is not - replicated. + Modify who has permission to read, write, or manage a database. This endpoint can + be used to modify both Cloudant and CouchDB related permissions. Be careful: by + removing a Cloudant API key, a member or an admin from the list of users that have + access permissions, you remove it from the list of users that have access to the + database. + ### Note about nobody role + The `nobody` username applies to all unauthenticated connection attempts. For + example, if an application tries to read data from a database, but did not + identify itself, the task can continue only if the `nobody` user has the role + `_reader`. :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param str accept: (optional) The type of the response: application/json, - multipart/mixed, multipart/related, or application/octet-stream. - :param str if_none_match: (optional) Header parameter for a conditional - HTTP request not matching an ETag. - :param bool attachments: (optional) Query parameter to specify whether to - include attachment content in the response. Note that when used with a - view-style query or changes feed this only applies when requesting - documents in the response. - :param bool att_encoding_info: (optional) Query parameter to specify - whether to include the encoding information for compressed attachments. - Note that when used with a view-style query or changes feed this only - applies when requesting documents in the response. - :param bool local_seq: (optional) Query parameter to specify whether to - include the last update sequence for the document. + :param SecurityObject admins: (optional) Schema for names and roles to map + to a database permission. + :param dict cloudant: (optional) Database permissions for Cloudant users, + API keys or both. + :param bool couchdb_auth_only: (optional) Manage permissions using the + `_users` database only. + :param SecurityObject members: (optional) Schema for names and roles to map + to a database permission. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Document` object + :rtype: DetailedResponse with `dict` result representing a `Ok` object """ if not db: raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - headers = { - 'Accept': accept, - 'If-None-Match': if_none_match, - } + if admins is not None: + admins = convert_model(admins) + if members is not None: + members = convert_model(members) + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_local_document', + operation_id='put_security', ) headers.update(sdk_headers) - params = { - 'attachments': attachments, - 'att_encoding_info': att_encoding_info, - 'local_seq': local_seq, + data = { + 'admins': admins, + 'cloudant': cloudant, + 'couchdb_auth_only': couchdb_auth_only, + 'members': members, } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) + headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id'] - path_param_values = self.encode_path_vars(db, doc_id) + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_local/{doc_id}'.format(**path_param_dict) + url = '/{db}/_security'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='PUT', url=url, headers=headers, - params=params, + data=data, ) response = self.send(request, **kwargs) return response - def put_local_document( + ######################### + # CORS + ######################### + + def get_cors_information( self, - db: str, - doc_id: str, - document: Union['Document', BinaryIO], - *, - content_type: Optional[str] = None, - batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Create or modify a local document. + Retrieve CORS configuration information. - Stores the specified local document. The semantics are identical to storing a - standard document in the specified database, except that the document is not - replicated. + Lists all Cross-origin resource sharing (CORS) configuration. CORS defines a way + in which the browser and the server interact to determine whether or not to allow + the request. - :param str db: Path parameter to specify the database name. - :param str doc_id: Path parameter to specify the document ID. - :param Document document: HTTP request body for Document operations. - :param str content_type: (optional) The type of the input. - :param str batch: (optional) Query parameter to specify whether to store in - batch mode. The server will respond with a HTTP 202 Accepted response code - immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object + :rtype: DetailedResponse with `dict` result representing a `CorsInformation` object """ - - if not db: - raise ValueError('db must be provided') - if not doc_id: - raise ValueError('doc_id must be provided') - if document is None: - raise ValueError('document must be provided') - if isinstance(document, Document): - document = convert_model(document) - content_type = content_type or 'application/json' - headers = { - 'Content-Type': content_type, - } + + headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='put_local_document', + operation_id='get_cors_information', ) headers.update(sdk_headers) - params = { - 'batch': batch, - } - - if isinstance(document, dict): - data = json.dumps(document) - if content_type is None: - headers['Content-Type'] = 'application/json' - else: - data = document - if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id'] - path_param_values = self.encode_path_vars(db, doc_id) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_local/{doc_id}'.format(**path_param_dict) + url = '/_api/v2/user/config/cors' request = self.prepare_request( - method='PUT', + method='GET', url=url, headers=headers, - params=params, - data=data, ) response = self.send(request, **kwargs) return response - ######################### - # Database Details - ######################### - - def post_revs_diff( + def put_cors_configuration( self, - db: str, - document_revisions: dict, + origins: List[str], + *, + allow_credentials: Optional[bool] = None, + enable_cors: Optional[bool] = None, **kwargs, ) -> DetailedResponse: """ - Query the document revisions and possible ancestors missing from the database. + Modify CORS configuration. - The replicator is the primary user of this operation. After receiving a set of new - revision IDs from the source database, the replicator sends this set to the - destination database's `_revs_diff` to find out which of them already exists - there. It can then avoid fetching and sending already-known document bodies. + Sets the CORS configuration. The configuration applies to all databases and all + account level endpoints in your account. - :param str db: Path parameter to specify the database name. - :param dict document_revisions: HTTP request body for operations with - Document revisions. + :param List[str] origins: An array of strings that contain allowed origin + domains. You have to specify the full URL including the protocol. It is + recommended that only the HTTPS protocol is used. Subdomains count as + separate domains, so you have to specify all subdomains used. + :param bool allow_credentials: (optional) Boolean value to allow + authentication credentials. If set to true, browser requests must be done + by using withCredentials = true. + :param bool enable_cors: (optional) Boolean value to turn CORS on and off. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `dict` object + :rtype: DetailedResponse with `dict` result representing a `Ok` object """ - if not db: - raise ValueError('db must be provided') - if document_revisions is None: - raise ValueError('document_revisions must be provided') + if origins is None: + raise ValueError('origins must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_revs_diff', + operation_id='put_cors_configuration', ) headers.update(sdk_headers) - data = json.dumps(document_revisions) + data = { + 'origins': origins, + 'allow_credentials': allow_credentials, + 'enable_cors': enable_cors, + } + data = {k: v for (k, v) in data.items() if v is not None} + data = json.dumps(data) headers['content-type'] = 'application/json' if 'headers' in kwargs: @@ -8008,12 +7839,9 @@ def post_revs_diff( del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) - path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_revs_diff'.format(**path_param_dict) + url = '/_api/v2/user/config/cors' request = self.prepare_request( - method='POST', + method='PUT', url=url, headers=headers, data=data, @@ -8022,210 +7850,367 @@ def post_revs_diff( response = self.send(request, **kwargs) return response - def get_shards_information( + ######################### + # Attachments + ######################### + + def head_attachment( self, db: str, + doc_id: str, + attachment_name: str, + *, + if_match: Optional[str] = None, + if_none_match: Optional[str] = None, + rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve shard information. + Retrieve the HTTP headers for an attachment. - List each shard range and the corresponding replicas for a specified database. + Returns the HTTP headers that contain a minimal amount of information about the + specified attachment. This method supports the same query arguments as the `GET + /{db}/{doc_id}/{attachment_name}` method, but only the header information + (including attachment size, encoding, and the MD5 hash as an ETag), is returned. :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str attachment_name: Path parameter to specify the attachment name. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. + :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ShardsInformation` object + :rtype: DetailedResponse """ if not db: raise ValueError('db must be provided') - headers = {} + if not doc_id: + raise ValueError('doc_id must be provided') + if not attachment_name: + raise ValueError('attachment_name must be provided') + headers = { + 'If-Match': if_match, + 'If-None-Match': if_none_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_shards_information', + operation_id='head_attachment', ) headers.update(sdk_headers) + params = { + 'rev': rev, + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' - path_param_keys = ['db'] - path_param_values = self.encode_path_vars(db) + path_param_keys = ['db', 'doc_id', 'attachment_name'] + path_param_values = self.encode_path_vars(db, doc_id, attachment_name) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_shards'.format(**path_param_dict) + url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='HEAD', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - def get_document_shards_info( + def delete_attachment( self, db: str, doc_id: str, + attachment_name: str, + *, + if_match: Optional[str] = None, + rev: Optional[str] = None, + batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve shard information for a specific document. + Delete an attachment. - Retrieves information about a specific shard where a particular document is - stored, along with information about the nodes where that shard has a replica. + Deletes the attachment with the filename, `{attachment_name}`, from the specified + doc. You must supply the `rev` query parameter or `If-Match` header with the + current revision to delete the attachment. :param str db: Path parameter to specify the database name. :param str doc_id: Path parameter to specify the document ID. + :param str attachment_name: Path parameter to specify the attachment name. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str rev: (optional) Query parameter to specify a document revision. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `DocumentShardInfo` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ if not db: raise ValueError('db must be provided') if not doc_id: raise ValueError('doc_id must be provided') - headers = {} + if not attachment_name: + raise ValueError('attachment_name must be provided') + headers = { + 'If-Match': if_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_document_shards_info', + operation_id='delete_attachment', ) headers.update(sdk_headers) + params = { + 'rev': rev, + 'batch': batch, + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - path_param_keys = ['db', 'doc_id'] - path_param_values = self.encode_path_vars(db, doc_id) + path_param_keys = ['db', 'doc_id', 'attachment_name'] + path_param_values = self.encode_path_vars(db, doc_id, attachment_name) path_param_dict = dict(zip(path_param_keys, path_param_values)) - url = '/{db}/_shards/{doc_id}'.format(**path_param_dict) + url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='DELETE', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - ######################### - # Monitoring - ######################### - - def head_up_information( + def get_attachment( self, + db: str, + doc_id: str, + attachment_name: str, + *, + if_match: Optional[str] = None, + if_none_match: Optional[str] = None, + range: Optional[str] = None, + rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve HTTP headers about whether the server is up. + Retrieve an attachment. - Retrieves the HTTP headers about whether the server is up. + Returns the file attachment that is associated with the document. The raw data of + the associated attachment is returned, just as if you were accessing a static + file. The returned Content-Type header is the same as the content type set when + the document attachment was submitted to the database. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str attachment_name: Path parameter to specify the attachment name. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. + :param str range: (optional) Header parameter to specify the byte range for + a request. This allows the implementation of resumable downloads and + skippable streams. This is available for all attachments inside CouchDB. + :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse + :rtype: DetailedResponse with `BinaryIO` result """ - headers = {} + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') + if not attachment_name: + raise ValueError('attachment_name must be provided') + headers = { + 'If-Match': if_match, + 'If-None-Match': if_none_match, + 'Range': range, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='head_up_information', + operation_id='get_attachment', ) headers.update(sdk_headers) + params = { + 'rev': rev, + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] + headers['Accept'] = '*/*' - url = '/_up' + path_param_keys = ['db', 'doc_id', 'attachment_name'] + path_param_values = self.encode_path_vars(db, doc_id, attachment_name) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) request = self.prepare_request( - method='HEAD', + method='GET', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - def get_active_tasks( + def put_attachment( self, + db: str, + doc_id: str, + attachment_name: str, + attachment: BinaryIO, + content_type: str, + *, + if_match: Optional[str] = None, + rev: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve list of running tasks. + Create or modify an attachment. - Lists running tasks, including the task type, name, status, and process ID. The - result includes a JSON array of the currently running tasks, with each task - described as a single object. Depending on the operation type, the set of response - object fields might be different. + Uploads the supplied content as an attachment to the specified document. The + attachment name that you provide must be a URL encoded string. You must supply the + Content-Type header, and for an existing document, you must also supply either the + `rev` query argument or the `If-Match` HTTP header. If you omit the revision, a + new, otherwise empty, document is created with the provided attachment, or a + conflict occurs. If the uploaded attachment uses an existing attachment name in + the remote database, it updates the corresponding stored content of the database. + Since you must supply the revision information to add an attachment to the + document, this serves as validation to update the existing attachment. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str attachment_name: Path parameter to specify the attachment name. + :param BinaryIO attachment: HTTP request body for attachment operations. + :param str content_type: Content-Type of the attachment. + :param str if_match: (optional) Header parameter for a conditional HTTP + request matching an ETag. + :param str rev: (optional) Query parameter to specify a document revision. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `List[ActiveTask]` result + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ - headers = {} + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') + if not attachment_name: + raise ValueError('attachment_name must be provided') + if attachment is None: + raise ValueError('attachment must be provided') + if not content_type: + raise ValueError('content_type must be provided') + headers = { + 'Content-Type': content_type, + 'If-Match': if_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_active_tasks', + operation_id='put_attachment', ) headers.update(sdk_headers) + params = { + 'rev': rev, + } + + data = attachment + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_active_tasks' + path_param_keys = ['db', 'doc_id', 'attachment_name'] + path_param_values = self.encode_path_vars(db, doc_id, attachment_name) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/{doc_id}/{attachment_name}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='PUT', url=url, headers=headers, + params=params, + data=data, ) response = self.send(request, **kwargs) return response - def get_activity_tracker_events( + ######################### + # Local Documents + ######################### + + def head_local_document( self, + db: str, + doc_id: str, + *, + if_none_match: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve activity tracking events information. + Retrieve HTTP headers for a local document. - Check event types sent to IBM Cloud Activity Tracker Event Routing for the IBM - Cloudant instance. + Retrieves the HTTP headers containing minimal amount of information about the + specified local document. Since the response body is empty, using the HEAD method + is a lightweight way to check if the local document exists or not. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `ActivityTrackerEvents` object + :rtype: DetailedResponse """ - headers = {} + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') + headers = { + 'If-None-Match': if_none_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_activity_tracker_events', + operation_id='head_local_document', ) headers.update(sdk_headers) if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' - url = '/_api/v2/user/activity_tracker/events' + path_param_keys = ['db', 'doc_id'] + path_param_values = self.encode_path_vars(db, doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_local/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='HEAD', url=url, headers=headers, ) @@ -8233,192 +8218,307 @@ def get_activity_tracker_events( response = self.send(request, **kwargs) return response - def post_activity_tracker_events( + def delete_local_document( self, - types: List[str], + db: str, + doc_id: str, + *, + batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Modify activity tracking events configuration. + Delete a local document. - Configure event types sent to IBM Cloud Activity Tracker Event Routing for the IBM - Cloudant instance. + Deletes the specified local document. The semantics are identical to deleting a + standard document in the specified database, except that the document is not + replicated. - :param List[str] types: An array of event types sent to IBM Cloud Activity - Tracker Event Routing for the IBM Cloudant instance. "management" is a - required element of this array. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `Ok` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ - if types is None: - raise ValueError('types must be provided') + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='post_activity_tracker_events', + operation_id='delete_local_document', ) headers.update(sdk_headers) - data = { - 'types': types, + params = { + 'batch': batch, } - data = {k: v for (k, v) in data.items() if v is not None} - data = json.dumps(data) - headers['content-type'] = 'application/json' if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/user/activity_tracker/events' + path_param_keys = ['db', 'doc_id'] + path_param_values = self.encode_path_vars(db, doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_local/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='POST', + method='DELETE', url=url, headers=headers, - data=data, + params=params, ) response = self.send(request, **kwargs) return response - def get_capacity_databases_information( + def get_local_document( self, + db: str, + doc_id: str, + *, + accept: Optional[str] = None, + if_none_match: Optional[str] = None, + attachments: Optional[bool] = None, + att_encoding_info: Optional[bool] = None, + local_seq: Optional[bool] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve maximum allowed database count. + Retrieve a local document. - Retrieves the maximum number of databases currently allowed in the instance. + Retrieves the specified local document. The semantics are identical to accessing a + standard document in the specified database, except that the document is not + replicated. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param str accept: (optional) The type of the response: application/json, + multipart/mixed, multipart/related, or application/octet-stream. + :param str if_none_match: (optional) Header parameter for a conditional + HTTP request not matching an ETag. + :param bool attachments: (optional) Query parameter to specify whether to + include attachment content in the response. Note that when used with a + view-style query or changes feed this only applies when requesting + documents in the response. + :param bool att_encoding_info: (optional) Query parameter to specify + whether to include the encoding information for compressed attachments. + Note that when used with a view-style query or changes feed this only + applies when requesting documents in the response. + :param bool local_seq: (optional) Query parameter to specify whether to + include the last update sequence for the document. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `CapacityDatabasesInformation` object + :rtype: DetailedResponse with `dict` result representing a `Document` object """ - headers = {} + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') + headers = { + 'Accept': accept, + 'If-None-Match': if_none_match, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_capacity_databases_information', + operation_id='get_local_document', ) headers.update(sdk_headers) + params = { + 'attachments': attachments, + 'att_encoding_info': att_encoding_info, + 'local_seq': local_seq, + } + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] - headers['Accept'] = 'application/json' - url = '/_api/v2/user/capacity/databases' + path_param_keys = ['db', 'doc_id'] + path_param_values = self.encode_path_vars(db, doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_local/{doc_id}'.format(**path_param_dict) request = self.prepare_request( method='GET', url=url, headers=headers, + params=params, ) response = self.send(request, **kwargs) return response - def get_current_databases_information( + def put_local_document( self, + db: str, + doc_id: str, + document: Union['Document', BinaryIO], + *, + content_type: Optional[str] = None, + batch: Optional[str] = None, **kwargs, ) -> DetailedResponse: """ - Retrieve current database count. + Create or modify a local document. - Retrieves the current number of databases that exist in the instance. + Stores the specified local document. The semantics are identical to storing a + standard document in the specified database, except that the document is not + replicated. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. + :param Document document: HTTP request body for Document operations. + :param str content_type: (optional) The type of the input. + :param str batch: (optional) Query parameter to specify whether to store in + batch mode. The server will respond with a HTTP 202 Accepted response code + immediately. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `CurrentDatabasesInformation` object + :rtype: DetailedResponse with `dict` result representing a `DocumentResult` object """ - headers = {} + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') + if document is None: + raise ValueError('document must be provided') + if isinstance(document, Document): + document = convert_model(document) + content_type = content_type or 'application/json' + headers = { + 'Content-Type': content_type, + } sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_current_databases_information', + operation_id='put_local_document', ) headers.update(sdk_headers) + params = { + 'batch': batch, + } + + if isinstance(document, dict): + data = json.dumps(document) + if content_type is None: + headers['Content-Type'] = 'application/json' + else: + data = document + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/user/current/databases' + path_param_keys = ['db', 'doc_id'] + path_param_values = self.encode_path_vars(db, doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_local/{doc_id}'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='PUT', url=url, headers=headers, + params=params, + data=data, ) response = self.send(request, **kwargs) return response - def get_current_throughput_information( + ######################### + # Database Details + ######################### + + def post_revs_diff( self, + db: str, + document_revisions: dict, **kwargs, ) -> DetailedResponse: """ - Retrieve the current provisioned throughput capacity consumption. + Query the document revisions and possible ancestors missing from the database. - View the current consumption of provisioned throughput capacity for an IBM - Cloudant instance. The current consumption shows the quantities of reads, writes, - and global queries conducted against the instance for a given second. + The replicator is the primary user of this operation. After receiving a set of new + revision IDs from the source database, the replicator sends this set to the + destination database's `_revs_diff` to find out which of them already exists + there. It can then avoid fetching and sending already-known document bodies. + :param str db: Path parameter to specify the database name. + :param dict document_revisions: HTTP request body for operations with + Document revisions. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `CurrentThroughputInformation` object + :rtype: DetailedResponse with `dict` result representing a `dict` object """ + if not db: + raise ValueError('db must be provided') + if document_revisions is None: + raise ValueError('document_revisions must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_current_throughput_information', + operation_id='post_revs_diff', ) headers.update(sdk_headers) + data = json.dumps(document_revisions) + headers['content-type'] = 'application/json' + if 'headers' in kwargs: headers.update(kwargs.get('headers')) del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_api/v2/user/current/throughput' + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_revs_diff'.format(**path_param_dict) request = self.prepare_request( - method='GET', + method='POST', url=url, headers=headers, + data=data, ) response = self.send(request, **kwargs) return response - def get_membership_information( + def get_shards_information( self, + db: str, **kwargs, ) -> DetailedResponse: """ - Retrieve cluster membership information. + Retrieve shard information. - Displays the nodes that are part of the cluster as `cluster_nodes`. The field, - `all_nodes`, displays all nodes this node knows about, including the ones that are - part of the cluster. This endpoint is useful when you set up a cluster. + List each shard range and the corresponding replicas for a specified database. + :param str db: Path parameter to specify the database name. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `MembershipInformation` object + :rtype: DetailedResponse with `dict` result representing a `ShardsInformation` object """ + if not db: + raise ValueError('db must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_membership_information', + operation_id='get_shards_information', ) headers.update(sdk_headers) @@ -8427,7 +8527,10 @@ def get_membership_information( del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_membership' + path_param_keys = ['db'] + path_param_values = self.encode_path_vars(db) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_shards'.format(**path_param_dict) request = self.prepare_request( method='GET', url=url, @@ -8437,27 +8540,34 @@ def get_membership_information( response = self.send(request, **kwargs) return response - def get_up_information( + def get_document_shards_info( self, + db: str, + doc_id: str, **kwargs, ) -> DetailedResponse: """ - Retrieve information about whether the server is up. + Retrieve shard information for a specific document. - Confirms that the server is up, running, and ready to respond to requests. If the - cluster is unavailable the endpoint returns a `503` response code. - **Tip:** The authentication for this endpoint is only enforced when using IAM. + Retrieves information about a specific shard where a particular document is + stored, along with information about the nodes where that shard has a replica. + :param str db: Path parameter to specify the database name. + :param str doc_id: Path parameter to specify the document ID. :param dict headers: A `dict` containing the request headers :return: A `DetailedResponse` containing the result, headers and HTTP status code. - :rtype: DetailedResponse with `dict` result representing a `UpInformation` object + :rtype: DetailedResponse with `dict` result representing a `DocumentShardInfo` object """ + if not db: + raise ValueError('db must be provided') + if not doc_id: + raise ValueError('doc_id must be provided') headers = {} sdk_headers = get_sdk_headers( service_name=self.DEFAULT_SERVICE_NAME, service_version='V1', - operation_id='get_up_information', + operation_id='get_document_shards_info', ) headers.update(sdk_headers) @@ -8466,7 +8576,10 @@ def get_up_information( del kwargs['headers'] headers['Accept'] = 'application/json' - url = '/_up' + path_param_keys = ['db', 'doc_id'] + path_param_values = self.encode_path_vars(db, doc_id) + path_param_dict = dict(zip(path_param_keys, path_param_values)) + url = '/{db}/_shards/{doc_id}'.format(**path_param_dict) request = self.prepare_request( method='GET', url=url, @@ -12757,8 +12870,8 @@ class DesignDocumentViewIndex: :param str signature: MD5 signature of the views for the design document. :param ContentInformationSizes sizes: Schema for size information of content. :param bool updater_running: Indicates if the view is currently being updated. - :param UpdatesPending updates_pending: Schema for an ability to tell if view is - up-to-date without querying it. + :param UpdatesPending updates_pending: Schema for information about pending + updates for an index, calculated across all available copies of all shards. :param int waiting_clients: Number of clients waiting on views from this design document. :param bool waiting_commit: Indicates if there are outstanding commits to the @@ -12791,8 +12904,8 @@ def __init__( content. :param bool updater_running: Indicates if the view is currently being updated. - :param UpdatesPending updates_pending: Schema for an ability to tell if - view is up-to-date without querying it. + :param UpdatesPending updates_pending: Schema for information about pending + updates for an index, calculated across all available copies of all shards. :param int waiting_clients: Number of clients waiting on views from this design document. :param bool waiting_commit: Indicates if there are outstanding commits to @@ -15080,6 +15193,119 @@ class TypeEnum(str, Enum): +class IndexInfoResult: + """ + Schema for the result of an _index_info request. + + :param str bookmark: The ID of the first design document after the current page + of results. Pass this value as `start_key` to retrieve the next page. This field + is `null` when no more design documents are available, or when the request + includes a `keys` parameter. + :param List[SearchIndexInformation] search_indexes: The status of each search + index across the design documents in the current page of results. + :param int total_rows: The total number of design documents in the database. A + design document can contain multiple indexes. + :param List[ViewIndexInformation] view_indexes: The view index status for each + design document in the current page of results. + """ + + def __init__( + self, + bookmark: str, + search_indexes: List['SearchIndexInformation'], + total_rows: int, + view_indexes: List['ViewIndexInformation'], + ) -> None: + """ + Initialize a IndexInfoResult object. + + :param str bookmark: The ID of the first design document after the current + page of results. Pass this value as `start_key` to retrieve the next page. + This field is `null` when no more design documents are available, or when + the request includes a `keys` parameter. + :param List[SearchIndexInformation] search_indexes: The status of each + search index across the design documents in the current page of results. + :param int total_rows: The total number of design documents in the + database. A design document can contain multiple indexes. + :param List[ViewIndexInformation] view_indexes: The view index status for + each design document in the current page of results. + """ + self.bookmark = bookmark + self.search_indexes = search_indexes + self.total_rows = total_rows + self.view_indexes = view_indexes + + @classmethod + def from_dict(cls, _dict: Dict) -> 'IndexInfoResult': + """Initialize a IndexInfoResult object from a json dictionary.""" + args = {} + if (bookmark := _dict.get('bookmark')) is not None: + args['bookmark'] = bookmark + else: + args['bookmark'] = None + if (search_indexes := _dict.get('search_indexes')) is not None: + args['search_indexes'] = [SearchIndexInformation.from_dict(v) for v in search_indexes] + else: + raise ValueError('Required property \'search_indexes\' not present in IndexInfoResult JSON') + if (total_rows := _dict.get('total_rows')) is not None: + args['total_rows'] = total_rows + else: + raise ValueError('Required property \'total_rows\' not present in IndexInfoResult JSON') + if (view_indexes := _dict.get('view_indexes')) is not None: + args['view_indexes'] = [ViewIndexInformation.from_dict(v) for v in view_indexes] + else: + raise ValueError('Required property \'view_indexes\' not present in IndexInfoResult JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a IndexInfoResult object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'bookmark') and self.bookmark is not None: + _dict['bookmark'] = self.bookmark + if hasattr(self, 'search_indexes') and self.search_indexes is not None: + search_indexes_list = [] + for v in self.search_indexes: + if isinstance(v, dict): + search_indexes_list.append(v) + else: + search_indexes_list.append(v.to_dict()) + _dict['search_indexes'] = search_indexes_list + if hasattr(self, 'total_rows') and self.total_rows is not None: + _dict['total_rows'] = self.total_rows + if hasattr(self, 'view_indexes') and self.view_indexes is not None: + view_indexes_list = [] + for v in self.view_indexes: + if isinstance(v, dict): + view_indexes_list.append(v) + else: + view_indexes_list.append(v.to_dict()) + _dict['view_indexes'] = view_indexes_list + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this IndexInfoResult object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'IndexInfoResult') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'IndexInfoResult') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class IndexInformation: """ Schema for information about an index. @@ -16222,8 +16448,10 @@ class ReplicationDatabaseAuth: :param ReplicationDatabaseAuthBasic basic: (optional) Schema for basic authentication of replication source or target database. - :param ReplicationDatabaseAuthIam iam: (optional) Schema for an IAM API key for - replication database authentication. + :param ReplicationDatabaseAuthIam iam: (optional) Deprecated: use the `ibm` + property instead to configure IAM for replication database authentication. + :param ReplicationDatabaseAuthIBM ibm: (optional) IBM IAM replication auth for + CouchDB or Cloudant. """ def __init__( @@ -16231,17 +16459,21 @@ def __init__( *, basic: Optional['ReplicationDatabaseAuthBasic'] = None, iam: Optional['ReplicationDatabaseAuthIam'] = None, + ibm: Optional['ReplicationDatabaseAuthIBM'] = None, ) -> None: """ Initialize a ReplicationDatabaseAuth object. :param ReplicationDatabaseAuthBasic basic: (optional) Schema for basic authentication of replication source or target database. - :param ReplicationDatabaseAuthIam iam: (optional) Schema for an IAM API key - for replication database authentication. + :param ReplicationDatabaseAuthIam iam: (optional) Deprecated: use the `ibm` + property instead to configure IAM for replication database authentication. + :param ReplicationDatabaseAuthIBM ibm: (optional) IBM IAM replication auth + for CouchDB or Cloudant. """ self.basic = basic self.iam = iam + self.ibm = ibm @classmethod def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuth': @@ -16251,6 +16483,8 @@ def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuth': args['basic'] = ReplicationDatabaseAuthBasic.from_dict(basic) if (iam := _dict.get('iam')) is not None: args['iam'] = ReplicationDatabaseAuthIam.from_dict(iam) + if (ibm := _dict.get('ibm')) is not None: + args['ibm'] = ReplicationDatabaseAuthIBM.from_dict(ibm) return cls(**args) @classmethod @@ -16271,6 +16505,11 @@ def to_dict(self) -> Dict: _dict['iam'] = self.iam else: _dict['iam'] = self.iam.to_dict() + if hasattr(self, 'ibm') and self.ibm is not None: + if isinstance(self.ibm, dict): + _dict['ibm'] = self.ibm + else: + _dict['ibm'] = self.ibm.to_dict() return _dict def _to_dict(self): @@ -16302,44 +16541,167 @@ class ReplicationDatabaseAuthBasic: def __init__( self, - password: str, - username: str, + password: str, + username: str, + ) -> None: + """ + Initialize a ReplicationDatabaseAuthBasic object. + + :param str password: The password associated with the username. + :param str username: Schema for a username. + """ + self.password = password + self.username = username + + @classmethod + def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuthBasic': + """Initialize a ReplicationDatabaseAuthBasic object from a json dictionary.""" + args = {} + if (password := _dict.get('password')) is not None: + args['password'] = password + else: + raise ValueError('Required property \'password\' not present in ReplicationDatabaseAuthBasic JSON') + if (username := _dict.get('username')) is not None: + args['username'] = username + else: + raise ValueError('Required property \'username\' not present in ReplicationDatabaseAuthBasic JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a ReplicationDatabaseAuthBasic object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'password') and self.password is not None: + _dict['password'] = self.password + if hasattr(self, 'username') and self.username is not None: + _dict['username'] = self.username + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this ReplicationDatabaseAuthBasic object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'ReplicationDatabaseAuthBasic') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'ReplicationDatabaseAuthBasic') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + +class ReplicationDatabaseAuthIBM: + """ + IBM IAM replication auth for CouchDB or Cloudant. + + :param ReplicationDatabaseAuthIBMIam iam: IAM API key for replication database + authentication. + """ + + def __init__( + self, + iam: 'ReplicationDatabaseAuthIBMIam', + ) -> None: + """ + Initialize a ReplicationDatabaseAuthIBM object. + + :param ReplicationDatabaseAuthIBMIam iam: IAM API key for replication + database authentication. + """ + self.iam = iam + + @classmethod + def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuthIBM': + """Initialize a ReplicationDatabaseAuthIBM object from a json dictionary.""" + args = {} + if (iam := _dict.get('iam')) is not None: + args['iam'] = ReplicationDatabaseAuthIBMIam.from_dict(iam) + else: + raise ValueError('Required property \'iam\' not present in ReplicationDatabaseAuthIBM JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a ReplicationDatabaseAuthIBM object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'iam') and self.iam is not None: + if isinstance(self.iam, dict): + _dict['iam'] = self.iam + else: + _dict['iam'] = self.iam.to_dict() + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this ReplicationDatabaseAuthIBM object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'ReplicationDatabaseAuthIBM') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'ReplicationDatabaseAuthIBM') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + +class ReplicationDatabaseAuthIBMIam: + """ + IAM API key for replication database authentication. + + :param str api_key: IAM API key. + """ + + def __init__( + self, + api_key: str, ) -> None: """ - Initialize a ReplicationDatabaseAuthBasic object. + Initialize a ReplicationDatabaseAuthIBMIam object. - :param str password: The password associated with the username. - :param str username: Schema for a username. + :param str api_key: IAM API key. """ - self.password = password - self.username = username + self.api_key = api_key @classmethod - def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuthBasic': - """Initialize a ReplicationDatabaseAuthBasic object from a json dictionary.""" + def from_dict(cls, _dict: Dict) -> 'ReplicationDatabaseAuthIBMIam': + """Initialize a ReplicationDatabaseAuthIBMIam object from a json dictionary.""" args = {} - if (password := _dict.get('password')) is not None: - args['password'] = password - else: - raise ValueError('Required property \'password\' not present in ReplicationDatabaseAuthBasic JSON') - if (username := _dict.get('username')) is not None: - args['username'] = username + if (api_key := _dict.get('api_key')) is not None: + args['api_key'] = api_key else: - raise ValueError('Required property \'username\' not present in ReplicationDatabaseAuthBasic JSON') + raise ValueError('Required property \'api_key\' not present in ReplicationDatabaseAuthIBMIam JSON') return cls(**args) @classmethod def _from_dict(cls, _dict): - """Initialize a ReplicationDatabaseAuthBasic object from a json dictionary.""" + """Initialize a ReplicationDatabaseAuthIBMIam object from a json dictionary.""" return cls.from_dict(_dict) def to_dict(self) -> Dict: """Return a json dictionary representing this model.""" _dict = {} - if hasattr(self, 'password') and self.password is not None: - _dict['password'] = self.password - if hasattr(self, 'username') and self.username is not None: - _dict['username'] = self.username + if hasattr(self, 'api_key') and self.api_key is not None: + _dict['api_key'] = self.api_key return _dict def _to_dict(self): @@ -16347,23 +16709,24 @@ def _to_dict(self): return self.to_dict() def __str__(self) -> str: - """Return a `str` version of this ReplicationDatabaseAuthBasic object.""" + """Return a `str` version of this ReplicationDatabaseAuthIBMIam object.""" return json.dumps(self.to_dict(), indent=2) - def __eq__(self, other: 'ReplicationDatabaseAuthBasic') -> bool: + def __eq__(self, other: 'ReplicationDatabaseAuthIBMIam') -> bool: """Return `true` when self and other are equal, false otherwise.""" if not isinstance(other, self.__class__): return False return self.__dict__ == other.__dict__ - def __ne__(self, other: 'ReplicationDatabaseAuthBasic') -> bool: + def __ne__(self, other: 'ReplicationDatabaseAuthIBMIam') -> bool: """Return `true` when self and other are not equal, false otherwise.""" return not self == other class ReplicationDatabaseAuthIam: """ - Schema for an IAM API key for replication database authentication. + Deprecated: use the `ibm` property instead to configure IAM for replication database + authentication. :param str api_key: IAM API key. """ @@ -16464,6 +16827,11 @@ class ReplicationDocument: Only administrators can modify the value to an owner other than themselves. :param dict query_params: (optional) Schema for a map of string key value pairs, such as query parameters. + :param str request_compression: (optional) Specify whether to compress HTTP + request bodies during replication. Set to `gzip` to compress request bodies or + `none` to disable compression. Only use `gzip` if the remote server accepts + compressed requests. If unset, the default is determined by the server + administrator. :param int retries_per_request: (optional) Number of times a replication request is retried. The requests are retried with a doubling exponential backoff starting at 0.25 seconds, with a cap at 5 minutes. @@ -16542,7 +16910,7 @@ class ReplicationDocument: """ # The set of defined properties for the class - _properties = frozenset(['_attachments', '_conflicts', '_deleted', '_deleted_conflicts', '_id', '_local_seq', '_rev', '_revisions', '_revs_info', 'cancel', 'checkpoint_interval', 'connection_timeout', 'continuous', 'create_target', 'create_target_params', 'doc_ids', 'filter', 'http_connections', 'owner', 'query_params', 'retries_per_request', 'selector', 'since_seq', 'socket_options', 'source', 'source_proxy', 'target', 'target_proxy', 'use_bulk_get', 'use_checkpoints', 'user_ctx', 'winning_revs_only', 'worker_batch_size', 'worker_processes']) + _properties = frozenset(['_attachments', '_conflicts', '_deleted', '_deleted_conflicts', '_id', '_local_seq', '_rev', '_revisions', '_revs_info', 'cancel', 'checkpoint_interval', 'connection_timeout', 'continuous', 'create_target', 'create_target_params', 'doc_ids', 'filter', 'http_connections', 'owner', 'query_params', 'request_compression', 'retries_per_request', 'selector', 'since_seq', 'socket_options', 'source', 'source_proxy', 'target', 'target_proxy', 'use_bulk_get', 'use_checkpoints', 'user_ctx', 'winning_revs_only', 'worker_batch_size', 'worker_processes']) def __init__( self, @@ -16569,6 +16937,7 @@ def __init__( http_connections: Optional[int] = None, owner: Optional[str] = None, query_params: Optional[dict] = None, + request_compression: Optional[str] = None, retries_per_request: Optional[int] = None, selector: Optional[dict] = None, since_seq: Optional[str] = None, @@ -16632,6 +17001,11 @@ def __init__( themselves. :param dict query_params: (optional) Schema for a map of string key value pairs, such as query parameters. + :param str request_compression: (optional) Specify whether to compress HTTP + request bodies during replication. Set to `gzip` to compress request bodies + or `none` to disable compression. Only use `gzip` if the remote server + accepts compressed requests. If unset, the default is determined by the + server administrator. :param int retries_per_request: (optional) Number of times a replication request is retried. The requests are retried with a doubling exponential backoff starting at 0.25 seconds, with a cap at 5 minutes. @@ -16726,6 +17100,7 @@ def __init__( self.http_connections = http_connections self.owner = owner self.query_params = query_params + self.request_compression = request_compression self.retries_per_request = retries_per_request self.selector = selector self.since_seq = since_seq @@ -16792,6 +17167,8 @@ def from_dict(cls, _dict: Dict) -> 'ReplicationDocument': args['owner'] = owner if (query_params := _dict.get('query_params')) is not None: args['query_params'] = query_params + if (request_compression := _dict.get('request_compression')) is not None: + args['request_compression'] = request_compression if (retries_per_request := _dict.get('retries_per_request')) is not None: args['retries_per_request'] = retries_per_request if (selector := _dict.get('selector')) is not None: @@ -16897,6 +17274,8 @@ def to_dict(self) -> Dict: _dict['owner'] = self.owner if hasattr(self, 'query_params') and self.query_params is not None: _dict['query_params'] = self.query_params + if hasattr(self, 'request_compression') and self.request_compression is not None: + _dict['request_compression'] = self.request_compression if hasattr(self, 'retries_per_request') and self.retries_per_request is not None: _dict['retries_per_request'] = self.retries_per_request if hasattr(self, 'selector') and self.selector is not None: @@ -16975,6 +17354,18 @@ def __ne__(self, other: 'ReplicationDocument') -> bool: """Return `true` when self and other are not equal, false otherwise.""" return not self == other + class RequestCompressionEnum(str, Enum): + """ + Specify whether to compress HTTP request bodies during replication. Set to `gzip` + to compress request bodies or `none` to disable compression. Only use `gzip` if + the remote server accepts compressed requests. If unset, the default is determined + by the server administrator. + """ + + NONE = 'none' + GZIP = 'gzip' + + class Revisions: """ @@ -18193,6 +18584,9 @@ class SearchIndexInfo: :param int doc_del_count: The number of deleted documents. :param int pending_seq: The pending sequence identifier. :param str signature: Unique signature of the search index. + :param UpdatesPending updates_pending: (optional) Schema for information about + pending updates for an index, calculated across all available copies of all + shards. """ def __init__( @@ -18203,6 +18597,8 @@ def __init__( doc_del_count: int, pending_seq: int, signature: str, + *, + updates_pending: Optional['UpdatesPending'] = None, ) -> None: """ Initialize a SearchIndexInfo object. @@ -18213,6 +18609,9 @@ def __init__( :param int doc_del_count: The number of deleted documents. :param int pending_seq: The pending sequence identifier. :param str signature: Unique signature of the search index. + :param UpdatesPending updates_pending: (optional) Schema for information + about pending updates for an index, calculated across all available copies + of all shards. """ self.committed_seq = committed_seq self.disk_size = disk_size @@ -18220,6 +18619,7 @@ def __init__( self.doc_del_count = doc_del_count self.pending_seq = pending_seq self.signature = signature + self.updates_pending = updates_pending @classmethod def from_dict(cls, _dict: Dict) -> 'SearchIndexInfo': @@ -18249,6 +18649,8 @@ def from_dict(cls, _dict: Dict) -> 'SearchIndexInfo': args['signature'] = signature else: raise ValueError('Required property \'signature\' not present in SearchIndexInfo JSON') + if (updates_pending := _dict.get('updates_pending')) is not None: + args['updates_pending'] = UpdatesPending.from_dict(updates_pending) return cls(**args) @classmethod @@ -18271,6 +18673,11 @@ def to_dict(self) -> Dict: _dict['pending_seq'] = self.pending_seq if hasattr(self, 'signature') and self.signature is not None: _dict['signature'] = self.signature + if hasattr(self, 'updates_pending') and self.updates_pending is not None: + if isinstance(self.updates_pending, dict): + _dict['updates_pending'] = self.updates_pending + else: + _dict['updates_pending'] = self.updates_pending.to_dict() return _dict def _to_dict(self): @@ -18292,6 +18699,132 @@ def __ne__(self, other: 'SearchIndexInfo') -> bool: return not self == other +class SearchIndexInformation: + """ + Schema for search index status for a named index within a design document. + + :param bool ok: ok. + :param str caused_by: (optional) The cause of the error (if available). + :param str error: (optional) The name of the error. + :param str reason: (optional) The reason the error occurred (if available). + :param int ref: (optional) An internal error reference (if available). + :param str ddoc: Schema for a design document ID including a `_design/` prefix. + :param SearchIndexInfo info: (optional) Schema for metadata information about a + search index. + :param str name: The name of the search index. + """ + + def __init__( + self, + ok: bool, + ddoc: str, + name: str, + *, + caused_by: Optional[str] = None, + error: Optional[str] = None, + reason: Optional[str] = None, + ref: Optional[int] = None, + info: Optional['SearchIndexInfo'] = None, + ) -> None: + """ + Initialize a SearchIndexInformation object. + + :param bool ok: ok. + :param str ddoc: Schema for a design document ID including a `_design/` + prefix. + :param str name: The name of the search index. + :param str caused_by: (optional) The cause of the error (if available). + :param str error: (optional) The name of the error. + :param str reason: (optional) The reason the error occurred (if available). + :param int ref: (optional) An internal error reference (if available). + :param SearchIndexInfo info: (optional) Schema for metadata information + about a search index. + """ + self.ok = ok + self.caused_by = caused_by + self.error = error + self.reason = reason + self.ref = ref + self.ddoc = ddoc + self.info = info + self.name = name + + @classmethod + def from_dict(cls, _dict: Dict) -> 'SearchIndexInformation': + """Initialize a SearchIndexInformation object from a json dictionary.""" + args = {} + if (ok := _dict.get('ok')) is not None: + args['ok'] = ok + else: + raise ValueError('Required property \'ok\' not present in SearchIndexInformation JSON') + if (caused_by := _dict.get('caused_by')) is not None: + args['caused_by'] = caused_by + if (error := _dict.get('error')) is not None: + args['error'] = error + if (reason := _dict.get('reason')) is not None: + args['reason'] = reason + if (ref := _dict.get('ref')) is not None: + args['ref'] = ref + if (ddoc := _dict.get('ddoc')) is not None: + args['ddoc'] = ddoc + else: + raise ValueError('Required property \'ddoc\' not present in SearchIndexInformation JSON') + if (info := _dict.get('info')) is not None: + args['info'] = SearchIndexInfo.from_dict(info) + if (name := _dict.get('name')) is not None: + args['name'] = name + else: + raise ValueError('Required property \'name\' not present in SearchIndexInformation JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a SearchIndexInformation object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'ok') and self.ok is not None: + _dict['ok'] = self.ok + if hasattr(self, 'caused_by') and self.caused_by is not None: + _dict['caused_by'] = self.caused_by + if hasattr(self, 'error') and self.error is not None: + _dict['error'] = self.error + if hasattr(self, 'reason') and self.reason is not None: + _dict['reason'] = self.reason + if hasattr(self, 'ref') and self.ref is not None: + _dict['ref'] = self.ref + if hasattr(self, 'ddoc') and self.ddoc is not None: + _dict['ddoc'] = self.ddoc + if hasattr(self, 'info') and self.info is not None: + if isinstance(self.info, dict): + _dict['info'] = self.info + else: + _dict['info'] = self.info.to_dict() + if hasattr(self, 'name') and self.name is not None: + _dict['name'] = self.name + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this SearchIndexInformation object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'SearchIndexInformation') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'SearchIndexInformation') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class SearchInfoResult: """ Schema for search index information. @@ -19617,13 +20150,23 @@ class StatusEnum(str, Enum): class UpdatesPending: """ - Schema for an ability to tell if view is up-to-date without querying it. - - :param int minimum: Sum of shard copies with the least amount of work to do. - :param int preferred: Sum of unique shards. This value is zero when at least one - copy of every shard range is up-to-date and the view is able to answer a query - without index building delays. - :param int total: Sum of all shard copies. + Schema for information about pending updates for an index, calculated across all + available copies of all shards. + + :param int copies: (optional) The number of shard copies that reported an + answer. Copies that are unreachable or in maintenance mode are not included. + Compare with the `copies_expected` value. + :param int copies_expected: (optional) The expected number of shard copy + responses. If `copies` is less than this value, the results might be partial and + `maximum` might not represent the true backlog. + :param int maximum: (optional) The backlog of the least up-to-date copy of each + shard range. A value of `0` means the index is fully built on every copy. + :param int minimum: The backlog of the most up-to-date copy of each shard range. + A value of `0` means that at least one complete copy exists for every shard + range. + :param int preferred: The backlog of the preferred shard copies, which are the + copies that queries are routed to by default. + :param int total: The total backlog across all shard copies. """ def __init__( @@ -19631,17 +20174,33 @@ def __init__( minimum: int, preferred: int, total: int, + *, + copies: Optional[int] = None, + copies_expected: Optional[int] = None, + maximum: Optional[int] = None, ) -> None: """ Initialize a UpdatesPending object. - :param int minimum: Sum of shard copies with the least amount of work to - do. - :param int preferred: Sum of unique shards. This value is zero when at - least one copy of every shard range is up-to-date and the view is able to - answer a query without index building delays. - :param int total: Sum of all shard copies. - """ + :param int minimum: The backlog of the most up-to-date copy of each shard + range. A value of `0` means that at least one complete copy exists for + every shard range. + :param int preferred: The backlog of the preferred shard copies, which are + the copies that queries are routed to by default. + :param int total: The total backlog across all shard copies. + :param int copies: (optional) The number of shard copies that reported an + answer. Copies that are unreachable or in maintenance mode are not + included. Compare with the `copies_expected` value. + :param int copies_expected: (optional) The expected number of shard copy + responses. If `copies` is less than this value, the results might be + partial and `maximum` might not represent the true backlog. + :param int maximum: (optional) The backlog of the least up-to-date copy of + each shard range. A value of `0` means the index is fully built on every + copy. + """ + self.copies = copies + self.copies_expected = copies_expected + self.maximum = maximum self.minimum = minimum self.preferred = preferred self.total = total @@ -19650,6 +20209,12 @@ def __init__( def from_dict(cls, _dict: Dict) -> 'UpdatesPending': """Initialize a UpdatesPending object from a json dictionary.""" args = {} + if (copies := _dict.get('copies')) is not None: + args['copies'] = copies + if (copies_expected := _dict.get('copies_expected')) is not None: + args['copies_expected'] = copies_expected + if (maximum := _dict.get('maximum')) is not None: + args['maximum'] = maximum if (minimum := _dict.get('minimum')) is not None: args['minimum'] = minimum else: @@ -19672,6 +20237,12 @@ def _from_dict(cls, _dict): def to_dict(self) -> Dict: """Return a json dictionary representing this model.""" _dict = {} + if hasattr(self, 'copies') and self.copies is not None: + _dict['copies'] = self.copies + if hasattr(self, 'copies_expected') and self.copies_expected is not None: + _dict['copies_expected'] = self.copies_expected + if hasattr(self, 'maximum') and self.maximum is not None: + _dict['maximum'] = self.maximum if hasattr(self, 'minimum') and self.minimum is not None: _dict['minimum'] = self.minimum if hasattr(self, 'preferred') and self.preferred is not None: @@ -19853,6 +20424,130 @@ def __ne__(self, other: 'UuidsResult') -> bool: return not self == other +class ViewIndexInformation: + """ + Schema for view index status for a design document. + + :param bool ok: ok. + :param str caused_by: (optional) The cause of the error (if available). + :param str error: (optional) The name of the error. + :param str reason: (optional) The reason the error occurred (if available). + :param int ref: (optional) An internal error reference (if available). + :param str ddoc: Schema for a design document ID including a `_design/` prefix. + :param DesignDocumentViewIndex info: (optional) View index information. + :param List[str] views: The map-reduce view names in the design document. + """ + + def __init__( + self, + ok: bool, + ddoc: str, + views: List[str], + *, + caused_by: Optional[str] = None, + error: Optional[str] = None, + reason: Optional[str] = None, + ref: Optional[int] = None, + info: Optional['DesignDocumentViewIndex'] = None, + ) -> None: + """ + Initialize a ViewIndexInformation object. + + :param bool ok: ok. + :param str ddoc: Schema for a design document ID including a `_design/` + prefix. + :param List[str] views: The map-reduce view names in the design document. + :param str caused_by: (optional) The cause of the error (if available). + :param str error: (optional) The name of the error. + :param str reason: (optional) The reason the error occurred (if available). + :param int ref: (optional) An internal error reference (if available). + :param DesignDocumentViewIndex info: (optional) View index information. + """ + self.ok = ok + self.caused_by = caused_by + self.error = error + self.reason = reason + self.ref = ref + self.ddoc = ddoc + self.info = info + self.views = views + + @classmethod + def from_dict(cls, _dict: Dict) -> 'ViewIndexInformation': + """Initialize a ViewIndexInformation object from a json dictionary.""" + args = {} + if (ok := _dict.get('ok')) is not None: + args['ok'] = ok + else: + raise ValueError('Required property \'ok\' not present in ViewIndexInformation JSON') + if (caused_by := _dict.get('caused_by')) is not None: + args['caused_by'] = caused_by + if (error := _dict.get('error')) is not None: + args['error'] = error + if (reason := _dict.get('reason')) is not None: + args['reason'] = reason + if (ref := _dict.get('ref')) is not None: + args['ref'] = ref + if (ddoc := _dict.get('ddoc')) is not None: + args['ddoc'] = ddoc + else: + raise ValueError('Required property \'ddoc\' not present in ViewIndexInformation JSON') + if (info := _dict.get('info')) is not None: + args['info'] = DesignDocumentViewIndex.from_dict(info) + if (views := _dict.get('views')) is not None: + args['views'] = views + else: + raise ValueError('Required property \'views\' not present in ViewIndexInformation JSON') + return cls(**args) + + @classmethod + def _from_dict(cls, _dict): + """Initialize a ViewIndexInformation object from a json dictionary.""" + return cls.from_dict(_dict) + + def to_dict(self) -> Dict: + """Return a json dictionary representing this model.""" + _dict = {} + if hasattr(self, 'ok') and self.ok is not None: + _dict['ok'] = self.ok + if hasattr(self, 'caused_by') and self.caused_by is not None: + _dict['caused_by'] = self.caused_by + if hasattr(self, 'error') and self.error is not None: + _dict['error'] = self.error + if hasattr(self, 'reason') and self.reason is not None: + _dict['reason'] = self.reason + if hasattr(self, 'ref') and self.ref is not None: + _dict['ref'] = self.ref + if hasattr(self, 'ddoc') and self.ddoc is not None: + _dict['ddoc'] = self.ddoc + if hasattr(self, 'info') and self.info is not None: + if isinstance(self.info, dict): + _dict['info'] = self.info + else: + _dict['info'] = self.info.to_dict() + if hasattr(self, 'views') and self.views is not None: + _dict['views'] = self.views + return _dict + + def _to_dict(self): + """Return a json dictionary representing this model.""" + return self.to_dict() + + def __str__(self) -> str: + """Return a `str` version of this ViewIndexInformation object.""" + return json.dumps(self.to_dict(), indent=2) + + def __eq__(self, other: 'ViewIndexInformation') -> bool: + """Return `true` when self and other are equal, false otherwise.""" + if not isinstance(other, self.__class__): + return False + return self.__dict__ == other.__dict__ + + def __ne__(self, other: 'ViewIndexInformation') -> bool: + """Return `true` when self and other are not equal, false otherwise.""" + return not self == other + + class ViewQueriesResult: """ Schema for the results of a queries view operation. diff --git a/stubs/gen-its-mappings.json b/stubs/gen-its-mappings.json index 16772714..524e2b5d 100644 --- a/stubs/gen-its-mappings.json +++ b/stubs/gen-its-mappings.json @@ -2499,6 +2499,103 @@ }, "uuid": "6026c807-3ad5-3944-a4cc-6a4906aaefd3" }, + { + "id": "a1b2c3d4-e5f6-3789-abcd-ef0123456789", + "request": { + "url": "/testString/_index_info", + "method": "POST", + "bodyPatterns": [ + { + "equalToJson": "{}", + "ignoreArrayOrder": false, + "ignoreExtraElements": true + } + ] + }, + "response": { + "status": 200, + "headers": { + "Cache-Control": "must-revalidate", + "Content-Type": "application/json", + "Date": "Mon, 23 May 2022 20:24:06 GMT", + "Server": "CouchDB/3.2.1 (Erlang OTP/20)", + "transaction-id": "a1b2c3d4e5f642406f8d93f1e20e401f", + "X-Cloudant-Action": "cloudantnosqldb.any-document.read", + "X-Couch-Request-ID": "a1b2c3d4e5", + "X-Frame-Options": "DENY", + "Strict-Transport-Security": "max-age=31536000", + "X-Content-Type-Options": "nosniff", + "X-Cloudant-Request-Class": "query", + "X-Cloudant-Backend": "bm-cc-us-east-05", + "Via": "1.1 lb1.bm-cc-us-east-05 (Glum/1.102.0)", + "Vary": "Accept-Encoding" + }, + "jsonBody": { + "total_rows": 1, + "bookmark": null, + "view_indexes": [ + { + "ddoc": "_design/testString", + "views": [ + "testString" + ], + "ok": true, + "info": { + "updates_pending": { + "minimum": 0, + "preferred": 0, + "total": 0, + "maximum": 0, + "copies": 24, + "copies_expected": 24 + }, + "waiting_commit": false, + "waiting_clients": 0, + "updater_running": false, + "update_seq": 14, + "sizes": { + "file": 30623, + "external": 1307, + "active": 2725 + }, + "signature": "bedc44e56c2ba97902aeaac2b51ad77c", + "purge_seq": 0, + "language": "javascript", + "compact_running": false, + "collator_versions": [ + "153.128" + ] + } + } + ], + "search_indexes": [ + { + "ddoc": "_design/testString", + "name": "testString", + "ok": true, + "info": { + "updates_pending": { + "minimum": 0, + "preferred": 0, + "total": 0, + "maximum": 0, + "copies": 24, + "copies_expected": 24 + }, + "signature": "f4c96067e9edeafd9afdf2876740b4cb", + "pending_seq": 14, + "doc_del_count": 0, + "doc_count": 11, + "disk_size": 14966, + "committed_seq": 14 + } + } + ], + "nouveau_indexes": [] + } + }, + "uuid": "a1b2c3d4-e5f6-3789-abcd-ef0123456789" + }, { "id": "c8bd56cb-8f5b-3521-80a9-75231b5a5069", "request": { diff --git a/test/integration/test_cloudant_v1.py b/test/integration/test_cloudant_v1.py index 0fbb061a..fb76ecd2 100644 --- a/test/integration/test_cloudant_v1.py +++ b/test/integration/test_cloudant_v1.py @@ -859,6 +859,102 @@ def test_post_design_docs_queries(self): all_docs_queries_result = response.get_result() assert all_docs_queries_result is not None + @needscredentials + def test_head_up_information(self): + response = self.cloudant_service.head_up_information() + + assert response.get_status_code() == 200 + + @needscredentials + def test_get_active_tasks(self): + response = self.cloudant_service.get_active_tasks() + + assert response.get_status_code() == 200 + list_active_task = response.get_result() + assert list_active_task is not None + + @needscredentials + def test_get_activity_tracker_events(self): + response = self.cloudant_service.get_activity_tracker_events() + + assert response.get_status_code() == 200 + activity_tracker_events = response.get_result() + assert activity_tracker_events is not None + + @needscredentials + def test_post_activity_tracker_events(self): + response = self.cloudant_service.post_activity_tracker_events( + types=['management', 'data'], + ) + + assert response.get_status_code() == 200 + ok = response.get_result() + assert ok is not None + + @needscredentials + def test_get_capacity_databases_information(self): + response = self.cloudant_service.get_capacity_databases_information() + + assert response.get_status_code() == 200 + capacity_databases_information = response.get_result() + assert capacity_databases_information is not None + + @needscredentials + def test_get_current_databases_information(self): + response = self.cloudant_service.get_current_databases_information() + + assert response.get_status_code() == 200 + current_databases_information = response.get_result() + assert current_databases_information is not None + + @needscredentials + def test_get_current_throughput_information(self): + response = self.cloudant_service.get_current_throughput_information() + + assert response.get_status_code() == 200 + current_throughput_information = response.get_result() + assert current_throughput_information is not None + + @needscredentials + def test_get_membership_information(self): + response = self.cloudant_service.get_membership_information() + + assert response.get_status_code() == 200 + membership_information = response.get_result() + assert membership_information is not None + + @needscredentials + def test_get_up_information(self): + response = self.cloudant_service.get_up_information() + + assert response.get_status_code() == 200 + up_information = response.get_result() + assert up_information is not None + + @needscredentials + def test_post_index_info(self): + response = self.cloudant_service.post_index_info( + db='testString', + att_encoding_info=False, + attachments=False, + conflicts=False, + descending=False, + include_docs=False, + inclusive_end=True, + limit=0, + skip=0, + update_seq=False, + end_key='testString', + key='testString', + keys=['_design/cookbook'], + start_key='testString', + type=['search'], + ) + + assert response.get_status_code() == 200 + index_info_result = response.get_result() + assert index_info_result is not None + @needscredentials def test_post_view(self): response = self.cloudant_service.post_view( @@ -1517,10 +1613,19 @@ def test_post_replicator(self): replication_database_auth_iam_model = { 'api_key': 'testString', } + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = { + 'api_key': 'testString', + } + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = { + 'iam': replication_database_auth_ibm_iam_model, + } # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = { 'basic': replication_database_auth_basic_model, 'iam': replication_database_auth_iam_model, + 'ibm': replication_database_auth_ibm_model, } # Construct a dict representation of a ReplicationDatabase model replication_database_model = { @@ -1556,6 +1661,7 @@ def test_post_replicator(self): 'http_connections': 10, 'owner': 'testString', 'query_params': {'key1': 'testString'}, + 'request_compression': 'gzip', 'retries_per_request': 3, 'selector': {'_id': {'$regex': 'docid'}}, 'since_seq': '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU', @@ -1642,10 +1748,19 @@ def test_put_replication_document(self): replication_database_auth_iam_model = { 'api_key': 'testString', } + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = { + 'api_key': 'testString', + } + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = { + 'iam': replication_database_auth_ibm_iam_model, + } # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = { 'basic': replication_database_auth_basic_model, 'iam': replication_database_auth_iam_model, + 'ibm': replication_database_auth_ibm_model, } # Construct a dict representation of a ReplicationDatabase model replication_database_model = { @@ -1681,6 +1796,7 @@ def test_put_replication_document(self): 'http_connections': 10, 'owner': 'testString', 'query_params': {'key1': 'testString'}, + 'request_compression': 'gzip', 'retries_per_request': 3, 'selector': {'_id': {'$regex': 'docid'}}, 'since_seq': '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU', @@ -2002,78 +2118,6 @@ def test_get_document_shards_info(self): document_shard_info = response.get_result() assert document_shard_info is not None - @needscredentials - def test_head_up_information(self): - response = self.cloudant_service.head_up_information() - - assert response.get_status_code() == 200 - - @needscredentials - def test_get_active_tasks(self): - response = self.cloudant_service.get_active_tasks() - - assert response.get_status_code() == 200 - list_active_task = response.get_result() - assert list_active_task is not None - - @needscredentials - def test_get_activity_tracker_events(self): - response = self.cloudant_service.get_activity_tracker_events() - - assert response.get_status_code() == 200 - activity_tracker_events = response.get_result() - assert activity_tracker_events is not None - - @needscredentials - def test_post_activity_tracker_events(self): - response = self.cloudant_service.post_activity_tracker_events( - types=['management', 'data'], - ) - - assert response.get_status_code() == 200 - ok = response.get_result() - assert ok is not None - - @needscredentials - def test_get_capacity_databases_information(self): - response = self.cloudant_service.get_capacity_databases_information() - - assert response.get_status_code() == 200 - capacity_databases_information = response.get_result() - assert capacity_databases_information is not None - - @needscredentials - def test_get_current_databases_information(self): - response = self.cloudant_service.get_current_databases_information() - - assert response.get_status_code() == 200 - current_databases_information = response.get_result() - assert current_databases_information is not None - - @needscredentials - def test_get_current_throughput_information(self): - response = self.cloudant_service.get_current_throughput_information() - - assert response.get_status_code() == 200 - current_throughput_information = response.get_result() - assert current_throughput_information is not None - - @needscredentials - def test_get_membership_information(self): - response = self.cloudant_service.get_membership_information() - - assert response.get_status_code() == 200 - membership_information = response.get_result() - assert membership_information is not None - - @needscredentials - def test_get_up_information(self): - response = self.cloudant_service.get_up_information() - - assert response.get_status_code() == 200 - up_information = response.get_result() - assert up_information is not None - @needscredentials def test_delete_database(self): response = self.cloudant_service.delete_database( diff --git a/test/unit/test_cloudant_v1.py b/test/unit/test_cloudant_v1.py index 7c3ce166..876b6320 100644 --- a/test/unit/test_cloudant_v1.py +++ b/test/unit/test_cloudant_v1.py @@ -5232,7 +5232,7 @@ def test_get_design_document_information_all_params(self): """ # Set up mock url = preprocess_url('/testString/_design/testString/_info') - mock_response = '{"name": "name", "view_index": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}}' + mock_response = '{"name": "name", "view_index": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}}' responses.add( responses.GET, url, @@ -5272,7 +5272,7 @@ def test_get_design_document_information_value_error(self): """ # Set up mock url = preprocess_url('/testString/_design/testString/_info') - mock_response = '{"name": "name", "view_index": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}}' + mock_response = '{"name": "name", "view_index": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}}' responses.add( responses.GET, url, @@ -5639,7 +5639,7 @@ def test_post_design_docs_queries_value_error_with_retries(self): ############################################################################## ############################################################################## -# Start of Service: Views +# Start of Service: Monitoring ############################################################################## # region @@ -5672,19 +5672,130 @@ def test_new_instance_without_authenticator(self): ) -class TestPostView: +class TestHeadUpInformation: """ - Test Class for post_view + Test Class for head_up_information """ @responses.activate - def test_post_view_all_params(self): + def test_head_up_information_all_params(self): """ - post_view() + head_up_information() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString') - mock_response = '{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}' + url = preprocess_url('/_up') + responses.add( + responses.HEAD, + url, + status=200, + ) + + # Invoke method + response = _service.head_up_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_head_up_information_all_params_with_retries(self): + # Enable retries and run test_head_up_information_all_params. + _service.enable_retries() + self.test_head_up_information_all_params() + + # Disable retries and run test_head_up_information_all_params. + _service.disable_retries() + self.test_head_up_information_all_params() + + +class TestGetActiveTasks: + """ + Test Class for get_active_tasks + """ + + @responses.activate + def test_get_active_tasks_all_params(self): + """ + get_active_tasks() + """ + # Set up mock + url = preprocess_url('/_active_tasks') + mock_response = '[{"bulk_get_attempts": 0, "bulk_get_docs": 0, "changes_done": 0, "changes_pending": 0, "checkpoint_interval": 30000, "checkpointed_source_seq": "checkpointed_source_seq", "continuous": false, "database": "database", "design_document": "design_document", "doc_id": "doc_id", "doc_write_failures": 0, "docs_read": 0, "docs_written": 0, "index": "index", "indexer_pid": "indexer_pid", "missing_revisions_found": 0, "node": "node", "phase": "docid_sort", "pid": "pid", "process_status": "exiting", "progress": 0, "replication_id": "replication_id", "retry": false, "revisions_checked": 0, "source": "source", "source_seq": "source_seq", "started_on": 0, "target": "target", "through_seq": "through_seq", "total_changes": 0, "type": "database_compaction", "updated_on": 0, "user": "user", "view": 0}]' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_active_tasks() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_active_tasks_all_params_with_retries(self): + # Enable retries and run test_get_active_tasks_all_params. + _service.enable_retries() + self.test_get_active_tasks_all_params() + + # Disable retries and run test_get_active_tasks_all_params. + _service.disable_retries() + self.test_get_active_tasks_all_params() + + +class TestGetActivityTrackerEvents: + """ + Test Class for get_activity_tracker_events + """ + + @responses.activate + def test_get_activity_tracker_events_all_params(self): + """ + get_activity_tracker_events() + """ + # Set up mock + url = preprocess_url('/_api/v2/user/activity_tracker/events') + mock_response = '{"types": ["management"]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_activity_tracker_events() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_activity_tracker_events_all_params_with_retries(self): + # Enable retries and run test_get_activity_tracker_events_all_params. + _service.enable_retries() + self.test_get_activity_tracker_events_all_params() + + # Disable retries and run test_get_activity_tracker_events_all_params. + _service.disable_retries() + self.test_get_activity_tracker_events_all_params() + + +class TestPostActivityTrackerEvents: + """ + Test Class for post_activity_tracker_events + """ + + @responses.activate + def test_post_activity_tracker_events_all_params(self): + """ + post_activity_tracker_events() + """ + # Set up mock + url = preprocess_url('/_api/v2/user/activity_tracker/events') + mock_response = '{"ok": true}' responses.add( responses.POST, url, @@ -5694,55 +5805,11 @@ def test_post_view_all_params(self): ) # Set up parameter values - db = 'testString' - ddoc = 'testString' - view = 'testString' - att_encoding_info = False - attachments = False - conflicts = False - descending = False - include_docs = True - inclusive_end = True - limit = 10 - skip = 0 - update_seq = False - end_key = 'testString' - end_key_doc_id = 'testString' - group = False - group_level = 1 - key = 'testString' - keys = ['examplekey'] - reduce = True - stable = False - start_key = 'testString' - start_key_doc_id = 'testString' - update = 'true' + types = ['management', 'data'] # Invoke method - response = _service.post_view( - db, - ddoc, - view, - att_encoding_info=att_encoding_info, - attachments=attachments, - conflicts=conflicts, - descending=descending, - include_docs=include_docs, - inclusive_end=inclusive_end, - limit=limit, - skip=skip, - update_seq=update_seq, - end_key=end_key, - end_key_doc_id=end_key_doc_id, - group=group, - group_level=group_level, - key=key, - keys=keys, - reduce=reduce, - stable=stable, - start_key=start_key, - start_key_doc_id=start_key_doc_id, - update=update, + response = _service.post_activity_tracker_events( + types, headers={}, ) @@ -5755,44 +5822,25 @@ def test_post_view_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['att_encoding_info'] == False - assert req_body['attachments'] == False - assert req_body['conflicts'] == False - assert req_body['descending'] == False - assert req_body['include_docs'] == True - assert req_body['inclusive_end'] == True - assert req_body['limit'] == 10 - assert req_body['skip'] == 0 - assert req_body['update_seq'] == False - assert req_body['end_key'] == 'testString' - assert req_body['end_key_doc_id'] == 'testString' - assert req_body['group'] == False - assert req_body['group_level'] == 1 - assert req_body['key'] == 'testString' - assert req_body['keys'] == ['examplekey'] - assert req_body['reduce'] == True - assert req_body['stable'] == False - assert req_body['start_key'] == 'testString' - assert req_body['start_key_doc_id'] == 'testString' - assert req_body['update'] == 'true' + assert req_body['types'] == ['management', 'data'] - def test_post_view_all_params_with_retries(self): - # Enable retries and run test_post_view_all_params. + def test_post_activity_tracker_events_all_params_with_retries(self): + # Enable retries and run test_post_activity_tracker_events_all_params. _service.enable_retries() - self.test_post_view_all_params() + self.test_post_activity_tracker_events_all_params() - # Disable retries and run test_post_view_all_params. + # Disable retries and run test_post_activity_tracker_events_all_params. _service.disable_retries() - self.test_post_view_all_params() + self.test_post_activity_tracker_events_all_params() @responses.activate - def test_post_view_value_error(self): + def test_post_activity_tracker_events_value_error(self): """ - test_post_view_value_error() + test_post_activity_tracker_events_value_error() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString') - mock_response = '{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}' + url = preprocess_url('/_api/v2/user/activity_tracker/events') + mock_response = '{"ok": true}' responses.add( responses.POST, url, @@ -5802,64 +5850,230 @@ def test_post_view_value_error(self): ) # Set up parameter values - db = 'testString' - ddoc = 'testString' - view = 'testString' - att_encoding_info = False - attachments = False - conflicts = False - descending = False - include_docs = True - inclusive_end = True - limit = 10 - skip = 0 - update_seq = False - end_key = 'testString' - end_key_doc_id = 'testString' - group = False - group_level = 1 - key = 'testString' - keys = ['examplekey'] - reduce = True - stable = False - start_key = 'testString' - start_key_doc_id = 'testString' - update = 'true' + types = ['management', 'data'] # Pass in all but one required param and check for a ValueError req_param_dict = { - "db": db, - "ddoc": ddoc, - "view": view, + "types": types, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_view(**req_copy) + _service.post_activity_tracker_events(**req_copy) - def test_post_view_value_error_with_retries(self): - # Enable retries and run test_post_view_value_error. + def test_post_activity_tracker_events_value_error_with_retries(self): + # Enable retries and run test_post_activity_tracker_events_value_error. _service.enable_retries() - self.test_post_view_value_error() + self.test_post_activity_tracker_events_value_error() - # Disable retries and run test_post_view_value_error. + # Disable retries and run test_post_activity_tracker_events_value_error. _service.disable_retries() - self.test_post_view_value_error() + self.test_post_activity_tracker_events_value_error() -class TestPostViewAsStream: +class TestGetCapacityDatabasesInformation: """ - Test Class for post_view_as_stream + Test Class for get_capacity_databases_information """ @responses.activate - def test_post_view_as_stream_all_params(self): + def test_get_capacity_databases_information_all_params(self): """ - post_view_as_stream() + get_capacity_databases_information() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString') - mock_response = '{"foo": "this is a mock response for JSON streaming"}' + url = preprocess_url('/_api/v2/user/capacity/databases') + mock_response = '{"current": {"databases": {"total": 0}}}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_capacity_databases_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_capacity_databases_information_all_params_with_retries(self): + # Enable retries and run test_get_capacity_databases_information_all_params. + _service.enable_retries() + self.test_get_capacity_databases_information_all_params() + + # Disable retries and run test_get_capacity_databases_information_all_params. + _service.disable_retries() + self.test_get_capacity_databases_information_all_params() + + +class TestGetCurrentDatabasesInformation: + """ + Test Class for get_current_databases_information + """ + + @responses.activate + def test_get_current_databases_information_all_params(self): + """ + get_current_databases_information() + """ + # Set up mock + url = preprocess_url('/_api/v2/user/current/databases') + mock_response = '{"databases": {"total": 0}}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_current_databases_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_current_databases_information_all_params_with_retries(self): + # Enable retries and run test_get_current_databases_information_all_params. + _service.enable_retries() + self.test_get_current_databases_information_all_params() + + # Disable retries and run test_get_current_databases_information_all_params. + _service.disable_retries() + self.test_get_current_databases_information_all_params() + + +class TestGetCurrentThroughputInformation: + """ + Test Class for get_current_throughput_information + """ + + @responses.activate + def test_get_current_throughput_information_all_params(self): + """ + get_current_throughput_information() + """ + # Set up mock + url = preprocess_url('/_api/v2/user/current/throughput') + mock_response = '{"throughput": {"query": 0, "read": 0, "write": 0}}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_current_throughput_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_current_throughput_information_all_params_with_retries(self): + # Enable retries and run test_get_current_throughput_information_all_params. + _service.enable_retries() + self.test_get_current_throughput_information_all_params() + + # Disable retries and run test_get_current_throughput_information_all_params. + _service.disable_retries() + self.test_get_current_throughput_information_all_params() + + +class TestGetMembershipInformation: + """ + Test Class for get_membership_information + """ + + @responses.activate + def test_get_membership_information_all_params(self): + """ + get_membership_information() + """ + # Set up mock + url = preprocess_url('/_membership') + mock_response = '{"all_nodes": ["all_nodes"], "cluster_nodes": ["cluster_nodes"]}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_membership_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_membership_information_all_params_with_retries(self): + # Enable retries and run test_get_membership_information_all_params. + _service.enable_retries() + self.test_get_membership_information_all_params() + + # Disable retries and run test_get_membership_information_all_params. + _service.disable_retries() + self.test_get_membership_information_all_params() + + +class TestGetUpInformation: + """ + Test Class for get_up_information + """ + + @responses.activate + def test_get_up_information_all_params(self): + """ + get_up_information() + """ + # Set up mock + url = preprocess_url('/_up') + mock_response = '{"cluster": "cluster", "seeds": {"anyKey": "anyValue"}, "status": "maintenance_mode"}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Invoke method + response = _service.get_up_information() + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_up_information_all_params_with_retries(self): + # Enable retries and run test_get_up_information_all_params. + _service.enable_retries() + self.test_get_up_information_all_params() + + # Disable retries and run test_get_up_information_all_params. + _service.disable_retries() + self.test_get_up_information_all_params() + + +class TestPostIndexInfo: + """ + Test Class for post_index_info + """ + + @responses.activate + def test_post_index_info_all_params(self): + """ + post_index_info() + """ + # Set up mock + url = preprocess_url('/testString/_index_info') + mock_response = '{"bookmark": "bookmark", "search_indexes": [{"ok": true, "caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "ddoc": "ddoc", "info": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature", "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}}, "name": "name"}], "total_rows": 0, "view_indexes": [{"ok": true, "caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "ddoc": "ddoc", "info": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}, "views": ["views"]}]}' responses.add( responses.POST, url, @@ -5870,34 +6084,24 @@ def test_post_view_as_stream_all_params(self): # Set up parameter values db = 'testString' - ddoc = 'testString' - view = 'testString' att_encoding_info = False attachments = False conflicts = False descending = False - include_docs = True + include_docs = False inclusive_end = True - limit = 10 + limit = 0 skip = 0 update_seq = False end_key = 'testString' - end_key_doc_id = 'testString' - group = False - group_level = 1 key = 'testString' - keys = ['examplekey'] - reduce = True - stable = False + keys = ['_design/cookbook'] start_key = 'testString' - start_key_doc_id = 'testString' - update = 'true' + type = ['search'] # Invoke method - response = _service.post_view_as_stream( + response = _service.post_index_info( db, - ddoc, - view, att_encoding_info=att_encoding_info, attachments=attachments, conflicts=conflicts, @@ -5908,16 +6112,10 @@ def test_post_view_as_stream_all_params(self): skip=skip, update_seq=update_seq, end_key=end_key, - end_key_doc_id=end_key_doc_id, - group=group, - group_level=group_level, key=key, keys=keys, - reduce=reduce, - stable=stable, start_key=start_key, - start_key_doc_id=start_key_doc_id, - update=update, + type=type, headers={}, ) @@ -5934,46 +6132,34 @@ def test_post_view_as_stream_all_params(self): assert req_body['attachments'] == False assert req_body['conflicts'] == False assert req_body['descending'] == False - assert req_body['include_docs'] == True + assert req_body['include_docs'] == False assert req_body['inclusive_end'] == True - assert req_body['limit'] == 10 + assert req_body['limit'] == 0 assert req_body['skip'] == 0 assert req_body['update_seq'] == False assert req_body['end_key'] == 'testString' - assert req_body['end_key_doc_id'] == 'testString' - assert req_body['group'] == False - assert req_body['group_level'] == 1 assert req_body['key'] == 'testString' - assert req_body['keys'] == ['examplekey'] - assert req_body['reduce'] == True - assert req_body['stable'] == False + assert req_body['keys'] == ['_design/cookbook'] assert req_body['start_key'] == 'testString' - assert req_body['start_key_doc_id'] == 'testString' - assert req_body['update'] == 'true' - - # Verify streamed JSON response - result = response.get_result() - assert isinstance(result, requests.models.Response) - response_buf = result.iter_content(chunk_size=1024) - assert str(next(response_buf), "utf-8") == mock_response + assert req_body['type'] == ['search'] - def test_post_view_as_stream_all_params_with_retries(self): - # Enable retries and run test_post_view_as_stream_all_params. + def test_post_index_info_all_params_with_retries(self): + # Enable retries and run test_post_index_info_all_params. _service.enable_retries() - self.test_post_view_as_stream_all_params() + self.test_post_index_info_all_params() - # Disable retries and run test_post_view_as_stream_all_params. + # Disable retries and run test_post_index_info_all_params. _service.disable_retries() - self.test_post_view_as_stream_all_params() + self.test_post_index_info_all_params() @responses.activate - def test_post_view_as_stream_value_error(self): + def test_post_index_info_value_error(self): """ - test_post_view_as_stream_value_error() + test_post_index_info_value_error() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString') - mock_response = '{"foo": "this is a mock response for JSON streaming"}' + url = preprocess_url('/testString/_index_info') + mock_response = '{"bookmark": "bookmark", "search_indexes": [{"ok": true, "caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "ddoc": "ddoc", "info": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature", "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}}, "name": "name"}], "total_rows": 0, "view_indexes": [{"ok": true, "caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "ddoc": "ddoc", "info": {"collator_versions": ["collator_versions"], "compact_running": false, "language": "language", "signature": "signature", "sizes": {"active": 0, "external": 0, "file": 0}, "updater_running": false, "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}, "waiting_clients": 0, "waiting_commit": true}, "views": ["views"]}]}' responses.add( responses.POST, url, @@ -5984,63 +6170,92 @@ def test_post_view_as_stream_value_error(self): # Set up parameter values db = 'testString' - ddoc = 'testString' - view = 'testString' att_encoding_info = False attachments = False conflicts = False descending = False - include_docs = True + include_docs = False inclusive_end = True - limit = 10 + limit = 0 skip = 0 update_seq = False end_key = 'testString' - end_key_doc_id = 'testString' - group = False - group_level = 1 key = 'testString' - keys = ['examplekey'] - reduce = True - stable = False + keys = ['_design/cookbook'] start_key = 'testString' - start_key_doc_id = 'testString' - update = 'true' + type = ['search'] # Pass in all but one required param and check for a ValueError req_param_dict = { "db": db, - "ddoc": ddoc, - "view": view, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_view_as_stream(**req_copy) + _service.post_index_info(**req_copy) - def test_post_view_as_stream_value_error_with_retries(self): - # Enable retries and run test_post_view_as_stream_value_error. + def test_post_index_info_value_error_with_retries(self): + # Enable retries and run test_post_index_info_value_error. _service.enable_retries() - self.test_post_view_as_stream_value_error() + self.test_post_index_info_value_error() - # Disable retries and run test_post_view_as_stream_value_error. + # Disable retries and run test_post_index_info_value_error. _service.disable_retries() - self.test_post_view_as_stream_value_error() + self.test_post_index_info_value_error() -class TestPostViewQueries: +# endregion +############################################################################## +# End of Service: Monitoring +############################################################################## + +############################################################################## +# Start of Service: Views +############################################################################## +# region + + +class TestNewInstance: """ - Test Class for post_view_queries + Test Class for new_instance + """ + + def test_new_instance(self): + """ + new_instance() + """ + os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' + + service = CloudantV1.new_instance( + service_name='TEST_SERVICE', + ) + + assert service is not None + assert isinstance(service, CloudantV1) + + def test_new_instance_without_authenticator(self): + """ + new_instance_without_authenticator() + """ + with pytest.raises(ValueError, match='authenticator must be provided'): + service = CloudantV1.new_instance( + service_name='TEST_SERVICE_NOT_FOUND', + ) + + +class TestPostView: + """ + Test Class for post_view """ @responses.activate - def test_post_view_queries_all_params(self): + def test_post_view_all_params(self): """ - post_view_queries() + post_view() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString/queries') - mock_response = '{"results": [{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}]}' + url = preprocess_url('/testString/_design/testString/_view/testString') + mock_response = '{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}' responses.add( responses.POST, url, @@ -6049,41 +6264,56 @@ def test_post_view_queries_all_params(self): status=200, ) - # Construct a dict representation of a ViewQuery model - view_query_model = {} - view_query_model['att_encoding_info'] = False - view_query_model['attachments'] = False - view_query_model['conflicts'] = False - view_query_model['descending'] = False - view_query_model['include_docs'] = True - view_query_model['inclusive_end'] = True - view_query_model['limit'] = 5 - view_query_model['skip'] = 0 - view_query_model['update_seq'] = False - view_query_model['end_key'] = 'testString' - view_query_model['end_key_doc_id'] = 'testString' - view_query_model['group'] = False - view_query_model['group_level'] = 1 - view_query_model['key'] = 'testString' - view_query_model['keys'] = ['testString'] - view_query_model['reduce'] = True - view_query_model['stable'] = False - view_query_model['start_key'] = 'testString' - view_query_model['start_key_doc_id'] = 'testString' - view_query_model['update'] = 'true' - # Set up parameter values db = 'testString' ddoc = 'testString' view = 'testString' - queries = [view_query_model] + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = True + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + end_key_doc_id = 'testString' + group = False + group_level = 1 + key = 'testString' + keys = ['examplekey'] + reduce = True + stable = False + start_key = 'testString' + start_key_doc_id = 'testString' + update = 'true' # Invoke method - response = _service.post_view_queries( + response = _service.post_view( db, ddoc, view, - queries, + att_encoding_info=att_encoding_info, + attachments=attachments, + conflicts=conflicts, + descending=descending, + include_docs=include_docs, + inclusive_end=inclusive_end, + limit=limit, + skip=skip, + update_seq=update_seq, + end_key=end_key, + end_key_doc_id=end_key_doc_id, + group=group, + group_level=group_level, + key=key, + keys=keys, + reduce=reduce, + stable=stable, + start_key=start_key, + start_key_doc_id=start_key_doc_id, + update=update, headers={}, ) @@ -6096,25 +6326,44 @@ def test_post_view_queries_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['queries'] == [view_query_model] + assert req_body['att_encoding_info'] == False + assert req_body['attachments'] == False + assert req_body['conflicts'] == False + assert req_body['descending'] == False + assert req_body['include_docs'] == True + assert req_body['inclusive_end'] == True + assert req_body['limit'] == 10 + assert req_body['skip'] == 0 + assert req_body['update_seq'] == False + assert req_body['end_key'] == 'testString' + assert req_body['end_key_doc_id'] == 'testString' + assert req_body['group'] == False + assert req_body['group_level'] == 1 + assert req_body['key'] == 'testString' + assert req_body['keys'] == ['examplekey'] + assert req_body['reduce'] == True + assert req_body['stable'] == False + assert req_body['start_key'] == 'testString' + assert req_body['start_key_doc_id'] == 'testString' + assert req_body['update'] == 'true' - def test_post_view_queries_all_params_with_retries(self): - # Enable retries and run test_post_view_queries_all_params. + def test_post_view_all_params_with_retries(self): + # Enable retries and run test_post_view_all_params. _service.enable_retries() - self.test_post_view_queries_all_params() + self.test_post_view_all_params() - # Disable retries and run test_post_view_queries_all_params. + # Disable retries and run test_post_view_all_params. _service.disable_retries() - self.test_post_view_queries_all_params() + self.test_post_view_all_params() @responses.activate - def test_post_view_queries_value_error(self): + def test_post_view_value_error(self): """ - test_post_view_queries_value_error() + test_post_view_value_error() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString/queries') - mock_response = '{"results": [{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}]}' + url = preprocess_url('/testString/_design/testString/_view/testString') + mock_response = '{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}' responses.add( responses.POST, url, @@ -6123,69 +6372,64 @@ def test_post_view_queries_value_error(self): status=200, ) - # Construct a dict representation of a ViewQuery model - view_query_model = {} - view_query_model['att_encoding_info'] = False - view_query_model['attachments'] = False - view_query_model['conflicts'] = False - view_query_model['descending'] = False - view_query_model['include_docs'] = True - view_query_model['inclusive_end'] = True - view_query_model['limit'] = 5 - view_query_model['skip'] = 0 - view_query_model['update_seq'] = False - view_query_model['end_key'] = 'testString' - view_query_model['end_key_doc_id'] = 'testString' - view_query_model['group'] = False - view_query_model['group_level'] = 1 - view_query_model['key'] = 'testString' - view_query_model['keys'] = ['testString'] - view_query_model['reduce'] = True - view_query_model['stable'] = False - view_query_model['start_key'] = 'testString' - view_query_model['start_key_doc_id'] = 'testString' - view_query_model['update'] = 'true' - # Set up parameter values db = 'testString' ddoc = 'testString' view = 'testString' - queries = [view_query_model] + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = True + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + end_key_doc_id = 'testString' + group = False + group_level = 1 + key = 'testString' + keys = ['examplekey'] + reduce = True + stable = False + start_key = 'testString' + start_key_doc_id = 'testString' + update = 'true' # Pass in all but one required param and check for a ValueError req_param_dict = { "db": db, "ddoc": ddoc, "view": view, - "queries": queries, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_view_queries(**req_copy) + _service.post_view(**req_copy) - def test_post_view_queries_value_error_with_retries(self): - # Enable retries and run test_post_view_queries_value_error. + def test_post_view_value_error_with_retries(self): + # Enable retries and run test_post_view_value_error. _service.enable_retries() - self.test_post_view_queries_value_error() + self.test_post_view_value_error() - # Disable retries and run test_post_view_queries_value_error. + # Disable retries and run test_post_view_value_error. _service.disable_retries() - self.test_post_view_queries_value_error() + self.test_post_view_value_error() -class TestPostViewQueriesAsStream: +class TestPostViewAsStream: """ - Test Class for post_view_queries_as_stream + Test Class for post_view_as_stream """ @responses.activate - def test_post_view_queries_as_stream_all_params(self): + def test_post_view_as_stream_all_params(self): """ - post_view_queries_as_stream() + post_view_as_stream() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString/queries') + url = preprocess_url('/testString/_design/testString/_view/testString') mock_response = '{"foo": "this is a mock response for JSON streaming"}' responses.add( responses.POST, @@ -6195,41 +6439,56 @@ def test_post_view_queries_as_stream_all_params(self): status=200, ) - # Construct a dict representation of a ViewQuery model - view_query_model = {} - view_query_model['att_encoding_info'] = False - view_query_model['attachments'] = False - view_query_model['conflicts'] = False - view_query_model['descending'] = False - view_query_model['include_docs'] = True - view_query_model['inclusive_end'] = True - view_query_model['limit'] = 5 - view_query_model['skip'] = 0 - view_query_model['update_seq'] = False - view_query_model['end_key'] = 'testString' - view_query_model['end_key_doc_id'] = 'testString' - view_query_model['group'] = False - view_query_model['group_level'] = 1 - view_query_model['key'] = 'testString' - view_query_model['keys'] = ['testString'] - view_query_model['reduce'] = True - view_query_model['stable'] = False - view_query_model['start_key'] = 'testString' - view_query_model['start_key_doc_id'] = 'testString' - view_query_model['update'] = 'true' - # Set up parameter values db = 'testString' ddoc = 'testString' view = 'testString' - queries = [view_query_model] + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = True + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + end_key_doc_id = 'testString' + group = False + group_level = 1 + key = 'testString' + keys = ['examplekey'] + reduce = True + stable = False + start_key = 'testString' + start_key_doc_id = 'testString' + update = 'true' # Invoke method - response = _service.post_view_queries_as_stream( + response = _service.post_view_as_stream( db, ddoc, view, - queries, + att_encoding_info=att_encoding_info, + attachments=attachments, + conflicts=conflicts, + descending=descending, + include_docs=include_docs, + inclusive_end=inclusive_end, + limit=limit, + skip=skip, + update_seq=update_seq, + end_key=end_key, + end_key_doc_id=end_key_doc_id, + group=group, + group_level=group_level, + key=key, + keys=keys, + reduce=reduce, + stable=stable, + start_key=start_key, + start_key_doc_id=start_key_doc_id, + update=update, headers={}, ) @@ -6242,7 +6501,26 @@ def test_post_view_queries_as_stream_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['queries'] == [view_query_model] + assert req_body['att_encoding_info'] == False + assert req_body['attachments'] == False + assert req_body['conflicts'] == False + assert req_body['descending'] == False + assert req_body['include_docs'] == True + assert req_body['inclusive_end'] == True + assert req_body['limit'] == 10 + assert req_body['skip'] == 0 + assert req_body['update_seq'] == False + assert req_body['end_key'] == 'testString' + assert req_body['end_key_doc_id'] == 'testString' + assert req_body['group'] == False + assert req_body['group_level'] == 1 + assert req_body['key'] == 'testString' + assert req_body['keys'] == ['examplekey'] + assert req_body['reduce'] == True + assert req_body['stable'] == False + assert req_body['start_key'] == 'testString' + assert req_body['start_key_doc_id'] == 'testString' + assert req_body['update'] == 'true' # Verify streamed JSON response result = response.get_result() @@ -6250,22 +6528,22 @@ def test_post_view_queries_as_stream_all_params(self): response_buf = result.iter_content(chunk_size=1024) assert str(next(response_buf), "utf-8") == mock_response - def test_post_view_queries_as_stream_all_params_with_retries(self): - # Enable retries and run test_post_view_queries_as_stream_all_params. + def test_post_view_as_stream_all_params_with_retries(self): + # Enable retries and run test_post_view_as_stream_all_params. _service.enable_retries() - self.test_post_view_queries_as_stream_all_params() + self.test_post_view_as_stream_all_params() - # Disable retries and run test_post_view_queries_as_stream_all_params. + # Disable retries and run test_post_view_as_stream_all_params. _service.disable_retries() - self.test_post_view_queries_as_stream_all_params() + self.test_post_view_as_stream_all_params() @responses.activate - def test_post_view_queries_as_stream_value_error(self): + def test_post_view_as_stream_value_error(self): """ - test_post_view_queries_as_stream_value_error() + test_post_view_as_stream_value_error() """ # Set up mock - url = preprocess_url('/testString/_design/testString/_view/testString/queries') + url = preprocess_url('/testString/_design/testString/_view/testString') mock_response = '{"foo": "this is a mock response for JSON streaming"}' responses.add( responses.POST, @@ -6275,194 +6553,211 @@ def test_post_view_queries_as_stream_value_error(self): status=200, ) - # Construct a dict representation of a ViewQuery model - view_query_model = {} - view_query_model['att_encoding_info'] = False - view_query_model['attachments'] = False - view_query_model['conflicts'] = False - view_query_model['descending'] = False - view_query_model['include_docs'] = True - view_query_model['inclusive_end'] = True - view_query_model['limit'] = 5 - view_query_model['skip'] = 0 - view_query_model['update_seq'] = False - view_query_model['end_key'] = 'testString' - view_query_model['end_key_doc_id'] = 'testString' - view_query_model['group'] = False - view_query_model['group_level'] = 1 - view_query_model['key'] = 'testString' - view_query_model['keys'] = ['testString'] - view_query_model['reduce'] = True - view_query_model['stable'] = False - view_query_model['start_key'] = 'testString' - view_query_model['start_key_doc_id'] = 'testString' - view_query_model['update'] = 'true' - # Set up parameter values db = 'testString' ddoc = 'testString' view = 'testString' - queries = [view_query_model] + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = True + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + end_key_doc_id = 'testString' + group = False + group_level = 1 + key = 'testString' + keys = ['examplekey'] + reduce = True + stable = False + start_key = 'testString' + start_key_doc_id = 'testString' + update = 'true' # Pass in all but one required param and check for a ValueError req_param_dict = { "db": db, "ddoc": ddoc, "view": view, - "queries": queries, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_view_queries_as_stream(**req_copy) + _service.post_view_as_stream(**req_copy) - def test_post_view_queries_as_stream_value_error_with_retries(self): - # Enable retries and run test_post_view_queries_as_stream_value_error. + def test_post_view_as_stream_value_error_with_retries(self): + # Enable retries and run test_post_view_as_stream_value_error. _service.enable_retries() - self.test_post_view_queries_as_stream_value_error() + self.test_post_view_as_stream_value_error() - # Disable retries and run test_post_view_queries_as_stream_value_error. + # Disable retries and run test_post_view_as_stream_value_error. _service.disable_retries() - self.test_post_view_queries_as_stream_value_error() - - -# endregion -############################################################################## -# End of Service: Views -############################################################################## - -############################################################################## -# Start of Service: PartitionedDatabases -############################################################################## -# region - - -class TestNewInstance: - """ - Test Class for new_instance - """ - - def test_new_instance(self): - """ - new_instance() - """ - os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' - - service = CloudantV1.new_instance( - service_name='TEST_SERVICE', - ) - - assert service is not None - assert isinstance(service, CloudantV1) - - def test_new_instance_without_authenticator(self): - """ - new_instance_without_authenticator() - """ - with pytest.raises(ValueError, match='authenticator must be provided'): - service = CloudantV1.new_instance( - service_name='TEST_SERVICE_NOT_FOUND', - ) + self.test_post_view_as_stream_value_error() -class TestGetPartitionInformation: +class TestPostViewQueries: """ - Test Class for get_partition_information + Test Class for post_view_queries """ @responses.activate - def test_get_partition_information_all_params(self): + def test_post_view_queries_all_params(self): """ - get_partition_information() + post_view_queries() """ # Set up mock - url = preprocess_url('/testString/_partition/testString') - mock_response = '{"db_name": "db_name", "doc_count": 0, "doc_del_count": 0, "partition": "partition", "partitioned_indexes": {"count": 0, "indexes": {"search": 0, "view": 0}, "limit": 0}, "sizes": {"active": 0, "external": 0}}' + url = preprocess_url('/testString/_design/testString/_view/testString/queries') + mock_response = '{"results": [{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}]}' responses.add( - responses.GET, + responses.POST, url, body=mock_response, content_type='application/json', status=200, ) + # Construct a dict representation of a ViewQuery model + view_query_model = {} + view_query_model['att_encoding_info'] = False + view_query_model['attachments'] = False + view_query_model['conflicts'] = False + view_query_model['descending'] = False + view_query_model['include_docs'] = True + view_query_model['inclusive_end'] = True + view_query_model['limit'] = 5 + view_query_model['skip'] = 0 + view_query_model['update_seq'] = False + view_query_model['end_key'] = 'testString' + view_query_model['end_key_doc_id'] = 'testString' + view_query_model['group'] = False + view_query_model['group_level'] = 1 + view_query_model['key'] = 'testString' + view_query_model['keys'] = ['testString'] + view_query_model['reduce'] = True + view_query_model['stable'] = False + view_query_model['start_key'] = 'testString' + view_query_model['start_key_doc_id'] = 'testString' + view_query_model['update'] = 'true' + # Set up parameter values db = 'testString' - partition_key = 'testString' + ddoc = 'testString' + view = 'testString' + queries = [view_query_model] # Invoke method - response = _service.get_partition_information( + response = _service.post_view_queries( db, - partition_key, + ddoc, + view, + queries, headers={}, ) # Check for correct operation assert len(responses.calls) == 1 assert response.status_code == 200 + # Decompress gzip compressed request body. + raw_body = responses.calls[0].request.body + responses.calls[0].request.body = gzip.decompress(raw_body.read() if isinstance(raw_body, io.IOBase) else raw_body) - def test_get_partition_information_all_params_with_retries(self): - # Enable retries and run test_get_partition_information_all_params. + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['queries'] == [view_query_model] + + def test_post_view_queries_all_params_with_retries(self): + # Enable retries and run test_post_view_queries_all_params. _service.enable_retries() - self.test_get_partition_information_all_params() + self.test_post_view_queries_all_params() - # Disable retries and run test_get_partition_information_all_params. + # Disable retries and run test_post_view_queries_all_params. _service.disable_retries() - self.test_get_partition_information_all_params() + self.test_post_view_queries_all_params() @responses.activate - def test_get_partition_information_value_error(self): + def test_post_view_queries_value_error(self): """ - test_get_partition_information_value_error() + test_post_view_queries_value_error() """ # Set up mock - url = preprocess_url('/testString/_partition/testString') - mock_response = '{"db_name": "db_name", "doc_count": 0, "doc_del_count": 0, "partition": "partition", "partitioned_indexes": {"count": 0, "indexes": {"search": 0, "view": 0}, "limit": 0}, "sizes": {"active": 0, "external": 0}}' + url = preprocess_url('/testString/_design/testString/_view/testString/queries') + mock_response = '{"results": [{"total_rows": 0, "update_seq": "update_seq", "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "anyValue", "value": "anyValue"}]}]}' responses.add( - responses.GET, + responses.POST, url, body=mock_response, content_type='application/json', status=200, ) - # Set up parameter values - db = 'testString' - partition_key = 'testString' + # Construct a dict representation of a ViewQuery model + view_query_model = {} + view_query_model['att_encoding_info'] = False + view_query_model['attachments'] = False + view_query_model['conflicts'] = False + view_query_model['descending'] = False + view_query_model['include_docs'] = True + view_query_model['inclusive_end'] = True + view_query_model['limit'] = 5 + view_query_model['skip'] = 0 + view_query_model['update_seq'] = False + view_query_model['end_key'] = 'testString' + view_query_model['end_key_doc_id'] = 'testString' + view_query_model['group'] = False + view_query_model['group_level'] = 1 + view_query_model['key'] = 'testString' + view_query_model['keys'] = ['testString'] + view_query_model['reduce'] = True + view_query_model['stable'] = False + view_query_model['start_key'] = 'testString' + view_query_model['start_key_doc_id'] = 'testString' + view_query_model['update'] = 'true' + + # Set up parameter values + db = 'testString' + ddoc = 'testString' + view = 'testString' + queries = [view_query_model] # Pass in all but one required param and check for a ValueError req_param_dict = { "db": db, - "partition_key": partition_key, + "ddoc": ddoc, + "view": view, + "queries": queries, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.get_partition_information(**req_copy) + _service.post_view_queries(**req_copy) - def test_get_partition_information_value_error_with_retries(self): - # Enable retries and run test_get_partition_information_value_error. + def test_post_view_queries_value_error_with_retries(self): + # Enable retries and run test_post_view_queries_value_error. _service.enable_retries() - self.test_get_partition_information_value_error() + self.test_post_view_queries_value_error() - # Disable retries and run test_get_partition_information_value_error. + # Disable retries and run test_post_view_queries_value_error. _service.disable_retries() - self.test_get_partition_information_value_error() + self.test_post_view_queries_value_error() -class TestPostPartitionAllDocs: +class TestPostViewQueriesAsStream: """ - Test Class for post_partition_all_docs + Test Class for post_view_queries_as_stream """ @responses.activate - def test_post_partition_all_docs_all_params(self): + def test_post_view_queries_as_stream_all_params(self): """ - post_partition_all_docs() + post_view_queries_as_stream() """ # Set up mock - url = preprocess_url('/testString/_partition/testString/_all_docs') - mock_response = '{"total_rows": 0, "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "key", "value": {"deleted": false, "rev": "rev"}}], "update_seq": "update_seq"}' + url = preprocess_url('/testString/_design/testString/_view/testString/queries') + mock_response = '{"foo": "this is a mock response for JSON streaming"}' responses.add( responses.POST, url, @@ -6471,40 +6766,41 @@ def test_post_partition_all_docs_all_params(self): status=200, ) + # Construct a dict representation of a ViewQuery model + view_query_model = {} + view_query_model['att_encoding_info'] = False + view_query_model['attachments'] = False + view_query_model['conflicts'] = False + view_query_model['descending'] = False + view_query_model['include_docs'] = True + view_query_model['inclusive_end'] = True + view_query_model['limit'] = 5 + view_query_model['skip'] = 0 + view_query_model['update_seq'] = False + view_query_model['end_key'] = 'testString' + view_query_model['end_key_doc_id'] = 'testString' + view_query_model['group'] = False + view_query_model['group_level'] = 1 + view_query_model['key'] = 'testString' + view_query_model['keys'] = ['testString'] + view_query_model['reduce'] = True + view_query_model['stable'] = False + view_query_model['start_key'] = 'testString' + view_query_model['start_key_doc_id'] = 'testString' + view_query_model['update'] = 'true' + # Set up parameter values db = 'testString' - partition_key = 'testString' - att_encoding_info = False - attachments = False - conflicts = False - descending = False - include_docs = False - inclusive_end = True - limit = 10 - skip = 0 - update_seq = False - end_key = 'testString' - key = 'testString' - keys = ['testString'] - start_key = '0007741142412418284' + ddoc = 'testString' + view = 'testString' + queries = [view_query_model] # Invoke method - response = _service.post_partition_all_docs( + response = _service.post_view_queries_as_stream( db, - partition_key, - att_encoding_info=att_encoding_info, - attachments=attachments, - conflicts=conflicts, - descending=descending, - include_docs=include_docs, - inclusive_end=inclusive_end, - limit=limit, - skip=skip, - update_seq=update_seq, - end_key=end_key, - key=key, - keys=keys, - start_key=start_key, + ddoc, + view, + queries, headers={}, ) @@ -6517,37 +6813,31 @@ def test_post_partition_all_docs_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['att_encoding_info'] == False - assert req_body['attachments'] == False - assert req_body['conflicts'] == False - assert req_body['descending'] == False - assert req_body['include_docs'] == False - assert req_body['inclusive_end'] == True - assert req_body['limit'] == 10 - assert req_body['skip'] == 0 - assert req_body['update_seq'] == False - assert req_body['end_key'] == 'testString' - assert req_body['key'] == 'testString' - assert req_body['keys'] == ['testString'] - assert req_body['start_key'] == '0007741142412418284' + assert req_body['queries'] == [view_query_model] - def test_post_partition_all_docs_all_params_with_retries(self): - # Enable retries and run test_post_partition_all_docs_all_params. + # Verify streamed JSON response + result = response.get_result() + assert isinstance(result, requests.models.Response) + response_buf = result.iter_content(chunk_size=1024) + assert str(next(response_buf), "utf-8") == mock_response + + def test_post_view_queries_as_stream_all_params_with_retries(self): + # Enable retries and run test_post_view_queries_as_stream_all_params. _service.enable_retries() - self.test_post_partition_all_docs_all_params() + self.test_post_view_queries_as_stream_all_params() - # Disable retries and run test_post_partition_all_docs_all_params. + # Disable retries and run test_post_view_queries_as_stream_all_params. _service.disable_retries() - self.test_post_partition_all_docs_all_params() + self.test_post_view_queries_as_stream_all_params() @responses.activate - def test_post_partition_all_docs_value_error(self): + def test_post_view_queries_as_stream_value_error(self): """ - test_post_partition_all_docs_value_error() + test_post_view_queries_as_stream_value_error() """ # Set up mock - url = preprocess_url('/testString/_partition/testString/_all_docs') - mock_response = '{"total_rows": 0, "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "key", "value": {"deleted": false, "rev": "rev"}}], "update_seq": "update_seq"}' + url = preprocess_url('/testString/_design/testString/_view/testString/queries') + mock_response = '{"foo": "this is a mock response for JSON streaming"}' responses.add( responses.POST, url, @@ -6556,83 +6846,221 @@ def test_post_partition_all_docs_value_error(self): status=200, ) + # Construct a dict representation of a ViewQuery model + view_query_model = {} + view_query_model['att_encoding_info'] = False + view_query_model['attachments'] = False + view_query_model['conflicts'] = False + view_query_model['descending'] = False + view_query_model['include_docs'] = True + view_query_model['inclusive_end'] = True + view_query_model['limit'] = 5 + view_query_model['skip'] = 0 + view_query_model['update_seq'] = False + view_query_model['end_key'] = 'testString' + view_query_model['end_key_doc_id'] = 'testString' + view_query_model['group'] = False + view_query_model['group_level'] = 1 + view_query_model['key'] = 'testString' + view_query_model['keys'] = ['testString'] + view_query_model['reduce'] = True + view_query_model['stable'] = False + view_query_model['start_key'] = 'testString' + view_query_model['start_key_doc_id'] = 'testString' + view_query_model['update'] = 'true' + # Set up parameter values db = 'testString' - partition_key = 'testString' - att_encoding_info = False - attachments = False - conflicts = False - descending = False - include_docs = False - inclusive_end = True - limit = 10 - skip = 0 - update_seq = False - end_key = 'testString' - key = 'testString' - keys = ['testString'] - start_key = '0007741142412418284' + ddoc = 'testString' + view = 'testString' + queries = [view_query_model] # Pass in all but one required param and check for a ValueError req_param_dict = { "db": db, - "partition_key": partition_key, + "ddoc": ddoc, + "view": view, + "queries": queries, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_partition_all_docs(**req_copy) + _service.post_view_queries_as_stream(**req_copy) - def test_post_partition_all_docs_value_error_with_retries(self): - # Enable retries and run test_post_partition_all_docs_value_error. + def test_post_view_queries_as_stream_value_error_with_retries(self): + # Enable retries and run test_post_view_queries_as_stream_value_error. _service.enable_retries() - self.test_post_partition_all_docs_value_error() + self.test_post_view_queries_as_stream_value_error() - # Disable retries and run test_post_partition_all_docs_value_error. + # Disable retries and run test_post_view_queries_as_stream_value_error. _service.disable_retries() - self.test_post_partition_all_docs_value_error() + self.test_post_view_queries_as_stream_value_error() -class TestPostPartitionAllDocsAsStream: +# endregion +############################################################################## +# End of Service: Views +############################################################################## + +############################################################################## +# Start of Service: PartitionedDatabases +############################################################################## +# region + + +class TestNewInstance: """ - Test Class for post_partition_all_docs_as_stream + Test Class for new_instance """ - @responses.activate - def test_post_partition_all_docs_as_stream_all_params(self): + def test_new_instance(self): """ - post_partition_all_docs_as_stream() + new_instance() """ - # Set up mock - url = preprocess_url('/testString/_partition/testString/_all_docs') - mock_response = '{"foo": "this is a mock response for JSON streaming"}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, + os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' + + service = CloudantV1.new_instance( + service_name='TEST_SERVICE', ) - # Set up parameter values - db = 'testString' - partition_key = 'testString' - att_encoding_info = False - attachments = False - conflicts = False - descending = False - include_docs = False - inclusive_end = True - limit = 10 - skip = 0 - update_seq = False - end_key = 'testString' - key = 'testString' + assert service is not None + assert isinstance(service, CloudantV1) + + def test_new_instance_without_authenticator(self): + """ + new_instance_without_authenticator() + """ + with pytest.raises(ValueError, match='authenticator must be provided'): + service = CloudantV1.new_instance( + service_name='TEST_SERVICE_NOT_FOUND', + ) + + +class TestGetPartitionInformation: + """ + Test Class for get_partition_information + """ + + @responses.activate + def test_get_partition_information_all_params(self): + """ + get_partition_information() + """ + # Set up mock + url = preprocess_url('/testString/_partition/testString') + mock_response = '{"db_name": "db_name", "doc_count": 0, "doc_del_count": 0, "partition": "partition", "partitioned_indexes": {"count": 0, "indexes": {"search": 0, "view": 0}, "limit": 0}, "sizes": {"active": 0, "external": 0}}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + db = 'testString' + partition_key = 'testString' + + # Invoke method + response = _service.get_partition_information( + db, + partition_key, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + + def test_get_partition_information_all_params_with_retries(self): + # Enable retries and run test_get_partition_information_all_params. + _service.enable_retries() + self.test_get_partition_information_all_params() + + # Disable retries and run test_get_partition_information_all_params. + _service.disable_retries() + self.test_get_partition_information_all_params() + + @responses.activate + def test_get_partition_information_value_error(self): + """ + test_get_partition_information_value_error() + """ + # Set up mock + url = preprocess_url('/testString/_partition/testString') + mock_response = '{"db_name": "db_name", "doc_count": 0, "doc_del_count": 0, "partition": "partition", "partitioned_indexes": {"count": 0, "indexes": {"search": 0, "view": 0}, "limit": 0}, "sizes": {"active": 0, "external": 0}}' + responses.add( + responses.GET, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + db = 'testString' + partition_key = 'testString' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "db": db, + "partition_key": partition_key, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.get_partition_information(**req_copy) + + def test_get_partition_information_value_error_with_retries(self): + # Enable retries and run test_get_partition_information_value_error. + _service.enable_retries() + self.test_get_partition_information_value_error() + + # Disable retries and run test_get_partition_information_value_error. + _service.disable_retries() + self.test_get_partition_information_value_error() + + +class TestPostPartitionAllDocs: + """ + Test Class for post_partition_all_docs + """ + + @responses.activate + def test_post_partition_all_docs_all_params(self): + """ + post_partition_all_docs() + """ + # Set up mock + url = preprocess_url('/testString/_partition/testString/_all_docs') + mock_response = '{"total_rows": 0, "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "key", "value": {"deleted": false, "rev": "rev"}}], "update_seq": "update_seq"}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + db = 'testString' + partition_key = 'testString' + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = False + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + key = 'testString' keys = ['testString'] start_key = '0007741142412418284' # Invoke method - response = _service.post_partition_all_docs_as_stream( + response = _service.post_partition_all_docs( db, partition_key, att_encoding_info=att_encoding_info, @@ -6674,29 +7102,23 @@ def test_post_partition_all_docs_as_stream_all_params(self): assert req_body['keys'] == ['testString'] assert req_body['start_key'] == '0007741142412418284' - # Verify streamed JSON response - result = response.get_result() - assert isinstance(result, requests.models.Response) - response_buf = result.iter_content(chunk_size=1024) - assert str(next(response_buf), "utf-8") == mock_response - - def test_post_partition_all_docs_as_stream_all_params_with_retries(self): - # Enable retries and run test_post_partition_all_docs_as_stream_all_params. + def test_post_partition_all_docs_all_params_with_retries(self): + # Enable retries and run test_post_partition_all_docs_all_params. _service.enable_retries() - self.test_post_partition_all_docs_as_stream_all_params() + self.test_post_partition_all_docs_all_params() - # Disable retries and run test_post_partition_all_docs_as_stream_all_params. + # Disable retries and run test_post_partition_all_docs_all_params. _service.disable_retries() - self.test_post_partition_all_docs_as_stream_all_params() + self.test_post_partition_all_docs_all_params() @responses.activate - def test_post_partition_all_docs_as_stream_value_error(self): + def test_post_partition_all_docs_value_error(self): """ - test_post_partition_all_docs_as_stream_value_error() + test_post_partition_all_docs_value_error() """ # Set up mock url = preprocess_url('/testString/_partition/testString/_all_docs') - mock_response = '{"foo": "this is a mock response for JSON streaming"}' + mock_response = '{"total_rows": 0, "rows": [{"caused_by": "caused_by", "error": "error", "reason": "reason", "ref": 0, "doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "id": "id", "key": "key", "value": {"deleted": false, "rev": "rev"}}], "update_seq": "update_seq"}' responses.add( responses.POST, url, @@ -6730,31 +7152,31 @@ def test_post_partition_all_docs_as_stream_value_error(self): for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_partition_all_docs_as_stream(**req_copy) + _service.post_partition_all_docs(**req_copy) - def test_post_partition_all_docs_as_stream_value_error_with_retries(self): - # Enable retries and run test_post_partition_all_docs_as_stream_value_error. + def test_post_partition_all_docs_value_error_with_retries(self): + # Enable retries and run test_post_partition_all_docs_value_error. _service.enable_retries() - self.test_post_partition_all_docs_as_stream_value_error() + self.test_post_partition_all_docs_value_error() - # Disable retries and run test_post_partition_all_docs_as_stream_value_error. + # Disable retries and run test_post_partition_all_docs_value_error. _service.disable_retries() - self.test_post_partition_all_docs_as_stream_value_error() + self.test_post_partition_all_docs_value_error() -class TestPostPartitionSearch: +class TestPostPartitionAllDocsAsStream: """ - Test Class for post_partition_search + Test Class for post_partition_all_docs_as_stream """ @responses.activate - def test_post_partition_search_all_params(self): + def test_post_partition_all_docs_as_stream_all_params(self): """ - post_partition_search() + post_partition_all_docs_as_stream() """ # Set up mock - url = preprocess_url('/testString/_partition/testString/_design/testString/_search/testString') - mock_response = '{"total_rows": 0, "bookmark": "bookmark", "by": "by", "counts": {"mapKey": {"mapKey": 0}}, "ranges": {"mapKey": {"mapKey": 0}}, "rows": [{"doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "fields": {"anyKey": "anyValue"}, "highlights": {"mapKey": ["inner"]}, "id": "id"}], "groups": [{"total_rows": 0, "bookmark": "bookmark", "by": "by", "counts": {"mapKey": {"mapKey": 0}}, "ranges": {"mapKey": {"mapKey": 0}}, "rows": [{"doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "fields": {"anyKey": "anyValue"}, "highlights": {"mapKey": ["inner"]}, "id": "id"}]}]}' + url = preprocess_url('/testString/_partition/testString/_all_docs') + mock_response = '{"foo": "this is a mock response for JSON streaming"}' responses.add( responses.POST, url, @@ -6766,39 +7188,37 @@ def test_post_partition_search_all_params(self): # Set up parameter values db = 'testString' partition_key = 'testString' - ddoc = 'testString' - index = 'testString' - query = 'name:Jane* AND active:True' - bookmark = 'testString' - highlight_fields = ['testString'] - highlight_number = 1 - highlight_post_tag = '' - highlight_pre_tag = '' - highlight_size = 100 + att_encoding_info = False + attachments = False + conflicts = False + descending = False include_docs = False - include_fields = ['testString'] - limit = 3 - sort = ['testString'] - stale = 'ok' + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + key = 'testString' + keys = ['testString'] + start_key = '0007741142412418284' # Invoke method - response = _service.post_partition_search( + response = _service.post_partition_all_docs_as_stream( db, partition_key, - ddoc, - index, - query, - bookmark=bookmark, - highlight_fields=highlight_fields, - highlight_number=highlight_number, - highlight_post_tag=highlight_post_tag, - highlight_pre_tag=highlight_pre_tag, - highlight_size=highlight_size, + att_encoding_info=att_encoding_info, + attachments=attachments, + conflicts=conflicts, + descending=descending, include_docs=include_docs, - include_fields=include_fields, + inclusive_end=inclusive_end, limit=limit, - sort=sort, - stale=stale, + skip=skip, + update_seq=update_seq, + end_key=end_key, + key=key, + keys=keys, + start_key=start_key, headers={}, ) @@ -6811,21 +7231,172 @@ def test_post_partition_search_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['query'] == 'name:Jane* AND active:True' - assert req_body['bookmark'] == 'testString' - assert req_body['highlight_fields'] == ['testString'] - assert req_body['highlight_number'] == 1 - assert req_body['highlight_post_tag'] == '' - assert req_body['highlight_pre_tag'] == '' - assert req_body['highlight_size'] == 100 + assert req_body['att_encoding_info'] == False + assert req_body['attachments'] == False + assert req_body['conflicts'] == False + assert req_body['descending'] == False assert req_body['include_docs'] == False - assert req_body['include_fields'] == ['testString'] - assert req_body['limit'] == 3 - assert req_body['sort'] == ['testString'] - assert req_body['stale'] == 'ok' + assert req_body['inclusive_end'] == True + assert req_body['limit'] == 10 + assert req_body['skip'] == 0 + assert req_body['update_seq'] == False + assert req_body['end_key'] == 'testString' + assert req_body['key'] == 'testString' + assert req_body['keys'] == ['testString'] + assert req_body['start_key'] == '0007741142412418284' - def test_post_partition_search_all_params_with_retries(self): - # Enable retries and run test_post_partition_search_all_params. + # Verify streamed JSON response + result = response.get_result() + assert isinstance(result, requests.models.Response) + response_buf = result.iter_content(chunk_size=1024) + assert str(next(response_buf), "utf-8") == mock_response + + def test_post_partition_all_docs_as_stream_all_params_with_retries(self): + # Enable retries and run test_post_partition_all_docs_as_stream_all_params. + _service.enable_retries() + self.test_post_partition_all_docs_as_stream_all_params() + + # Disable retries and run test_post_partition_all_docs_as_stream_all_params. + _service.disable_retries() + self.test_post_partition_all_docs_as_stream_all_params() + + @responses.activate + def test_post_partition_all_docs_as_stream_value_error(self): + """ + test_post_partition_all_docs_as_stream_value_error() + """ + # Set up mock + url = preprocess_url('/testString/_partition/testString/_all_docs') + mock_response = '{"foo": "this is a mock response for JSON streaming"}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + db = 'testString' + partition_key = 'testString' + att_encoding_info = False + attachments = False + conflicts = False + descending = False + include_docs = False + inclusive_end = True + limit = 10 + skip = 0 + update_seq = False + end_key = 'testString' + key = 'testString' + keys = ['testString'] + start_key = '0007741142412418284' + + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "db": db, + "partition_key": partition_key, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.post_partition_all_docs_as_stream(**req_copy) + + def test_post_partition_all_docs_as_stream_value_error_with_retries(self): + # Enable retries and run test_post_partition_all_docs_as_stream_value_error. + _service.enable_retries() + self.test_post_partition_all_docs_as_stream_value_error() + + # Disable retries and run test_post_partition_all_docs_as_stream_value_error. + _service.disable_retries() + self.test_post_partition_all_docs_as_stream_value_error() + + +class TestPostPartitionSearch: + """ + Test Class for post_partition_search + """ + + @responses.activate + def test_post_partition_search_all_params(self): + """ + post_partition_search() + """ + # Set up mock + url = preprocess_url('/testString/_partition/testString/_design/testString/_search/testString') + mock_response = '{"total_rows": 0, "bookmark": "bookmark", "by": "by", "counts": {"mapKey": {"mapKey": 0}}, "ranges": {"mapKey": {"mapKey": 0}}, "rows": [{"doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "fields": {"anyKey": "anyValue"}, "highlights": {"mapKey": ["inner"]}, "id": "id"}], "groups": [{"total_rows": 0, "bookmark": "bookmark", "by": "by", "counts": {"mapKey": {"mapKey": 0}}, "ranges": {"mapKey": {"mapKey": 0}}, "rows": [{"doc": {"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}]}, "fields": {"anyKey": "anyValue"}, "highlights": {"mapKey": ["inner"]}, "id": "id"}]}]}' + responses.add( + responses.POST, + url, + body=mock_response, + content_type='application/json', + status=200, + ) + + # Set up parameter values + db = 'testString' + partition_key = 'testString' + ddoc = 'testString' + index = 'testString' + query = 'name:Jane* AND active:True' + bookmark = 'testString' + highlight_fields = ['testString'] + highlight_number = 1 + highlight_post_tag = '' + highlight_pre_tag = '' + highlight_size = 100 + include_docs = False + include_fields = ['testString'] + limit = 3 + sort = ['testString'] + stale = 'ok' + + # Invoke method + response = _service.post_partition_search( + db, + partition_key, + ddoc, + index, + query, + bookmark=bookmark, + highlight_fields=highlight_fields, + highlight_number=highlight_number, + highlight_post_tag=highlight_post_tag, + highlight_pre_tag=highlight_pre_tag, + highlight_size=highlight_size, + include_docs=include_docs, + include_fields=include_fields, + limit=limit, + sort=sort, + stale=stale, + headers={}, + ) + + # Check for correct operation + assert len(responses.calls) == 1 + assert response.status_code == 200 + # Decompress gzip compressed request body. + raw_body = responses.calls[0].request.body + responses.calls[0].request.body = gzip.decompress(raw_body.read() if isinstance(raw_body, io.IOBase) else raw_body) + + # Validate body params + req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) + assert req_body['query'] == 'name:Jane* AND active:True' + assert req_body['bookmark'] == 'testString' + assert req_body['highlight_fields'] == ['testString'] + assert req_body['highlight_number'] == 1 + assert req_body['highlight_post_tag'] == '' + assert req_body['highlight_pre_tag'] == '' + assert req_body['highlight_size'] == 100 + assert req_body['include_docs'] == False + assert req_body['include_fields'] == ['testString'] + assert req_body['limit'] == 3 + assert req_body['sort'] == ['testString'] + assert req_body['stale'] == 'ok' + + def test_post_partition_search_all_params_with_retries(self): + # Enable retries and run test_post_partition_search_all_params. _service.enable_retries() self.test_post_partition_search_all_params() @@ -9196,7 +9767,7 @@ def test_get_search_info_all_params(self): """ # Set up mock url = preprocess_url('/testString/_design/testString/_search_info/testString') - mock_response = '{"name": "name", "search_index": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature"}}' + mock_response = '{"name": "name", "search_index": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature", "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}}}' responses.add( responses.GET, url, @@ -9238,7 +9809,7 @@ def test_get_search_info_value_error(self): """ # Set up mock url = preprocess_url('/testString/_design/testString/_search_info/testString') - mock_response = '{"name": "name", "search_index": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature"}}' + mock_response = '{"name": "name", "search_index": {"committed_seq": 0, "disk_size": 0, "doc_count": 0, "doc_del_count": 0, "pending_seq": 0, "signature": "signature", "updates_pending": {"copies": 0, "copies_expected": 0, "maximum": 0, "minimum": 0, "preferred": 0, "total": 0}}}' responses.add( responses.GET, url, @@ -9632,10 +10203,19 @@ def test_post_replicator_all_params(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -9671,6 +10251,7 @@ def test_post_replicator_all_params(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -9775,10 +10356,19 @@ def test_post_replicator_required_params(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -9814,6 +10404,7 @@ def test_post_replicator_required_params(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -9912,10 +10503,19 @@ def test_post_replicator_value_error(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -9951,6 +10551,7 @@ def test_post_replicator_value_error(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -10131,7 +10732,7 @@ def test_get_replication_document_all_params(self): """ # Set up mock url = preprocess_url('/_replicator/testString') - mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' + mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "request_compression": "none", "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' responses.add( responses.GET, url, @@ -10204,7 +10805,7 @@ def test_get_replication_document_required_params(self): """ # Set up mock url = preprocess_url('/_replicator/testString') - mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' + mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "request_compression": "none", "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' responses.add( responses.GET, url, @@ -10242,7 +10843,7 @@ def test_get_replication_document_value_error(self): """ # Set up mock url = preprocess_url('/_replicator/testString') - mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' + mock_response = '{"_attachments": {"mapKey": {"content_type": "content_type", "data": "VGhpcyBpcyBhIG1vY2sgYnl0ZSBhcnJheSB2YWx1ZS4=", "digest": "digest", "encoded_length": 0, "encoding": "encoding", "follows": false, "length": 0, "revpos": 1, "stub": true}}, "_conflicts": ["conflicts"], "_deleted": true, "_deleted_conflicts": ["deleted_conflicts"], "_id": "_id", "_local_seq": "_local_seq", "_rev": "_rev", "_revisions": {"ids": ["ids"], "start": 1}, "_revs_info": [{"rev": "rev", "status": "available"}], "cancel": true, "checkpoint_interval": 30000, "connection_timeout": 30000, "continuous": false, "create_target": false, "create_target_params": {"n": 3, "partitioned": false, "q": 16}, "doc_ids": ["doc_ids"], "filter": "filter", "http_connections": 20, "owner": "owner", "query_params": {"mapKey": "inner"}, "request_compression": "none", "retries_per_request": 5, "selector": {"anyKey": "anyValue"}, "since_seq": "since_seq", "socket_options": "socket_options", "source": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "source_proxy": "source_proxy", "target": {"auth": {"basic": {"password": "password", "username": "username"}, "iam": {"api_key": "api_key"}, "ibm": {"iam": {"api_key": "api_key"}}}, "headers": {"mapKey": "inner"}, "url": "url"}, "target_proxy": "target_proxy", "use_bulk_get": true, "use_checkpoints": true, "user_ctx": {"db": "db", "name": "name", "roles": ["_reader"]}, "winning_revs_only": false, "worker_batch_size": 500, "worker_processes": 4}' responses.add( responses.GET, url, @@ -10331,10 +10932,19 @@ def test_put_replication_document_all_params(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -10370,6 +10980,7 @@ def test_put_replication_document_all_params(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -10484,10 +11095,19 @@ def test_put_replication_document_required_params(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -10523,6 +11143,7 @@ def test_put_replication_document_required_params(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -10623,10 +11244,19 @@ def test_put_replication_document_value_error(self): replication_database_auth_iam_model = {} replication_database_auth_iam_model['api_key'] = 'testString' + # Construct a dict representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model = {} + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a dict representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model = {} + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a dict representation of a ReplicationDatabaseAuth model replication_database_auth_model = {} replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a dict representation of a ReplicationDatabase model replication_database_model = {} @@ -10662,6 +11292,7 @@ def test_put_replication_document_value_error(self): replication_document_model['http_connections'] = 10 replication_document_model['owner'] = 'testString' replication_document_model['query_params'] = {'key1': 'testString'} + replication_document_model['request_compression'] = 'gzip' replication_document_model['retries_per_request'] = 3 replication_document_model['selector'] = {'_id': {'$regex': 'docid'}} replication_document_model['since_seq'] = '34-g1AAAAGjeJzLYWBgYMlgTmGQT0lKzi9KdU' @@ -12990,315 +13621,18 @@ def test_put_local_document_value_error_with_retries(self): _service.enable_retries() self.test_put_local_document_value_error() - # Disable retries and run test_put_local_document_value_error. - _service.disable_retries() - self.test_put_local_document_value_error() - - -# endregion -############################################################################## -# End of Service: LocalDocuments -############################################################################## - -############################################################################## -# Start of Service: DatabaseDetails -############################################################################## -# region - - -class TestNewInstance: - """ - Test Class for new_instance - """ - - def test_new_instance(self): - """ - new_instance() - """ - os.environ['TEST_SERVICE_AUTH_TYPE'] = 'noAuth' - - service = CloudantV1.new_instance( - service_name='TEST_SERVICE', - ) - - assert service is not None - assert isinstance(service, CloudantV1) - - def test_new_instance_without_authenticator(self): - """ - new_instance_without_authenticator() - """ - with pytest.raises(ValueError, match='authenticator must be provided'): - service = CloudantV1.new_instance( - service_name='TEST_SERVICE_NOT_FOUND', - ) - - -class TestPostRevsDiff: - """ - Test Class for post_revs_diff - """ - - @responses.activate - def test_post_revs_diff_all_params(self): - """ - post_revs_diff() - """ - # Set up mock - url = preprocess_url('/testString/_revs_diff') - mock_response = '{"mapKey": {"missing": ["missing"], "possible_ancestors": ["possible_ancestors"]}}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - document_revisions = {'key1': ['testString']} - - # Invoke method - response = _service.post_revs_diff( - db, - document_revisions, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - # Decompress gzip compressed request body. - raw_body = responses.calls[0].request.body - responses.calls[0].request.body = gzip.decompress(raw_body.read() if isinstance(raw_body, io.IOBase) else raw_body) - - # Validate body params - req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body == document_revisions - - def test_post_revs_diff_all_params_with_retries(self): - # Enable retries and run test_post_revs_diff_all_params. - _service.enable_retries() - self.test_post_revs_diff_all_params() - - # Disable retries and run test_post_revs_diff_all_params. - _service.disable_retries() - self.test_post_revs_diff_all_params() - - @responses.activate - def test_post_revs_diff_value_error(self): - """ - test_post_revs_diff_value_error() - """ - # Set up mock - url = preprocess_url('/testString/_revs_diff') - mock_response = '{"mapKey": {"missing": ["missing"], "possible_ancestors": ["possible_ancestors"]}}' - responses.add( - responses.POST, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - document_revisions = {'key1': ['testString']} - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "db": db, - "document_revisions": document_revisions, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.post_revs_diff(**req_copy) - - def test_post_revs_diff_value_error_with_retries(self): - # Enable retries and run test_post_revs_diff_value_error. - _service.enable_retries() - self.test_post_revs_diff_value_error() - - # Disable retries and run test_post_revs_diff_value_error. - _service.disable_retries() - self.test_post_revs_diff_value_error() - - -class TestGetShardsInformation: - """ - Test Class for get_shards_information - """ - - @responses.activate - def test_get_shards_information_all_params(self): - """ - get_shards_information() - """ - # Set up mock - url = preprocess_url('/testString/_shards') - mock_response = '{"shards": {"mapKey": ["inner"]}}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - - # Invoke method - response = _service.get_shards_information( - db, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_get_shards_information_all_params_with_retries(self): - # Enable retries and run test_get_shards_information_all_params. - _service.enable_retries() - self.test_get_shards_information_all_params() - - # Disable retries and run test_get_shards_information_all_params. - _service.disable_retries() - self.test_get_shards_information_all_params() - - @responses.activate - def test_get_shards_information_value_error(self): - """ - test_get_shards_information_value_error() - """ - # Set up mock - url = preprocess_url('/testString/_shards') - mock_response = '{"shards": {"mapKey": ["inner"]}}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "db": db, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.get_shards_information(**req_copy) - - def test_get_shards_information_value_error_with_retries(self): - # Enable retries and run test_get_shards_information_value_error. - _service.enable_retries() - self.test_get_shards_information_value_error() - - # Disable retries and run test_get_shards_information_value_error. - _service.disable_retries() - self.test_get_shards_information_value_error() - - -class TestGetDocumentShardsInfo: - """ - Test Class for get_document_shards_info - """ - - @responses.activate - def test_get_document_shards_info_all_params(self): - """ - get_document_shards_info() - """ - # Set up mock - url = preprocess_url('/testString/_shards/testString') - mock_response = '{"nodes": ["nodes"], "range": "range"}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - doc_id = 'testString' - - # Invoke method - response = _service.get_document_shards_info( - db, - doc_id, - headers={}, - ) - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_get_document_shards_info_all_params_with_retries(self): - # Enable retries and run test_get_document_shards_info_all_params. - _service.enable_retries() - self.test_get_document_shards_info_all_params() - - # Disable retries and run test_get_document_shards_info_all_params. - _service.disable_retries() - self.test_get_document_shards_info_all_params() - - @responses.activate - def test_get_document_shards_info_value_error(self): - """ - test_get_document_shards_info_value_error() - """ - # Set up mock - url = preprocess_url('/testString/_shards/testString') - mock_response = '{"nodes": ["nodes"], "range": "range"}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Set up parameter values - db = 'testString' - doc_id = 'testString' - - # Pass in all but one required param and check for a ValueError - req_param_dict = { - "db": db, - "doc_id": doc_id, - } - for param in req_param_dict.keys(): - req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} - with pytest.raises(ValueError): - _service.get_document_shards_info(**req_copy) - - def test_get_document_shards_info_value_error_with_retries(self): - # Enable retries and run test_get_document_shards_info_value_error. - _service.enable_retries() - self.test_get_document_shards_info_value_error() - - # Disable retries and run test_get_document_shards_info_value_error. + # Disable retries and run test_put_local_document_value_error. _service.disable_retries() - self.test_get_document_shards_info_value_error() + self.test_put_local_document_value_error() # endregion ############################################################################## -# End of Service: DatabaseDetails +# End of Service: LocalDocuments ############################################################################## ############################################################################## -# Start of Service: Monitoring +# Start of Service: DatabaseDetails ############################################################################## # region @@ -13331,130 +13665,19 @@ def test_new_instance_without_authenticator(self): ) -class TestHeadUpInformation: - """ - Test Class for head_up_information - """ - - @responses.activate - def test_head_up_information_all_params(self): - """ - head_up_information() - """ - # Set up mock - url = preprocess_url('/_up') - responses.add( - responses.HEAD, - url, - status=200, - ) - - # Invoke method - response = _service.head_up_information() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_head_up_information_all_params_with_retries(self): - # Enable retries and run test_head_up_information_all_params. - _service.enable_retries() - self.test_head_up_information_all_params() - - # Disable retries and run test_head_up_information_all_params. - _service.disable_retries() - self.test_head_up_information_all_params() - - -class TestGetActiveTasks: - """ - Test Class for get_active_tasks - """ - - @responses.activate - def test_get_active_tasks_all_params(self): - """ - get_active_tasks() - """ - # Set up mock - url = preprocess_url('/_active_tasks') - mock_response = '[{"bulk_get_attempts": 0, "bulk_get_docs": 0, "changes_done": 0, "changes_pending": 0, "checkpoint_interval": 30000, "checkpointed_source_seq": "checkpointed_source_seq", "continuous": false, "database": "database", "design_document": "design_document", "doc_id": "doc_id", "doc_write_failures": 0, "docs_read": 0, "docs_written": 0, "index": "index", "indexer_pid": "indexer_pid", "missing_revisions_found": 0, "node": "node", "phase": "docid_sort", "pid": "pid", "process_status": "exiting", "progress": 0, "replication_id": "replication_id", "retry": false, "revisions_checked": 0, "source": "source", "source_seq": "source_seq", "started_on": 0, "target": "target", "through_seq": "through_seq", "total_changes": 0, "type": "database_compaction", "updated_on": 0, "user": "user", "view": 0}]' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Invoke method - response = _service.get_active_tasks() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_get_active_tasks_all_params_with_retries(self): - # Enable retries and run test_get_active_tasks_all_params. - _service.enable_retries() - self.test_get_active_tasks_all_params() - - # Disable retries and run test_get_active_tasks_all_params. - _service.disable_retries() - self.test_get_active_tasks_all_params() - - -class TestGetActivityTrackerEvents: - """ - Test Class for get_activity_tracker_events - """ - - @responses.activate - def test_get_activity_tracker_events_all_params(self): - """ - get_activity_tracker_events() - """ - # Set up mock - url = preprocess_url('/_api/v2/user/activity_tracker/events') - mock_response = '{"types": ["management"]}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) - - # Invoke method - response = _service.get_activity_tracker_events() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_get_activity_tracker_events_all_params_with_retries(self): - # Enable retries and run test_get_activity_tracker_events_all_params. - _service.enable_retries() - self.test_get_activity_tracker_events_all_params() - - # Disable retries and run test_get_activity_tracker_events_all_params. - _service.disable_retries() - self.test_get_activity_tracker_events_all_params() - - -class TestPostActivityTrackerEvents: +class TestPostRevsDiff: """ - Test Class for post_activity_tracker_events + Test Class for post_revs_diff """ @responses.activate - def test_post_activity_tracker_events_all_params(self): + def test_post_revs_diff_all_params(self): """ - post_activity_tracker_events() + post_revs_diff() """ # Set up mock - url = preprocess_url('/_api/v2/user/activity_tracker/events') - mock_response = '{"ok": true}' + url = preprocess_url('/testString/_revs_diff') + mock_response = '{"mapKey": {"missing": ["missing"], "possible_ancestors": ["possible_ancestors"]}}' responses.add( responses.POST, url, @@ -13464,11 +13687,13 @@ def test_post_activity_tracker_events_all_params(self): ) # Set up parameter values - types = ['management', 'data'] + db = 'testString' + document_revisions = {'key1': ['testString']} # Invoke method - response = _service.post_activity_tracker_events( - types, + response = _service.post_revs_diff( + db, + document_revisions, headers={}, ) @@ -13481,25 +13706,25 @@ def test_post_activity_tracker_events_all_params(self): # Validate body params req_body = json.loads(str(responses.calls[0].request.body, 'utf-8')) - assert req_body['types'] == ['management', 'data'] + assert req_body == document_revisions - def test_post_activity_tracker_events_all_params_with_retries(self): - # Enable retries and run test_post_activity_tracker_events_all_params. + def test_post_revs_diff_all_params_with_retries(self): + # Enable retries and run test_post_revs_diff_all_params. _service.enable_retries() - self.test_post_activity_tracker_events_all_params() + self.test_post_revs_diff_all_params() - # Disable retries and run test_post_activity_tracker_events_all_params. + # Disable retries and run test_post_revs_diff_all_params. _service.disable_retries() - self.test_post_activity_tracker_events_all_params() + self.test_post_revs_diff_all_params() @responses.activate - def test_post_activity_tracker_events_value_error(self): + def test_post_revs_diff_value_error(self): """ - test_post_activity_tracker_events_value_error() + test_post_revs_diff_value_error() """ # Set up mock - url = preprocess_url('/_api/v2/user/activity_tracker/events') - mock_response = '{"ok": true}' + url = preprocess_url('/testString/_revs_diff') + mock_response = '{"mapKey": {"missing": ["missing"], "possible_ancestors": ["possible_ancestors"]}}' responses.add( responses.POST, url, @@ -13509,40 +13734,42 @@ def test_post_activity_tracker_events_value_error(self): ) # Set up parameter values - types = ['management', 'data'] + db = 'testString' + document_revisions = {'key1': ['testString']} # Pass in all but one required param and check for a ValueError req_param_dict = { - "types": types, + "db": db, + "document_revisions": document_revisions, } for param in req_param_dict.keys(): req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} with pytest.raises(ValueError): - _service.post_activity_tracker_events(**req_copy) + _service.post_revs_diff(**req_copy) - def test_post_activity_tracker_events_value_error_with_retries(self): - # Enable retries and run test_post_activity_tracker_events_value_error. + def test_post_revs_diff_value_error_with_retries(self): + # Enable retries and run test_post_revs_diff_value_error. _service.enable_retries() - self.test_post_activity_tracker_events_value_error() + self.test_post_revs_diff_value_error() - # Disable retries and run test_post_activity_tracker_events_value_error. + # Disable retries and run test_post_revs_diff_value_error. _service.disable_retries() - self.test_post_activity_tracker_events_value_error() + self.test_post_revs_diff_value_error() -class TestGetCapacityDatabasesInformation: +class TestGetShardsInformation: """ - Test Class for get_capacity_databases_information + Test Class for get_shards_information """ @responses.activate - def test_get_capacity_databases_information_all_params(self): + def test_get_shards_information_all_params(self): """ - get_capacity_databases_information() + get_shards_information() """ # Set up mock - url = preprocess_url('/_api/v2/user/capacity/databases') - mock_response = '{"current": {"databases": {"total": 0}}}' + url = preprocess_url('/testString/_shards') + mock_response = '{"shards": {"mapKey": ["inner"]}}' responses.add( responses.GET, url, @@ -13551,74 +13778,36 @@ def test_get_capacity_databases_information_all_params(self): status=200, ) - # Invoke method - response = _service.get_capacity_databases_information() - - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 - - def test_get_capacity_databases_information_all_params_with_retries(self): - # Enable retries and run test_get_capacity_databases_information_all_params. - _service.enable_retries() - self.test_get_capacity_databases_information_all_params() - - # Disable retries and run test_get_capacity_databases_information_all_params. - _service.disable_retries() - self.test_get_capacity_databases_information_all_params() - - -class TestGetCurrentDatabasesInformation: - """ - Test Class for get_current_databases_information - """ - - @responses.activate - def test_get_current_databases_information_all_params(self): - """ - get_current_databases_information() - """ - # Set up mock - url = preprocess_url('/_api/v2/user/current/databases') - mock_response = '{"databases": {"total": 0}}' - responses.add( - responses.GET, - url, - body=mock_response, - content_type='application/json', - status=200, - ) + # Set up parameter values + db = 'testString' # Invoke method - response = _service.get_current_databases_information() + response = _service.get_shards_information( + db, + headers={}, + ) # Check for correct operation assert len(responses.calls) == 1 assert response.status_code == 200 - def test_get_current_databases_information_all_params_with_retries(self): - # Enable retries and run test_get_current_databases_information_all_params. + def test_get_shards_information_all_params_with_retries(self): + # Enable retries and run test_get_shards_information_all_params. _service.enable_retries() - self.test_get_current_databases_information_all_params() + self.test_get_shards_information_all_params() - # Disable retries and run test_get_current_databases_information_all_params. + # Disable retries and run test_get_shards_information_all_params. _service.disable_retries() - self.test_get_current_databases_information_all_params() - - -class TestGetCurrentThroughputInformation: - """ - Test Class for get_current_throughput_information - """ + self.test_get_shards_information_all_params() @responses.activate - def test_get_current_throughput_information_all_params(self): + def test_get_shards_information_value_error(self): """ - get_current_throughput_information() + test_get_shards_information_value_error() """ - # Set up mock - url = preprocess_url('/_api/v2/user/current/throughput') - mock_response = '{"throughput": {"query": 0, "read": 0, "write": 0}}' + # Set up mock + url = preprocess_url('/testString/_shards') + mock_response = '{"shards": {"mapKey": ["inner"]}}' responses.add( responses.GET, url, @@ -13627,36 +13816,41 @@ def test_get_current_throughput_information_all_params(self): status=200, ) - # Invoke method - response = _service.get_current_throughput_information() + # Set up parameter values + db = 'testString' - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "db": db, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.get_shards_information(**req_copy) - def test_get_current_throughput_information_all_params_with_retries(self): - # Enable retries and run test_get_current_throughput_information_all_params. + def test_get_shards_information_value_error_with_retries(self): + # Enable retries and run test_get_shards_information_value_error. _service.enable_retries() - self.test_get_current_throughput_information_all_params() + self.test_get_shards_information_value_error() - # Disable retries and run test_get_current_throughput_information_all_params. + # Disable retries and run test_get_shards_information_value_error. _service.disable_retries() - self.test_get_current_throughput_information_all_params() + self.test_get_shards_information_value_error() -class TestGetMembershipInformation: +class TestGetDocumentShardsInfo: """ - Test Class for get_membership_information + Test Class for get_document_shards_info """ @responses.activate - def test_get_membership_information_all_params(self): + def test_get_document_shards_info_all_params(self): """ - get_membership_information() + get_document_shards_info() """ # Set up mock - url = preprocess_url('/_membership') - mock_response = '{"all_nodes": ["all_nodes"], "cluster_nodes": ["cluster_nodes"]}' + url = preprocess_url('/testString/_shards/testString') + mock_response = '{"nodes": ["nodes"], "range": "range"}' responses.add( responses.GET, url, @@ -13665,36 +13859,38 @@ def test_get_membership_information_all_params(self): status=200, ) + # Set up parameter values + db = 'testString' + doc_id = 'testString' + # Invoke method - response = _service.get_membership_information() + response = _service.get_document_shards_info( + db, + doc_id, + headers={}, + ) # Check for correct operation assert len(responses.calls) == 1 assert response.status_code == 200 - def test_get_membership_information_all_params_with_retries(self): - # Enable retries and run test_get_membership_information_all_params. + def test_get_document_shards_info_all_params_with_retries(self): + # Enable retries and run test_get_document_shards_info_all_params. _service.enable_retries() - self.test_get_membership_information_all_params() + self.test_get_document_shards_info_all_params() - # Disable retries and run test_get_membership_information_all_params. + # Disable retries and run test_get_document_shards_info_all_params. _service.disable_retries() - self.test_get_membership_information_all_params() - - -class TestGetUpInformation: - """ - Test Class for get_up_information - """ + self.test_get_document_shards_info_all_params() @responses.activate - def test_get_up_information_all_params(self): + def test_get_document_shards_info_value_error(self): """ - get_up_information() + test_get_document_shards_info_value_error() """ # Set up mock - url = preprocess_url('/_up') - mock_response = '{"cluster": "cluster", "seeds": {"anyKey": "anyValue"}, "status": "maintenance_mode"}' + url = preprocess_url('/testString/_shards/testString') + mock_response = '{"nodes": ["nodes"], "range": "range"}' responses.add( responses.GET, url, @@ -13703,26 +13899,33 @@ def test_get_up_information_all_params(self): status=200, ) - # Invoke method - response = _service.get_up_information() + # Set up parameter values + db = 'testString' + doc_id = 'testString' - # Check for correct operation - assert len(responses.calls) == 1 - assert response.status_code == 200 + # Pass in all but one required param and check for a ValueError + req_param_dict = { + "db": db, + "doc_id": doc_id, + } + for param in req_param_dict.keys(): + req_copy = {key: val if key is not param else None for (key, val) in req_param_dict.items()} + with pytest.raises(ValueError): + _service.get_document_shards_info(**req_copy) - def test_get_up_information_all_params_with_retries(self): - # Enable retries and run test_get_up_information_all_params. + def test_get_document_shards_info_value_error_with_retries(self): + # Enable retries and run test_get_document_shards_info_value_error. _service.enable_retries() - self.test_get_up_information_all_params() + self.test_get_document_shards_info_value_error() - # Disable retries and run test_get_up_information_all_params. + # Disable retries and run test_get_document_shards_info_value_error. _service.disable_retries() - self.test_get_up_information_all_params() + self.test_get_document_shards_info_value_error() # endregion ############################################################################## -# End of Service: Monitoring +# End of Service: DatabaseDetails ############################################################################## @@ -15453,6 +15656,9 @@ def test_design_document_information_serialization(self): content_information_sizes_model['file'] = 0 updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 updates_pending_model['minimum'] = 0 updates_pending_model['preferred'] = 0 updates_pending_model['total'] = 0 @@ -15537,6 +15743,9 @@ def test_design_document_view_index_serialization(self): content_information_sizes_model['file'] = 0 updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 updates_pending_model['minimum'] = 0 updates_pending_model['preferred'] = 0 updates_pending_model['total'] = 0 @@ -16404,6 +16613,94 @@ def test_index_field_serialization(self): assert actual_dict.keys() == expected_dict.keys() +class TestModel_IndexInfoResult: + """ + Test Class for IndexInfoResult + """ + + def test_index_info_result_serialization(self): + """ + Test serialization/deserialization for IndexInfoResult + """ + + # Construct dict forms of any model objects needed in order to build this model. + + updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 + updates_pending_model['minimum'] = 0 + updates_pending_model['preferred'] = 0 + updates_pending_model['total'] = 0 + + search_index_info_model = {} # SearchIndexInfo + search_index_info_model['committed_seq'] = 0 + search_index_info_model['disk_size'] = 0 + search_index_info_model['doc_count'] = 0 + search_index_info_model['doc_del_count'] = 0 + search_index_info_model['pending_seq'] = 0 + search_index_info_model['signature'] = 'testString' + search_index_info_model['updates_pending'] = updates_pending_model + + search_index_information_model = {} # SearchIndexInformation + search_index_information_model['ok'] = True + search_index_information_model['caused_by'] = 'testString' + search_index_information_model['error'] = 'testString' + search_index_information_model['reason'] = 'testString' + search_index_information_model['ref'] = 0 + search_index_information_model['ddoc'] = 'testString' + search_index_information_model['info'] = search_index_info_model + search_index_information_model['name'] = 'testString' + + content_information_sizes_model = {} # ContentInformationSizes + content_information_sizes_model['active'] = 0 + content_information_sizes_model['external'] = 0 + content_information_sizes_model['file'] = 0 + + design_document_view_index_model = {} # DesignDocumentViewIndex + design_document_view_index_model['collator_versions'] = ['testString'] + design_document_view_index_model['compact_running'] = True + design_document_view_index_model['language'] = 'testString' + design_document_view_index_model['signature'] = 'testString' + design_document_view_index_model['sizes'] = content_information_sizes_model + design_document_view_index_model['updater_running'] = True + design_document_view_index_model['updates_pending'] = updates_pending_model + design_document_view_index_model['waiting_clients'] = 0 + design_document_view_index_model['waiting_commit'] = True + + view_index_information_model = {} # ViewIndexInformation + view_index_information_model['ok'] = True + view_index_information_model['caused_by'] = 'testString' + view_index_information_model['error'] = 'testString' + view_index_information_model['reason'] = 'testString' + view_index_information_model['ref'] = 0 + view_index_information_model['ddoc'] = 'testString' + view_index_information_model['info'] = design_document_view_index_model + view_index_information_model['views'] = ['testString'] + + # Construct a json representation of a IndexInfoResult model + index_info_result_model_json = {} + index_info_result_model_json['bookmark'] = 'testString' + index_info_result_model_json['search_indexes'] = [search_index_information_model] + index_info_result_model_json['total_rows'] = 0 + index_info_result_model_json['view_indexes'] = [view_index_information_model] + + # Construct a model instance of IndexInfoResult by calling from_dict on the json representation + index_info_result_model = IndexInfoResult.from_dict(index_info_result_model_json) + assert index_info_result_model != False + + # Construct a model instance of IndexInfoResult by calling from_dict on the json representation + index_info_result_model_dict = IndexInfoResult.from_dict(index_info_result_model_json).__dict__ + index_info_result_model2 = IndexInfoResult(**index_info_result_model_dict) + + # Verify the model instances are equivalent + assert index_info_result_model == index_info_result_model2 + + # Convert model instance back to dict and verify no loss of data + index_info_result_model_json2 = index_info_result_model.to_dict() + assert index_info_result_model_json2 == index_info_result_model_json + + class TestModel_IndexInformation: """ Test Class for IndexInformation @@ -16920,9 +17217,16 @@ def test_replication_database_serialization(self): replication_database_auth_iam_model = {} # ReplicationDatabaseAuthIam replication_database_auth_iam_model['api_key'] = 'testString' + replication_database_auth_ibm_iam_model = {} # ReplicationDatabaseAuthIBMIam + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + replication_database_auth_ibm_model = {} # ReplicationDatabaseAuthIBM + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + replication_database_auth_model = {} # ReplicationDatabaseAuth replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model # Construct a json representation of a ReplicationDatabase model replication_database_model_json = {} @@ -16965,10 +17269,17 @@ def test_replication_database_auth_serialization(self): replication_database_auth_iam_model = {} # ReplicationDatabaseAuthIam replication_database_auth_iam_model['api_key'] = 'testString' + replication_database_auth_ibm_iam_model = {} # ReplicationDatabaseAuthIBMIam + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + replication_database_auth_ibm_model = {} # ReplicationDatabaseAuthIBM + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + # Construct a json representation of a ReplicationDatabaseAuth model replication_database_auth_model_json = {} replication_database_auth_model_json['basic'] = replication_database_auth_basic_model replication_database_auth_model_json['iam'] = replication_database_auth_iam_model + replication_database_auth_model_json['ibm'] = replication_database_auth_ibm_model # Construct a model instance of ReplicationDatabaseAuth by calling from_dict on the json representation replication_database_auth_model = ReplicationDatabaseAuth.from_dict(replication_database_auth_model_json) @@ -17017,6 +17328,71 @@ def test_replication_database_auth_basic_serialization(self): assert replication_database_auth_basic_model_json2 == replication_database_auth_basic_model_json +class TestModel_ReplicationDatabaseAuthIBM: + """ + Test Class for ReplicationDatabaseAuthIBM + """ + + def test_replication_database_auth_ibm_serialization(self): + """ + Test serialization/deserialization for ReplicationDatabaseAuthIBM + """ + + # Construct dict forms of any model objects needed in order to build this model. + + replication_database_auth_ibm_iam_model = {} # ReplicationDatabaseAuthIBMIam + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + # Construct a json representation of a ReplicationDatabaseAuthIBM model + replication_database_auth_ibm_model_json = {} + replication_database_auth_ibm_model_json['iam'] = replication_database_auth_ibm_iam_model + + # Construct a model instance of ReplicationDatabaseAuthIBM by calling from_dict on the json representation + replication_database_auth_ibm_model = ReplicationDatabaseAuthIBM.from_dict(replication_database_auth_ibm_model_json) + assert replication_database_auth_ibm_model != False + + # Construct a model instance of ReplicationDatabaseAuthIBM by calling from_dict on the json representation + replication_database_auth_ibm_model_dict = ReplicationDatabaseAuthIBM.from_dict(replication_database_auth_ibm_model_json).__dict__ + replication_database_auth_ibm_model2 = ReplicationDatabaseAuthIBM(**replication_database_auth_ibm_model_dict) + + # Verify the model instances are equivalent + assert replication_database_auth_ibm_model == replication_database_auth_ibm_model2 + + # Convert model instance back to dict and verify no loss of data + replication_database_auth_ibm_model_json2 = replication_database_auth_ibm_model.to_dict() + assert replication_database_auth_ibm_model_json2 == replication_database_auth_ibm_model_json + + +class TestModel_ReplicationDatabaseAuthIBMIam: + """ + Test Class for ReplicationDatabaseAuthIBMIam + """ + + def test_replication_database_auth_ibm_iam_serialization(self): + """ + Test serialization/deserialization for ReplicationDatabaseAuthIBMIam + """ + + # Construct a json representation of a ReplicationDatabaseAuthIBMIam model + replication_database_auth_ibm_iam_model_json = {} + replication_database_auth_ibm_iam_model_json['api_key'] = 'testString' + + # Construct a model instance of ReplicationDatabaseAuthIBMIam by calling from_dict on the json representation + replication_database_auth_ibm_iam_model = ReplicationDatabaseAuthIBMIam.from_dict(replication_database_auth_ibm_iam_model_json) + assert replication_database_auth_ibm_iam_model != False + + # Construct a model instance of ReplicationDatabaseAuthIBMIam by calling from_dict on the json representation + replication_database_auth_ibm_iam_model_dict = ReplicationDatabaseAuthIBMIam.from_dict(replication_database_auth_ibm_iam_model_json).__dict__ + replication_database_auth_ibm_iam_model2 = ReplicationDatabaseAuthIBMIam(**replication_database_auth_ibm_iam_model_dict) + + # Verify the model instances are equivalent + assert replication_database_auth_ibm_iam_model == replication_database_auth_ibm_iam_model2 + + # Convert model instance back to dict and verify no loss of data + replication_database_auth_ibm_iam_model_json2 = replication_database_auth_ibm_iam_model.to_dict() + assert replication_database_auth_ibm_iam_model_json2 == replication_database_auth_ibm_iam_model_json + + class TestModel_ReplicationDatabaseAuthIam: """ Test Class for ReplicationDatabaseAuthIam @@ -17090,9 +17466,16 @@ def test_replication_document_serialization(self): replication_database_auth_iam_model = {} # ReplicationDatabaseAuthIam replication_database_auth_iam_model['api_key'] = 'testString' + replication_database_auth_ibm_iam_model = {} # ReplicationDatabaseAuthIBMIam + replication_database_auth_ibm_iam_model['api_key'] = 'testString' + + replication_database_auth_ibm_model = {} # ReplicationDatabaseAuthIBM + replication_database_auth_ibm_model['iam'] = replication_database_auth_ibm_iam_model + replication_database_auth_model = {} # ReplicationDatabaseAuth replication_database_auth_model['basic'] = replication_database_auth_basic_model replication_database_auth_model['iam'] = replication_database_auth_iam_model + replication_database_auth_model['ibm'] = replication_database_auth_ibm_model replication_database_model = {} # ReplicationDatabase replication_database_model['auth'] = replication_database_auth_model @@ -17126,6 +17509,7 @@ def test_replication_document_serialization(self): replication_document_model_json['http_connections'] = 20 replication_document_model_json['owner'] = 'testString' replication_document_model_json['query_params'] = {'key1': 'testString'} + replication_document_model_json['request_compression'] = 'none' replication_document_model_json['retries_per_request'] = 5 replication_document_model_json['selector'] = {'anyKey': 'anyValue'} replication_document_model_json['since_seq'] = 'testString' @@ -17688,6 +18072,16 @@ def test_search_index_info_serialization(self): Test serialization/deserialization for SearchIndexInfo """ + # Construct dict forms of any model objects needed in order to build this model. + + updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 + updates_pending_model['minimum'] = 0 + updates_pending_model['preferred'] = 0 + updates_pending_model['total'] = 0 + # Construct a json representation of a SearchIndexInfo model search_index_info_model_json = {} search_index_info_model_json['committed_seq'] = 0 @@ -17696,6 +18090,7 @@ def test_search_index_info_serialization(self): search_index_info_model_json['doc_del_count'] = 0 search_index_info_model_json['pending_seq'] = 0 search_index_info_model_json['signature'] = 'testString' + search_index_info_model_json['updates_pending'] = updates_pending_model # Construct a model instance of SearchIndexInfo by calling from_dict on the json representation search_index_info_model = SearchIndexInfo.from_dict(search_index_info_model_json) @@ -17713,6 +18108,62 @@ def test_search_index_info_serialization(self): assert search_index_info_model_json2 == search_index_info_model_json +class TestModel_SearchIndexInformation: + """ + Test Class for SearchIndexInformation + """ + + def test_search_index_information_serialization(self): + """ + Test serialization/deserialization for SearchIndexInformation + """ + + # Construct dict forms of any model objects needed in order to build this model. + + updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 + updates_pending_model['minimum'] = 0 + updates_pending_model['preferred'] = 0 + updates_pending_model['total'] = 0 + + search_index_info_model = {} # SearchIndexInfo + search_index_info_model['committed_seq'] = 0 + search_index_info_model['disk_size'] = 0 + search_index_info_model['doc_count'] = 0 + search_index_info_model['doc_del_count'] = 0 + search_index_info_model['pending_seq'] = 0 + search_index_info_model['signature'] = 'testString' + search_index_info_model['updates_pending'] = updates_pending_model + + # Construct a json representation of a SearchIndexInformation model + search_index_information_model_json = {} + search_index_information_model_json['ok'] = True + search_index_information_model_json['caused_by'] = 'testString' + search_index_information_model_json['error'] = 'testString' + search_index_information_model_json['reason'] = 'testString' + search_index_information_model_json['ref'] = 0 + search_index_information_model_json['ddoc'] = 'testString' + search_index_information_model_json['info'] = search_index_info_model + search_index_information_model_json['name'] = 'testString' + + # Construct a model instance of SearchIndexInformation by calling from_dict on the json representation + search_index_information_model = SearchIndexInformation.from_dict(search_index_information_model_json) + assert search_index_information_model != False + + # Construct a model instance of SearchIndexInformation by calling from_dict on the json representation + search_index_information_model_dict = SearchIndexInformation.from_dict(search_index_information_model_json).__dict__ + search_index_information_model2 = SearchIndexInformation(**search_index_information_model_dict) + + # Verify the model instances are equivalent + assert search_index_information_model == search_index_information_model2 + + # Convert model instance back to dict and verify no loss of data + search_index_information_model_json2 = search_index_information_model.to_dict() + assert search_index_information_model_json2 == search_index_information_model_json + + class TestModel_SearchInfoResult: """ Test Class for SearchInfoResult @@ -17725,6 +18176,14 @@ def test_search_info_result_serialization(self): # Construct dict forms of any model objects needed in order to build this model. + updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 + updates_pending_model['minimum'] = 0 + updates_pending_model['preferred'] = 0 + updates_pending_model['total'] = 0 + search_index_info_model = {} # SearchIndexInfo search_index_info_model['committed_seq'] = 0 search_index_info_model['disk_size'] = 0 @@ -17732,6 +18191,7 @@ def test_search_info_result_serialization(self): search_index_info_model['doc_del_count'] = 0 search_index_info_model['pending_seq'] = 0 search_index_info_model['signature'] = 'testString' + search_index_info_model['updates_pending'] = updates_pending_model # Construct a json representation of a SearchInfoResult model search_info_result_model_json = {} @@ -18347,6 +18807,9 @@ def test_updates_pending_serialization(self): # Construct a json representation of a UpdatesPending model updates_pending_model_json = {} + updates_pending_model_json['copies'] = 0 + updates_pending_model_json['copies_expected'] = 0 + updates_pending_model_json['maximum'] = 0 updates_pending_model_json['minimum'] = 0 updates_pending_model_json['preferred'] = 0 updates_pending_model_json['total'] = 0 @@ -18429,6 +18892,69 @@ def test_uuids_result_serialization(self): assert uuids_result_model_json2 == uuids_result_model_json +class TestModel_ViewIndexInformation: + """ + Test Class for ViewIndexInformation + """ + + def test_view_index_information_serialization(self): + """ + Test serialization/deserialization for ViewIndexInformation + """ + + # Construct dict forms of any model objects needed in order to build this model. + + content_information_sizes_model = {} # ContentInformationSizes + content_information_sizes_model['active'] = 0 + content_information_sizes_model['external'] = 0 + content_information_sizes_model['file'] = 0 + + updates_pending_model = {} # UpdatesPending + updates_pending_model['copies'] = 0 + updates_pending_model['copies_expected'] = 0 + updates_pending_model['maximum'] = 0 + updates_pending_model['minimum'] = 0 + updates_pending_model['preferred'] = 0 + updates_pending_model['total'] = 0 + + design_document_view_index_model = {} # DesignDocumentViewIndex + design_document_view_index_model['collator_versions'] = ['testString'] + design_document_view_index_model['compact_running'] = True + design_document_view_index_model['language'] = 'testString' + design_document_view_index_model['signature'] = 'testString' + design_document_view_index_model['sizes'] = content_information_sizes_model + design_document_view_index_model['updater_running'] = True + design_document_view_index_model['updates_pending'] = updates_pending_model + design_document_view_index_model['waiting_clients'] = 0 + design_document_view_index_model['waiting_commit'] = True + + # Construct a json representation of a ViewIndexInformation model + view_index_information_model_json = {} + view_index_information_model_json['ok'] = True + view_index_information_model_json['caused_by'] = 'testString' + view_index_information_model_json['error'] = 'testString' + view_index_information_model_json['reason'] = 'testString' + view_index_information_model_json['ref'] = 0 + view_index_information_model_json['ddoc'] = 'testString' + view_index_information_model_json['info'] = design_document_view_index_model + view_index_information_model_json['views'] = ['testString'] + + # Construct a model instance of ViewIndexInformation by calling from_dict on the json representation + view_index_information_model = ViewIndexInformation.from_dict(view_index_information_model_json) + assert view_index_information_model != False + + # Construct a model instance of ViewIndexInformation by calling from_dict on the json representation + view_index_information_model_dict = ViewIndexInformation.from_dict(view_index_information_model_json).__dict__ + view_index_information_model2 = ViewIndexInformation(**view_index_information_model_dict) + + # Verify the model instances are equivalent + assert view_index_information_model == view_index_information_model2 + + # Convert model instance back to dict and verify no loss of data + view_index_information_model_json2 = view_index_information_model.to_dict() + assert view_index_information_model_json2 == view_index_information_model_json + + class TestModel_ViewQueriesResult: """ Test Class for ViewQueriesResult