Full Code of cloudant/python-cloudant for AI

master 1fb0bb577e8f cached
93 files
964.7 KB
224.4k tokens
1203 symbols
1 requests
Download .txt
Showing preview only (1,003K chars total). Download the full file or copy to clipboard to get everything.
Repository: cloudant/python-cloudant
Branch: master
Commit: 1fb0bb577e8f
Files: 93
Total size: 964.7 KB

Directory structure:
gitextract_yhao7vs7/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── CHANGES.md
├── CONTRIBUTING.md
├── DCO1.1.txt
├── Jenkinsfile
├── LICENSE
├── MANIFEST.in
├── MIGRATION.md
├── README.md
├── VERSION
├── docs/
│   ├── Makefile
│   ├── adapters.rst
│   ├── client.rst
│   ├── cloudant.rst
│   ├── compatibility.rst
│   ├── conf.py
│   ├── database.rst
│   ├── design_document.rst
│   ├── document.rst
│   ├── error.rst
│   ├── feed.rst
│   ├── getting_started.rst
│   ├── index.rst
│   ├── make.bat
│   ├── module_index.rst
│   ├── modules.rst
│   ├── query.rst
│   ├── replicator.rst
│   ├── result.rst
│   ├── security_document.rst
│   └── view.rst
├── pylintrc
├── requirements.txt
├── setup.py
├── src/
│   └── cloudant/
│       ├── _2to3.py
│       ├── __init__.py
│       ├── _client_session.py
│       ├── _common_util.py
│       ├── _messages.py
│       ├── adapters.py
│       ├── client.py
│       ├── database.py
│       ├── design_document.py
│       ├── document.py
│       ├── error.py
│       ├── feed.py
│       ├── index.py
│       ├── query.py
│       ├── replicator.py
│       ├── result.py
│       ├── scheduler.py
│       ├── security_document.py
│       └── view.py
├── test-requirements.txt
└── tests/
    ├── __init__.py
    ├── credentials.py
    ├── integration/
    │   ├── __init__.py
    │   ├── changes_test.py
    │   ├── document_test.py
    │   ├── end_to_end_example_test.py
    │   ├── iter_test.py
    │   └── replicator_test.py
    └── unit/
        ├── __init__.py
        ├── _test_util.py
        ├── adapter_tests.py
        ├── auth_renewal_tests.py
        ├── changes_tests.py
        ├── client_tests.py
        ├── cloud_foundry_tests.py
        ├── database_partition_tests.py
        ├── database_tests.py
        ├── db_updates_tests.py
        ├── design_document_tests.py
        ├── document_tests.py
        ├── document_validation_tests.py
        ├── fixtures/
        │   └── __init__.py
        ├── iam_auth_tests.py
        ├── index_tests.py
        ├── infinite_feed_tests.py
        ├── param_translation_tests.py
        ├── query_result_tests.py
        ├── query_tests.py
        ├── replicator_mock_tests.py
        ├── replicator_tests.py
        ├── result_tests.py
        ├── scheduler_tests.py
        ├── security_document_tests.py
        ├── unit_t_db_base.py
        ├── view_execution_tests.py
        └── view_tests.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
Please [read these guidelines](http://ibm.biz/cdt-issue-guide) before opening an issue.

<!-- Issues will be CLOSED IMMEDIATELY if the following template is not completed. -->

## Bug Description

### 1. Steps to reproduce and the simplest code sample possible to demonstrate the issue
<!--
Outline the steps you take to make the problem happen.
Provide the simplest code sample you can, in context, that reproduces the issue.
-->

### 2. What you expected to happen

### 3. What actually happened

## Environment details
<!--
- Version(s) that are affected by this issue.
    > 2.0.2
- Python version
    > 3.6.2
-->


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Thanks for your hard work, please ensure all items are complete before opening.
-->
## Checklist

- [ ] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](../blob/master/DCO1.1.txt)
- [ ] Added tests for code changes _or_ test/build only changes
- [ ] Updated the change log file (`CHANGES.md`) _or_ test/build only changes
- [ ] Completed the PR template below:

## Description
<!--
Provide a short description; saving the detail for the `Approach` section

Also EITHER:
Link to issue this PR is resolving, use the Fixes #nnn form so that the
issue closes automatically when the PR merges e.g.:

Fixes #23

OR

For PRs without an associated issue and/or test/build issues

### 1. Steps to reproduce and the simplest code sample possible to demonstrate the issue
### 2. What you expected to happen
### 3. What actually happened
-->

## Approach

<!--
Be brief: which component(s) of the code base does the fix focus on.

A place to note whether the part of the code base that is being worked is
particularly sensitive.
-->

## Schema & API Changes

<!--
EITHER:

- "No change"

OR

For public API (as opposed to internal) changes

- "Fixing bug in API, will change x in such-and-such way"
-->

## Security and Privacy

<!--
EITHER:

- "No change"

OR

"Making changes in e.g. auth|https|encryption|io
need to be careful about..."

-->

## Testing

<!--
EITHER:

- Added new tests:
    - test x
    - test y
    - test z

OR

- Modified existing tests because ...

OR

- N/A build or packaging only changes

OR

In exceptional circumstances there may be a good reason we can't add automated
tests, for example if a specific device is required to reproduce a problem.

- No new tests because...
-->

## Monitoring and Logging
<!--
EITHER:

- "No change"

OR

- "Added new log line X..."
-->


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Emacs temp files
*~
\#*
\.\#*

# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
venv/
venv.*/
*.egg-info/
.installed.cfg
*.egg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot

# Sphinx documentation
docs/_build/



================================================
FILE: .travis.yml
================================================
sudo: required

language: python

python:
  - "3.8"

env:
  - ADMIN_PARTY=true COUCHDB_VERSION=2.3.1
  - ADMIN_PARTY=false COUCHDB_VERSION=2.3.1

services:
  - docker

before_install:
  - docker pull couchdb:$COUCHDB_VERSION
  - docker run -d -p 5984:5984 couchdb:$COUCHDB_VERSION

install: "pip install -r requirements.txt && pip install -r test-requirements.txt"

before_script:
    # Make sure CouchDB is up
    - while [ $? -ne 0 ]; do sleep 1 && curl -v http://localhost:5984; done
    - curl -X PUT http://localhost:5984/_users
    - curl -X PUT http://localhost:5984/_replicator

# command to run tests
script:
    - pylint ./src/cloudant
    - nosetests -A 'not db or ((db == "couch" or "couch" in db) and (not couchapi or couchapi <='${COUCHDB_VERSION:0:1}'))' -w ./tests/unit

notifications:
  email: false


================================================
FILE: CHANGES.md
================================================
# UNRELEASED
- [DEPRECATED] This library is end-of-life and no longer supported.

# 2.15.0 (2021-08-26)
- [NEW] Override `dict.get` method for `CouchDatabase` to add `remote` parameter allowing it to
  retrieve a remote document if specified.
- [FIXED] Fixed the documentation for `bookmarks`.
- [FIXED] Also exit `follow_replication` for `failed` state.
- [FIXED] Fixed result paging for grouped view queries.
- [FIXED] Incorrect use of username as account name in `Cloudant.bluemix()`.
- [FIXED] Use custom encoder (if provided) for all view `key` params not just `keys`.
- [FIXED] Support boolean type for `key`, `endkey`, and `startkey` in view requests.
- [DEPRECATED] This library is now deprecated and will be EOL on Dec 31 2021.
- [REMOVED] Removed Python 2 compatibility from the supported environments.
- [IMPROVED] Documented use of `None` account name and url override for `Cloudant.iam()`.
- [IMPROVED] - Document IDs and attachment names are now rejected if they could cause an unexpected
  Cloudant request. We have seen that some applications pass unsantized document IDs to SDK functions
  (e.g. direct from user requests). In response to this we have updated many functions to reject
  obviously invalid paths. However, for complete safety applications must still validate that
  document IDs and attachment names match expected patterns.

# 2.14.0 (2020-08-17)

- [FIXED] Set default value for `partitioned` parameter to false when creating a design document.
- [FIXED] Corrected setting of `partitioned` flag for `create_query_index` requests.
- [FIXED] Added a workaround for installation on Python 2.

# 2.13.0 (2020-04-16)

- [FIXED] Correctly raise exceptions from `create_database` calls.
- [FIXED] Fix `DeprecationWarning` from `collections`.

# 2.12.0 (2019-03-28)

- [NEW] Added partitioned database support.
- [FIXED] Bug where document context manager performed remote save despite uncaught exceptions being
  raised inside `with` block.
- [FIXED] Fixed parameter type of `selector` in docstring.
- [FIXED] Removed internal `Document._document_id` property to allow a safe use of dict's methods.
- [IMPROVED] Performance of `Result` iteration by releasing result objects immediately after they
  are returned to the client.
- [IMPROVED] Updated `Getting started` section with a `get_query_result` example.
- [IMPROVED] Updated `Result` iteration by paginating with views' `startkey` and queries'
  `bookmark`.

# 2.11.0 (2019-01-21)

- [NEW] Added option for client to authenticate with IAM token server.
- [FIXED] Updated the default IAM token server URL.

# 2.10.2 (2018-12-19)

- [FIXED] A performance regression deserializing JSON in version 2.10.1.

# 2.10.1 (2018-11-16)

- [FIXED] Unexpected keyword argument errors when using the library with the `simplejson` module
 present in the environment caused by `requests` preferentially loading it over the system `json`
 module.

# 2.10.0 (2018-09-19)

- [NEW] Add custom JSON encoder/decoder option to `Document` constructor.
- [NEW] Add new view parameters, `stable` and `update`, as keyword arguments to `get_view_result`.
- [NEW] Allow arbitrary query parameters to be passed to custom changes filters.
- [FIXED] Case where an exception was raised after successful retry when using `doc.update_field`.
- [FIXED] Removed unnecessary request when retrieving a Result collection that is less than the
  `page_size` value.

# 2.9.0 (2018-06-13)

- [NEW] Added functionality to test if a key is in a database as in `key in db`, overriding dict
  `__contains__` and checking in the remote database.
- [NEW] Moved `create_query_index` and other query related methods to `CouchDatabase` as the
  `_index`/`_find` API is available in CouchDB 2.x.
- [NEW] Support IAM authentication in replication documents.
- [FIXED] Case where `Document` context manager would throw instead of creating a new document if no
  `_id` was provided.
- [IMPROVED] Added support for IAM API key in `cloudant_bluemix` method.
- [IMPROVED] Shortened length of client URLs by removing username and password.
- [IMPROVED] Verified library operation on Python 3.6.3.

# 2.8.1 (2018-02-16)

- [FIXED] Installation failures of 2.8.0 caused by missing VERSION file in distribution.

# 2.8.0 (2018-02-15)

- [NEW] Added support for `/_search_disk_size` endpoint which retrieves disk size information for a
  specific search index.
- [FIXED] Updated default IBM Cloud Identity and Access Management token URL.
- [REMOVED] Removed broken source and target parameters that constantly threw `AttributeError` when
  creating a replication document.

# 2.7.0 (2017-10-31)

- [NEW] Added API for upcoming Bluemix Identity and Access Management support for Cloudant on
  Bluemix. Note: IAM API key support is not yet enabled in the service.
- [NEW] Added HTTP basic authentication support.
- [NEW] Added `Result.all()` convenience method.
- [NEW] Allow `service_name` to be specified when instantiating from a Bluemix VCAP_SERVICES
  environment variable.
- [IMPROVED] Updated `posixpath.join` references to use `'/'.join` when concatenating URL parts.
- [IMPROVED] Updated documentation by replacing deprecated Cloudant links with the latest Bluemix
  links.

# 2.6.0 (2017-08-10)

- [NEW] Added `Cloudant.bluemix()` class method to the Cloudant client allowing service credentials
  to be passed using the CloudFoundry VCAP_SERVICES environment variable.
- [FIXED] Fixed client construction in `cloudant_bluemix` context manager.
- [FIXED] Fixed validation for feed options to accept zero as a valid value.

# 2.5.0 (2017-07-06)

- [FIXED] Fixed crash caused by non-UTF8 chars in design documents.
- [FIXED] Fixed `TypeError` when setting revision limits on Python>=3.6.
- [FIXED] Fixed the `exists()` double check on `client.py` and `database.py`.
- [FIXED] Fixed Cloudant exception code 409 with 412 when creating a database that already exists.
- [FIXED] Catch error if `throw_on_exists` flag is `False` for creating a document.
- [FIXED] Fixed /_all_docs call where `keys` is an empty list.
- [FIXED] Issue where docs with IDs that sorted lower than 0 were not returned when iterating
  through _all_docs.

# 2.4.0 (2017-02-14)

- [NEW] Added `timeout` option to the client constructor for setting a timeout on a HTTP connection
  or a response.
- [NEW] Added `cloudant_bluemix` method to the Cloudant client allowing service credentials to be
  passed using the CloudFoundry VCAP_SERVICES environment variable.
- [IMPROVED] Updated non-response related errors with additional status code and improved error
  message for easier debugging.  All non-response error are handled using either CloudantException
  or CloudantArgumentError.
- [FIXED] Support `long` type argument when executing in Python 2.

# 2.3.1 (2016-11-30)

- [FIXED] Resolved issue where generated UUIDs for replication documents would not be converted to
  strings.
- [FIXED] Resolved issue where CouchDatabase.infinite_changes() method can cause a stack overflow.

# 2.3.0 (2016-11-02)

- [FIXED] Resolved issue where the custom JSON encoder was at times not used when transforming data.
- [NEW] Added support for managing the database security document through the SecurityDocument class
  and CouchDatabase convenience method `get_security_document`.
- [NEW] Added `auto_renewal` option to the client constructor to handle the automatic renewal of an
  expired session cookie auth.

# 2.2.0 (2016-10-20)

- [NEW] Added auto connect feature to the client constructor.
- [FIXED] Requests session is no longer valid after disconnect.

# 2.1.1 (2016-10-03)

- [FIXED] HTTPError is now raised when 4xx or 5xx codes are encountered.

# 2.1.0 (2016-08-31)

- [NEW] Added support for Cloudant Search execution.
- [NEW] Added support for Cloudant Search index management.
- [NEW] Added support for managing and querying list functions.
- [NEW] Added support for managing and querying show functions.
- [NEW] Added support for querying update handlers.
- [NEW] Added `rewrites` accessor property for URL rewriting.
- [NEW] Added `st_indexes` accessor property for Cloudant Geospatial indexes.
- [NEW] Added support for DesignDocument `_info` and `_search_info` endpoints.
- [NEW] Added `validate_doc_update` accessor property for update validators.
- [NEW] Added support for a custom `requests.HTTPAdapter` to be configured using an optional
  `adapter` arg e.g.  `Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME,
  adapter=Replay429Adapter())`.
- [IMPROVED] Made the 429 response code backoff optional and configurable. To enable the backoff add
  an `adapter` arg of a `Replay429Adapter` with the desired number of retries and initial
  backoff. To replicate the 2.0.0 behaviour use: `adapter=Replay429Adapter(retries=10,
  initialBackoff=0.25)`. If `retries` or `initialBackoff` are not specified they will default to 3
  retries and a 0.25 s initial backoff.
- [IMPROVED] Additional error reason details appended to HTTP response message errors.
- [FIX] `415 Client Error: Unsupported Media Type` when using keys with `db.all_docs`.
- [FIX] Allowed strings as well as lists for search `group_sort` arguments.

# 2.0.3 (2016-06-03)

- [FIX] Fixed the python-cloudant readthedocs documentation home page to resolve correctly.

# 2.0.2 (2016-06-02)

- [IMPROVED] Updated documentation links from python-cloudant.readthedocs.org to
  python-cloudant.readthedocs.io.
- [FIX] Fixed issue with Windows platform compatibility,replaced usage of os.uname for the
  user-agent string.
- [FIX] Fixed readthedocs link in README.rst to resolve to documentation home page.

# 2.0.1 (2016-06-02)

- [IMPROVED] Updated documentation links from python-cloudant.readthedocs.org to
  python-cloudant.readthedocs.io.
- [FIX] Fixed issue with Windows platform compatibility,replaced usage of os.uname for the
  user-agent string.
- [FIX] Fixed readthedocs link in README.rst to resolve to documentation home page.

# 2.0.0 (2016-05-02)

- [BREAKING] Renamed modules account.py, errors.py, indexes.py, views.py, to client.py, error.py,
  index.py, and view.py.
- [BREAKING] Removed the `make_result` method from `View` and `Query` classes.  If you need to make
  a query or view result, use `CloudantDatabase.get_query_result`, `CouchDatabase.get_view_result`,
  or the `View.custom_result` context manager.  Additionally, the `Result` and `QueryResult` classes
  can be called directly to construct a result object.
- [BREAKING] Refactored the `SearchIndex` class to now be the `TextIndex` class.  Also renamed the
  `CloudantDatabase` convenience methods of `get_all_indexes`, `create_index`, and `delete_index` as
  `get_query_indexes`, `create_query_index`, and `delete_query_index` respectively.  These changes
  were made to clarify that the changed class and the changed methods were specific to query index
  processing only.
- [BREAKING] Replace "session" and "url" feed constructor arguments with "source" which can be
  either a client or a database object.  Changes also made to the client `db_updates` method
  signature and the database `changes` method signature.
- [BREAKING] Fixed `CloudantDatabase.share_database` to accept all valid permission roles.  Changed
  the method signature to accept roles as a list argument.
- [BREAKING] Removed credentials module from the API and moved it to the tests folder since the
  functionality is outside of the scope of this library but is still be useful in unit/integration
  tests.
- [IMPROVED] Changed the handling of queries using the keys argument to issue a http POST request
  instead of a http GET request so that the request is no longer bound by any URL length limitation.
- [IMPROVED] Added support for Result/QueryResult data access via index value and added validation
  logic to `Result.__getitem__()`.
- [IMPROVED] Updated feed functionality to process `_changes` and `_db_updates` with their supported
  options.  Also added an infinite feed option.
- [NEW] Handled HTTP status code `429 Too Many Requests` with blocking backoff and retries.
- [NEW] Added support for CouchDB Admin Party mode.  This library can now be used with CouchDB
  instances where everyone is Admin.
- [FIX] Fixed `Document.get_attachment` method to successfully create text and binary files based on
  http response Content-Type.  The method also returns text, binary, and json content based on http
  response Content-Type.
- [FIX] Added validation to `Cloudant.bill`, `Cloudant.volume_usage`, and `Cloudant.requests_usage`
  methods to ensure that a valid year/month combination or neither are used as arguments.
- [FIX] Fixed the handling of empty views in the DesignDocument.
- [FIX] The `CouchDatabase.create_document` method now handles documents and design documents
  correctly.  If the document created is a design document then the locally cached object will be a
  DesignDocument otherwise it will be a Document.
- [CHANGE] Moved internal `Code` class, functions like `python_to_couch` and `type_or_none`, and
  constants into a _common_util module.
- [CHANGE] Updated User-Agent header format to be `python-cloudant/<library version>/Python/<Python
  version>/<OS name>/<OS architecture>`.
- [CHANGE] Completed the addition of unit tests that target a database server.  Removed all mocked
  unit tests.

# 2.0.0b2 (2016-02-24)

- [FIX] Remove the fields parameter from required Query parameters.
- [NEW] Add Python 3 support.

# 2.0.0b1 (2016-01-11)


- [NEW] Added support for Cloudant Query execution.
- [NEW] Added support for Cloudant Query index management.
- [FIX] DesignDocument content is no longer limited to just views.
- [FIX] Document url encoding is now enforced.
- [FIX] Database iterator now yields Document/DesignDocument objects with valid document urls.

# 2.0.0a4 (2015-12-03)


- [FIX] Fixed incorrect readme reference to current library being Alpha 2.

# 2.0.0a3 (2015-12-03)


- [NEW] Added API documentation hosted on readthedocs.org.

# 2.0.0a2 (2015-11-19)


- [NEW] Added unit tests targeting CouchDB and Cloudant databases.
- [FIX] Fixed bug in database create validation check to work if response code is either 201
  (created) or 202 (accepted).
- [FIX] Fixed database iterator infinite loop problem and to now yield a Document object.
- [BREAKING] Removed previous bulk_docs method from the CouchDatabase class and renamed the previous
  bulk_insert method as bulk_docs.  The previous bulk_docs functionality is available through the
  all_docs method using the "keys" parameter.
- [FIX] Made missing_revisions, revisions_diff, get_revision_limit, set_revision_limit, and
  view_cleanup API methods available for CouchDB as well as Cloudant.
- [BREAKING] Moved the db_update method to the account module.
- [FIX] Fixed missing_revisions to key on 'missing_revs'.
- [FIX] Fixed set_revision_limit to encode the request data payload correctly.
- [FIX] `Document.create()` will no longer update an existing document.
- [BREAKING] Renamed Document `field_append` method to `list_field_append`.
- [BREAKING] Renamed Document `field_remove` method to `list_field_remove`.
- [BREAKING] Renamed Document `field_replace` method to `field_set`.
- [FIX] The Document local dictionary `_id` key is now synched with `_document_id` private
  attribute.
- [FIX] The Document local dictionary is now refreshed after an add/update/delete of an attachment.
- [FIX] The Document `fetch()` method now refreshes the Document local dictionary content correctly.
- [BREAKING] Replace the ReplicatorDatabase class with the Replicator class.  A Replicator object
  has a database attribute that represents the _replicator database.  This allows the Replicator to
  work for both a CloudantDatabase and a CouchDatabase.
- [REMOVED] Removed "not implemented" methods from the DesignDocument.
- [FIX] Add implicit "_design/" prefix for DesignDocument document ids.

# 2.0.0a1 (2015-10-13)


- Initial release (2.0.0a1).


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

## Issues

Please [read these guidelines](http://ibm.biz/cdt-issue-guide) before opening an issue.
If you still need to open an issue then we ask that you complete the template as
fully as possible.

## Pull requests

We welcome pull requests, but ask contributors to keep in mind the following:

* Only PRs with the template completed will be accepted
* We will not accept PRs for user specific functionality

### Developer Certificate of Origin

In order for us to accept pull-requests, the contributor must sign-off a
[Developer Certificate of Origin (DCO)](DCO1.1.txt). This clarifies the
intellectual property license granted with any contribution. It is for your
protection as a Contributor as well as the protection of IBM and its customers;
it does not change your rights to use your own Contributions for any other purpose.

Please read the agreement and acknowledge it by ticking the appropriate box in the PR
 text, for example:

- [x] Tick to sign-off your agreement to the Developer Certificate of Origin (DCO) 1.1

## General information

Python-Cloudant Client Library is written in Python.

## Requirements

- Python
- pip

It is recommended to use a [virtual environment](https://virtualenv.pypa.io/en/latest) during development. The
python-cloudant dependencies can be installed via the `requirements.txt` file using pip.

For example to create a virtualenv and install requirements:

```sh
virtualenv .
./bin/activate
pip install -r requirements.txt
pip install -r test-requirements.txt
```

## Testing

The tests need an Apache CouchDB or Cloudant service to run against.

The tests create databases in your CouchDB instance, these are `db-<uuid4()>`.
They also create and delete documents in the `_replicator` database.

The tests are run with the `nosetests` runner. In this example the `ADMIN_PARTY` environment variable is used to tell
 the tests not to use any authentication. See below for the full set of variables that can be used.

```sh
$ ADMIN_PARTY=true nosetests -w ./tests/unit
```

There are several environment variables which affect
test behaviour:

- `RUN_CLOUDANT_TESTS`: set this to run the tests that use Cloudant-specific features. If
  you set this, you must set one of the following combinations of other variables:
    - `DB_URL`, `DB_USER` and `DB_PASSWORD`.
    - `CLOUDANT_ACCOUNT`, `DB_USER` and `DB_PASSWORD`.
    - If you set both `DB_URL` and `CLOUDANT_ACCOUNT`, `DB_URL` is used as the
      URL to make requests to and `CLOUDANT_ACCOUNT` is inserted into the `X-Cloudant-User`
      header.
- Without `RUN_CLOUDANT_TESTS`, the following environment variables have an effect:
    - Set `DB_URL` to set the root URL of the CouchDB/Cloudant instance. It defaults
      to `http://localhost:5984`.
    - Set `ADMIN_PARTY` to `true` to not use any authentication details.
    - Without `ADMIN_PARTY`, set `DB_USER` and `DB_PASSWORD` to use those
      credentials to access the database.
    - Without `ADMIN_PARTY` and `DB_USER`, the tests assume CouchDB is in
      admin party mode, but create a user via `_config` to run tests as.
      This user is deleted at the end of the test run, but beware it'll
      break other applications using the CouchDB instance that rely on
      admin party mode being in effect while the tests are running.

### Test attributes

Database tests also have node attributes. Currently there are these attributes:
`db` - `cloudant` and/or `couch`
`couchapi` - Apache CouchDB major version number (i.e. API level) e.g. `2`

Example to run database tests that require CouchDB version 1 API and no Cloudant features:
`nosetests -A 'db and ((db is "couch" or "couch" in db) and (not couchapi or couchapi <=1))' -w ./tests/unit`


================================================
FILE: DCO1.1.txt
================================================
Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

       By making a contribution to this project, I certify that:

       (a) The contribution was created in whole or in part by me and I
           have the right to submit it under the open source license
           indicated in the file; or

       (b) The contribution is based upon previous work that, to the best
           of my knowledge, is covered under an appropriate open source
           license and I have the right under that license to submit that
           work with modifications, whether created in whole or in part
           by me, under the same open source license (unless I am
           permitted to submit under a different license), as indicated
           in the file; or

       (c) The contribution was provided directly to me by some other
           person who certified (a), (b) or (c) and I have not modified
           it.

       (d) I understand and agree that this project and the contribution
           are public and that a record of the contribution (including all
           personal information I submit with it, including my sign-off) is
           maintained indefinitely and may be redistributed consistent with
           this project or the open source license(s) involved.


================================================
FILE: Jenkinsfile
================================================
def getEnvForSuite(suiteName) {
  // Base environment variables
  def envVars = [
    "DB_URL=${SDKS_TEST_SERVER_URL}",
    "RUN_CLOUDANT_TESTS=1",
    "SKIP_DB_UPDATES=1" // Disable pending resolution of case 71610
  ]
  // Add test suite specific environment variables
  switch(suiteName) {
    case 'basic':
      envVars.add("RUN_BASIC_AUTH_TESTS=1")
      break
    case 'iam':
      // Setting IAM_API_KEY forces tests to run using an IAM enabled client.
      envVars.add("IAM_API_KEY=$DB_IAM_API_KEY")
      envVars.add("IAM_TOKEN_URL=$SDKS_TEST_IAM_URL")
      break
    case 'cookie':
    case 'simplejson':
      break
    default:
      error("Unknown test suite environment ${suiteName}")
  }
  return envVars
}

def setupPythonAndTest(pythonVersion, testSuite) {
  node('sdks-executor') {
    // Unstash the source on this node
    unstash name: 'source'
    // Set up the environment and test
    withCredentials([usernamePassword(credentialsId: 'testServerLegacy', usernameVariable: 'DB_USER', passwordVariable: 'DB_PASSWORD'),
                     string(credentialsId: 'testServerIamApiKey', variable: 'DB_IAM_API_KEY')]) {
      withEnv(getEnvForSuite("${testSuite}")) {
        try {
          sh """
            virtualenv tmp -p ${pythonVersion.startsWith('3') ? "python3" : "python"}
            . ./tmp/bin/activate
            python --version
            pip install -r requirements.txt
            pip install -r test-requirements.txt
            ${'simplejson'.equals(testSuite) ? 'pip install simplejson' : ''}
            pylint ./src/cloudant
            nosetests -A 'not db or (db == "cloudant" or "cloudant" in db)' -w ./tests/unit --with-xunit
          """
        } finally {
          // Load the test results
          junit 'nosetests.xml'
        }
      }
    }
  }
}

// Start of build
stage('Checkout'){
  // Checkout and stash the source
  node{
    checkout scm
    stash name: 'source'
  }
}

stage('Test'){
  def py3 = '3'
  def axes = [:]
  [py3].each { version ->
    ['basic','cookie','iam'].each { auth ->
       axes.put("Python${version}-${auth}", {setupPythonAndTest(version, auth)})
    }
  }
  axes.put("Python${py3}-simplejson", {setupPythonAndTest(py3, 'simplejson')})
  parallel(axes)
}

stage('Publish') {
  gitTagAndPublish {
    isDraft=true
    releaseApiUrl='https://api.github.com/repos/cloudant/python-cloudant/releases'
  }
}


================================================
FILE: LICENSE
================================================
Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: MANIFEST.in
================================================
include requirements.txt VERSION LICENSE


================================================
FILE: MIGRATION.md
================================================
# Migrating to the `cloudant-python-sdk` library
This document is to assist in migrating from the `python-cloudant` (module: `cloudant`) to the newly supported [`cloudant-python-sdk`](https://github.com/IBM/cloudant-python-sdk) (module: `ibmcloudant`).

## Initializing the client connection
There are several ways to create a client connection in `cloudant-python-sdk`:
1. [Environment variables](https://github.com/IBM/cloudant-python-sdk#authentication-with-environment-variables)
2. [External configuration file](https://github.com/IBM/cloudant-python-sdk#authentication-with-external-configuration)
3. [Programmatically](https://github.com/IBM/cloudant-python-sdk#programmatic-authentication)

[See the README](https://github.com/IBM/cloudant-python-sdk#code-examples) for code examples on using environment variables.

## Other differences
1. The `cloudant-python-sdk` library does not support local dictionary caching of database and document objects.
1. There are no context managers in `cloudant-python-sdk`. To reproduce the behaviour of the `python-cloudant`
context managers in `cloudant-python-sdk` users need to explicitly call the specific operations against the
remote HTTP API. For example, in the case of the document context manager, this would mean doing both a `get_document`
to fetch and a `put_document` to save.
1. In `cloudant-python-sdk` View, Search, and Query (aka `_find` endpoint) operation responses contain raw JSON
content like using `raw_result=True` in `python-cloudant`.
1. Replay adapters are replaced by the [automatic retries](https://github.com/IBM/ibm-cloud-sdk-common/#automatic-retries) feature for failed requests.
1. Error handling is not transferable from `python-cloudant` to `cloudant-python-sdk`. For more information go to the [Error handling section](https://cloud.ibm.com/apidocs/cloudant?code=python#error-handling) in our API docs.
1. Custom HTTP client configurations in `python-cloudant` can be set differently in
   `cloudant-python-sdk`. For more information go to the
   [Configuring the HTTP client section](https://github.com/IBM/ibm-cloud-sdk-common/#configuring-the-http-client)
   in the IBM Cloud SDK Common README.
   
### Troubleshooting
1. Authentication errors occur during service instantiation. For example, the code `service =
   CloudantV1.new_instance(service_name="EXAMPLE")` will fail with `ValueError: At least one of
   iam_profile_name or iam_profile_id must be specified.` if required environment variables
   prefixed with `EXAMPLE` are not set.
1. Server errors occur when running a request against the service. We suggest to
   check server errors with
   [`getServerInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getserverinformation)
   which is the new alternative of `metadata()`.
   
## Request mapping
Here's a list of the top 5 most frequently used `python-cloudant` operations and the `cloudant-python-sdk` equivalent API operation documentation link:

| `python-cloudant` operation           | `cloudant-python-sdk` API operation documentation link |
|---------------------------------------|---------------------------------|
|`Document('db_name', 'docid').fetch()` |[`getDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdocument)|
|`db.get_view_result()`                 |[`postView`](https://cloud.ibm.com/apidocs/cloudant?code=python#postview)|
|`db.get_query_result()`                |[`postFind`](https://cloud.ibm.com/apidocs/cloudant?code=python#postfind)|
| `doc.exists()`                        |[`headDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#headdocument)|
|`Document('db_name', 'docid').save()`  |[`putDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#putdocument)|


[A table](#reference-table) with the whole list of operations is provided at the end of this guide.

The `cloudant-python-sdk` library is generated from a more complete API spec and provides a significant number of operations that do not exist in `python-cloudant`. See [the IBM Cloud API Documentation](https://cloud.ibm.com/apidocs/cloudant) to review request parameter and body options, code examples, and additional details for every endpoint.

## Known Issues
There's an [outline of known issues](https://github.com/IBM/cloudant-python-sdk/blob/master/KNOWN_ISSUES.md) in the `cloudant-python-sdk` repository.

## Reference table
The table below contains a list of `python-cloudant` functions and the `cloudant-python-sdk` equivalent API operation documentation link.  The `cloudant-python-sdk` operation documentation link will contain the new function in a code sample e.g. `getServerInformation` link will contain a code example with `get_server_information()`.

**Note:** There are many API operations included in the new `cloudant-python-sdk` that are not available in the `python-cloudant` library. The [API documentation](https://cloud.ibm.com/apidocs/cloudant?code=python) contains the full list of operations.

| `python-cloudant` function | `cloudant-python-sdk` API operation documentation link |
|-----------------|---------------------|
|`metadata()`|[`getServerInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getserverinformation)|
|`all_dbs()`|[`getAllDbs`](https://cloud.ibm.com/apidocs/cloudant?code=python#getalldbs)|
|`db_updates()/infinite_db_updates()`|[`getDbUpdates`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdbupdates)|
|`Replicator.stop_replication()`|[`deleteReplicationDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#deletereplicationdocument)|
|`Replicator.replication_state()`|[`getReplicationDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getreplicationdocument)|
|`Replicator.create_replication()`|[`putReplicationDocument`](https://cloud.ibm.com/apidocs/cloudant?code=#putreplicationdocument)|
|`Scheduler.get_doc()`|[`getSchedulerDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getschedulerdocument)|
|`Scheduler.list_docs()`|[`getSchedulerDocs`](https://cloud.ibm.com/apidocs/cloudant?code=python#getschedulerdocs)|
|`Scheduler.list_jobs()`|[`getSchedulerJobs`](https://cloud.ibm.com/apidocs/cloudant?code=python#getschedulerjobs)|
|`session()`|[`getSessionInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getsessioninformation)|
|`uuids()`|[`getUuids`](https://cloud.ibm.com/apidocs/cloudant?code=python#getuuids)|
|`db.delete()`|[`deleteDatabase`](https://cloud.ibm.com/apidocs/cloudant?code=python#deletedatabase)|
|`db.metadata()`|[`getDatabaseInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdatabaseinformation)|
|`db.create_document()`|[`postDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#postdocument)|
|`db.create()`|[`putDatabase`](https://cloud.ibm.com/apidocs/cloudant?code=python#putdatabase)|
|`db.all_docs()/db.keys()`|[`postAllDocs`](https://cloud.ibm.com/apidocs/cloudant?code=python#postalldocs)|
|`db.bulk_docs()`|[`postBulkDocs`](https://cloud.ibm.com/apidocs/cloudant?code=python#postbulkdocs)|
|`db.changes()/db.infinite_changes()`|[`postChanges`](https://cloud.ibm.com/apidocs/cloudant?code=python#postchanges-databases)|
|`DesignDocument(db, '_design/doc').delete()`|[`deleteDesignDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#deletedesigndocument)|
|`db.get_design_document()/DesignDocument(db, '_design/doc').fetch()`|[`getDesignDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdesigndocument)|
|`DesignDocument(db, '_design/doc').save()`|[`putDesignDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#putdesigndocument)|
|`DesignDocument(db, '_design/doc').info()`|[`getDesignDocumentInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdesigndocumentinformation)|
|`db.get_search_result()`|[`postSearch`](https://cloud.ibm.com/apidocs/cloudant?code=python#postsearch)|
|`db.get_view_result()`|[`postView`](https://cloud.ibm.com/apidocs/cloudant?code=python#postview)|
|`db.list_design_documents()`|[`postDesignDocs`](https://cloud.ibm.com/apidocs/cloudant?code=python#postdesigndocs)|
|`db.get_query_result()`|[`postFind`](https://cloud.ibm.com/apidocs/cloudant?code=python#postfind)|
|`db.get_query_indexes()`|[`getIndexesInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getindexesinformation)|
|`db.create_query_index()`|[`postIndex`](https://cloud.ibm.com/apidocs/cloudant?code=python#postindex)|
|`db.delete_query_index()`|[`deleteIndex`](https://cloud.ibm.com/apidocs/cloudant?code=python#deleteindex)|
|`Document(db, '_local/docid').fetch()`|[`getLocalDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getlocaldocument)|
|`Document(db, '_local/docid').save()`|[`putLocalDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#putlocaldocument)|
|`Document(db, '_local/docid').delete()`|[`deleteLocalDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#deletelocaldocument)|
|`db.missing_revisions()/db.revisions_diff()`|[`postRevsDiff`](https://cloud.ibm.com/apidocs/cloudant?code=python#postrevsdiff)|
|`db.partition_metadata()`|[`getPartitionInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getpartitioninformation)|
|`db.partitioned_all_docs()`|[`postPartitionAllDocs`](https://cloud.ibm.com/apidocs/cloudant?code=python#postpartitionalldocs)|
|`db.get_partitioned_search_result()`|[`postPartitionSearch`](https://cloud.ibm.com/apidocs/cloudant?code=python#postpartitionsearch)|
|`db.get_partitioned_view_result()`|[`postPartitionView`](https://cloud.ibm.com/apidocs/cloudant?code=python#postpartitionview)|
|`db.get_partitioned_query_result()`|[`postPartitionFind`](https://cloud.ibm.com/apidocs/cloudant?code=python#postpartitionfind-partitioned-databases)|
|`db.get_security_document()/db.security_document()`|[`getSecurity`](https://cloud.ibm.com/apidocs/cloudant?code=python#getsecurity)|
|`db.share_database()`|[`putSecurity`](https://cloud.ibm.com/apidocs/cloudant?code=python#putsecurity)|
|`db.shards()`|[`getShardsInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getshardsinformation)|
|`Document(db, 'docid').delete()`|[`deleteDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#deletedocument)|
|`Document(db, 'docid').fetch()`|[`getDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#getdocument)|
|`Document(db, 'docid').exists()`|[`headDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#headdocument)|
|`Document(db, 'docid').save()`|[`putDocument`](https://cloud.ibm.com/apidocs/cloudant?code=python#putdocument)|
|`Document(db, 'docid').delete_attachment()`|[`deleteAttachment`](https://cloud.ibm.com/apidocs/cloudant?code=python#deleteattachment)|
|`Document(db, 'docid').get_attachment()`|[`getAttachment`](https://cloud.ibm.com/apidocs/cloudant?code=python#getattachment)|
|`Document(db, 'docid').put_attachment()`|[`putAttachment`](https://cloud.ibm.com/apidocs/cloudant?code=python#putattachment)|
|`generate_api_key()`|[`postApiKeys`](https://cloud.ibm.com/apidocs/cloudant?code=python#postapikeys)|
|`SecurityDocument().save()`|[`putCloudantSecurityConfiguration`](https://cloud.ibm.com/apidocs/cloudant?code=python#putcloudantsecurity)|
|`cors_configuration()/cors_origin()`|[`getCorsInformation`](https://cloud.ibm.com/apidocs/cloudant?code=python#getcorsinformation)|
|`update_cors_configuration()`|[`putCorsConfiguration`](https://cloud.ibm.com/apidocs/cloudant?code=python#putcorsconfiguration)|


================================================
FILE: README.md
================================================
# :warning: NO LONGER MAINTAINED :warning:

**This library is end-of-life and no longer supported.**

This repository will not be updated. The repository will be kept available in read-only mode.

Please see the [Migration Guide](./MIGRATION.md) for advice
about migrating to our replacement library
[cloudant-python-sdk](https://github.com/IBM/cloudant-python-sdk).

For FAQs and additional information please refer to the
[Cloudant blog](https://blog.cloudant.com/2021/06/30/Cloudant-SDK-Transition.html).

# Cloudant Python Client

[![Build Status](https://travis-ci.org/cloudant/python-cloudant.svg?branch=master)](https://travis-ci.org/cloudant/python-cloudant)
[![Readthedocs](https://readthedocs.org/projects/pip/badge/)](http://python-cloudant.readthedocs.io)
[![Compatibility](https://img.shields.io/badge/python-3.5-blue.svg)](http://python-cloudant.readthedocs.io/en/latest/compatibility.html)
[![pypi](https://img.shields.io/pypi/v/cloudant.svg)](https://pypi.python.org/pypi/cloudant)

This is the official Cloudant library for Python.

* [Installation and Usage](#installation-and-usage)
* [Getting Started](#getting-started)
* [API Reference](http://python-cloudant.readthedocs.io/en/latest/cloudant.html)
* [Related Documentation](#related-documentation)
* [Development](#development)
    * [Contributing](CONTRIBUTING.md)
    * [Test Suite](CONTRIBUTING.md#running-the-tests)
    * [Using in Other Projects](#using-in-other-projects)
    * [License](#license)
    * [Issues](#issues)
* [Migrating to `cloudant-python-sdk` library](#migrating-to-cloudant-python-sdk-library)

## Installation and Usage


Released versions of this library are [hosted on PyPI](https://pypi.python.org/pypi/cloudant) and can be installed with `pip`.

In order to install the latest version, execute

    pip install cloudant

## Getting started

See [Getting started (readthedocs.io)](http://python-cloudant.readthedocs.io/en/latest/getting_started.html)

## API Reference

See [API reference docs (readthedocs.io)](http://python-cloudant.readthedocs.io/en/latest/cloudant.html)

## Related Documentation

* [Cloudant Python client library docs (readthedocs.io)](http://python-cloudant.readthedocs.io)
* [Cloudant documentation](https://console.bluemix.net/docs/services/Cloudant/cloudant.html#overview)
* [Cloudant Learning Center](https://developer.ibm.com/clouddataservices/cloudant-learning-center/)
* [Tutorial for creating and populating a database on IBM Cloud](https://console.bluemix.net/docs/services/Cloudant/tutorials/create_database.html#creating-and-populating-a-simple-cloudant-nosql-db-database-on-ibm-cloud)

## Development

See [CONTRIBUTING.md](https://github.com/cloudant/python-cloudant/blob/master/CONTRIBUTING.md)

## Using in other projects

The preferred approach for using `python-cloudant` in other projects is to use the PyPI as described above.

### Examples in open source projects

[Getting Started with Python Flask on IBM Cloud](https://github.com/IBM-Cloud/get-started-python)

[Movie Recommender Demo](https://github.com/snowch/movie-recommender-demo):
- [Update and check if documents exist](https://github.com/snowch/movie-recommender-demo/blob/master/web_app/app/dao.py#L162-L168)
- [Connect to Cloudant using 429 backoff with 10 retries](https://github.com/snowch/movie-recommender-demo/blob/master/web_app/app/cloudant_db.py#L17-L18)

[Watson Recipe Bot](https://github.com/ibm-watson-data-lab/watson-recipe-bot-python-cloudant):
- [Use Cloudant Query to find design docs](https://github.com/ibm-watson-data-lab/watson-recipe-bot-python-cloudant/blob/master/souschef/cloudant_recipe_store.py#L33-L77)

## License

Copyright © 2015 IBM. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

## Issues

Before opening a new issue please consider the following:
* Only the latest release is supported. If at all possible please try to reproduce the issue using
the latest version.
* Please check the [existing issues](https://github.com/cloudant/python-cloudant/issues)
to see if the problem has already been reported. Note that the default search
includes only open issues, but it may already have been closed.
* Cloudant customers should contact Cloudant support for urgent issues.
* When opening a new issue [here in github](../../issues) please complete the template fully.

## Migrating to `cloudant-python-sdk` library
We have a newly supported Cloudant Python SDK named [cloudant-python-sdk](https://github.com/IBM/cloudant-python-sdk).
For advice on migrating from this module see [MIGRATION.md](MIGRATION.md).


================================================
FILE: VERSION
================================================
2.15.1-SNAPSHOT


================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext

help:
	@echo "Please use \`make <target>' where <target> is one of"
	@echo "  html       to make standalone HTML files"
	@echo "  dirhtml    to make HTML files named index.html in directories"
	@echo "  singlehtml to make a single large HTML file"
	@echo "  pickle     to make pickle files"
	@echo "  json       to make JSON files"
	@echo "  htmlhelp   to make HTML files and a HTML help project"
	@echo "  qthelp     to make HTML files and a qthelp project"
	@echo "  applehelp  to make an Apple Help Book"
	@echo "  devhelp    to make HTML files and a Devhelp project"
	@echo "  epub       to make an epub"
	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
	@echo "  text       to make text files"
	@echo "  man        to make manual pages"
	@echo "  texinfo    to make Texinfo files"
	@echo "  info       to make Texinfo files and run them through makeinfo"
	@echo "  gettext    to make PO message catalogs"
	@echo "  changes    to make an overview of all changed/added/deprecated items"
	@echo "  xml        to make Docutils-native XML files"
	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
	@echo "  linkcheck  to check all external links for integrity"
	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
	@echo "  coverage   to run coverage check of the documentation (if enabled)"

clean:
	rm -rf $(BUILDDIR)/*

html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/CloudantPythonclientlibrary.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/CloudantPythonclientlibrary.qhc"

applehelp:
	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
	@echo
	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
	@echo "N.B. You won't be able to view it unless you put it in" \
	      "~/Library/Documentation/Help or install it in your application" \
	      "bundle."

devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/CloudantPythonclientlibrary"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/CloudantPythonclientlibrary"
	@echo "# devhelp"

epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

latexpdfja:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through platex and dvipdfmx..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

texinfo:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo
	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
	@echo "Run \`make' in that directory to run these through makeinfo" \
	      "(use \`make info' here to do that automatically)."

info:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo "Running Texinfo files through makeinfo..."
	make -C $(BUILDDIR)/texinfo info
	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

gettext:
	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
	@echo
	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."

coverage:
	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
	@echo "Testing of coverage in the sources finished, look at the " \
	      "results in $(BUILDDIR)/coverage/python.txt."

xml:
	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
	@echo
	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."

pseudoxml:
	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
	@echo
	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."


================================================
FILE: docs/adapters.rst
================================================
adapters
========

.. automodule:: cloudant.adapters
    :members:
    :undoc-members:
    :special-members: __getitem__, __iter__
    :show-inheritance:


================================================
FILE: docs/client.rst
================================================
client
======

.. automodule:: cloudant.client
    :members:
    :undoc-members:
    :special-members: __getitem__, __delitem__, __setitem__
    :show-inheritance:


================================================
FILE: docs/cloudant.rst
================================================
Cloudant client library API
===========================

.. automodule:: cloudant
    :members:
    :undoc-members:
    :show-inheritance:

.. toctree::
   :maxdepth: 3

   modules


================================================
FILE: docs/compatibility.rst
================================================
Compatibility
=============

This library can be used with the following databases

* `IBM Cloudant® Database-as-a-Service <https://cloudant.com/>`_
* `IBM Cloudant® Data Layer Local Edition (Cloudant Local) <http://www.ibm.com/software/products/cloudant-data-layer-local-edition>`_
* `Apache CouchDB™ <http://couchdb.apache.org/>`_

Note that some features are Cloudant specific.

This library has been tested with the following versions of Python

*  `Python™ 3.5 <https://www.python.org/downloads/release/python-351/>`_


================================================
FILE: docs/conf.py
================================================
# -*- coding: utf-8 -*-
#
# Cloudant Python client library documentation build configuration file, created by
# sphinx-quickstart on Thu Nov 19 15:15:05 2015.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os
import shlex

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))

sys.path.insert(0, os.path.abspath('../src'))

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    'sphinx.ext.autodoc',
    'sphinx.ext.intersphinx'
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = u'python-cloudant'
copyright = u'2015, IBM'
author = u'IBM'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.15.1-SNAPSHOT'
# The full version, including alpha/beta/rc tags.
release = '2.15.1-SNAPSHOT'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']

# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = []

# otherwise, readthedocs.org uses their theme by default,
# so no need to specify it

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
#html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
#html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}

# If false, no module index is generated.
#html_domain_indices = True

# If false, no index is generated.
#html_use_index = True

# If true, the index is split into individual pages for each letter.
#html_split_index = False

# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
#html_search_language = 'en'

# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
#html_search_options = {'type': 'default'}

# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#html_search_scorer = 'scorer.js'

# Output file base name for HTML help builder.
htmlhelp_basename = 'CloudantPythonclientlibrarydoc'

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#'preamble': '',

# Latex figure (float) alignment
#'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
  (master_doc, 'CloudantPythonclientlibrary.tex', u'python-cloudant documentation',
   u'IBM', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
#latex_domain_indices = True


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'pythoncloudantclientlibrary', u'python-cloudant documentation',
     [author], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
  (master_doc, 'PythonCloudantclientlibrary', u'python-cloudant documentation',
   author, 'PythonCloudantclientlibrary', 'One line description of project.',
   'Miscellaneous'),
]

# Documents to append as an appendix to all manuals.
#texinfo_appendices = []

# If false, no module index is generated.
#texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}


================================================
FILE: docs/database.rst
================================================
database
========

.. automodule:: cloudant.database
    :members:
    :undoc-members:
    :special-members: __getitem__, __iter__
    :show-inheritance:


================================================
FILE: docs/design_document.rst
================================================
design_document
===============

.. automodule:: cloudant.design_document
    :members:
    :exclude-members: info
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/document.rst
================================================
document
========

.. automodule:: cloudant.document
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/error.rst
================================================
error
=====

.. automodule:: cloudant.error
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/feed.rst
================================================
feed
====

.. automodule:: cloudant.feed
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/getting_started.rst
================================================
###############
Getting started
###############

Now it's time to begin doing some work with Cloudant and Python.  For working
code samples of any of the API's please go to our test suite.

.. toctree::
   :maxdepth: 2

***********
Connections
***********

In order to manage a connection you must first initialize the connection by 
constructing either a ``Cloudant`` or ``CouchDB`` client.  Since connecting to 
the Cloudant managed service provides extra end points as compared to a CouchDB 
server, we provide the two different client implementations in order to 
connect to the desired database service.  Once the client is constructed, 
you follow that up by connecting to the server, performing your tasks, and
then disconnecting from the server.

Later in the `Context managers`_ section we will see how to 
simplify this process through the use of the Python *with* statement.

Note: If you require retrying requests after an HTTP 429 error, the
``Replay429Adapter`` can be added when constructing a ``Cloudant``
client and configured with an initial back off and retry count.

Note: Currently, the connect and read timeout will wait forever for
a HTTP connection or a response on all requests.  A timeout can be
set using the ``timeout`` argument when constructing a client.

Connecting with a client
========================

.. code-block:: python

    # Use CouchDB to create a CouchDB client
    # from cloudant.client import CouchDB
    # client = CouchDB(USERNAME, PASSWORD, url='http://127.0.0.1:5984', connect=True)

    # Use Cloudant to create a Cloudant client using account
    from cloudant.client import Cloudant
    client = Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME, connect=True)
    # or using url
    # client = Cloudant(USERNAME, PASSWORD, url='https://acct.cloudant.com')

    # or with a 429 replay adapter that includes configured retries and initial backoff
    # client = Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME,
    #                   adapter=Replay429Adapter(retries=10, initialBackoff=0.01))

    # or with a connect and read timeout of 5 minutes
    # client = Cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME,
    #                   timeout=300)

    # Perform client tasks...
    session = client.session()
    print('Username: {0}'.format(session['userCtx']['name']))
    print('Databases: {0}'.format(client.all_dbs()))

    # Disconnect from the server
    client.disconnect()

**************
Authentication
**************

When constructing a ``Cloudant`` client, you can authenticate using the
`cookie authentication <http://guide.couchdb.org/editions/1/en/security.html#cookies>`_ functionality.
The server will always attempt to automatically renew the cookie
shortly before its expiry. However, if the client does not send a
request to the server during this renewal window and
``auto_renew=False`` then the cookie is not renewed.

Using ``auto_renew=True`` will attempt to renew the cookie at
any point during the lifetime of the session when either of the
following statements hold true:

- The server returns a ``credentials_expired`` error message.
- The server returns a ``401 Unauthorized`` status code.
- The server returns a ``403 Forbidden`` status code.

.. code-block:: python

    # Create client using auto_renew to automatically renew expired cookie auth
    client = Cloudant(USERNAME, PASSWORD, url='https://acct.cloudant.com',
                     connect=True,
                     auto_renew=True)


************************************
Identity and Access Management (IAM)
************************************

IBM Cloud Identity & Access Management enables you to securely authenticate
users and control access to all cloud resources consistently in the IBM Bluemix
Cloud Platform.

See `IBM Cloud Identity and Access Management <https://console.bluemix.net/docs/services/Cloudant/guides/iam.html#ibm-cloud-identity-and-access-management>`_
for more information.

The production IAM token service at *https://iam.cloud.ibm.com/identity/token* is used
by default. You can set an ``IAM_TOKEN_URL`` environment variable to override
this.

You can easily connect to your Cloudant account using an IAM API key:

.. code-block:: python

    # Authenticate using an IAM API key
    client = Cloudant.iam(ACCOUNT_NAME, API_KEY, connect=True)

If you need to authenticate to a server outside of the `cloudant.com` domain, you can use the `url` parameter:

.. code-block:: python

    # Authenticate using an IAM API key to an account outside of the cloudant.com domain
    client = Cloudant.iam(None, API_KEY, url='https://private.endpoint.example', connect=True)


****************
Resource sharing
****************

The ``Cloudant`` or ``CouchDB`` client objects make HTTP calls using the ``requests`` library.
``requests`` uses the `urllib3 <https://pypi.python.org/pypi/urllib3>`_ library which features
connection pooling and thread safety.

Connection pools can be managed by using the ``requests`` library's
`HTTPAdapter <https://github.com/kennethreitz/requests/blob/master/requests/adapters.py#L78>`_
when constructing a ``Cloudant`` or ``ClouchDB`` client instance.
The default number set by the ``urllib3`` library for cached connection pools is 10.
Use the ``HTTPAdapter`` argument ``pool_connections`` to set the number of
urllib3 connection pools to cache, and the ``pool_maxsize`` argument to set the
maximum number of connections to save in the pool.

Although the ``client`` session is documented as thread safe and it's possible for a
static ``client`` to be accessible by multiple threads, there are still cases that do not
guarantee thread safe execution.  It's recommended to use one ``client`` object per thread.

.. code-block:: python

    # Create client with 15 cached pool connections and a max pool size of 100
    httpAdapter = HTTPAdapter(pool_connections=15, pool_maxsize=100)
    client = Cloudant(USERNAME, PASSWORD, url='https://acct.cloudant.com'
                     connect=True,
                     adapter=httpAdapter)

Note: Idle connections within the pool may be terminated by the server, so will not remain open
indefinitely meaning that this will not completely remove the overhead of creating new connections.

Using library in app server environment
=======================================

This library can be used in an app server, and the example
below shows how to use ``client`` in a ``flask`` app server.

.. code-block:: python

   from flask import Flask
   import atexit

   app = Flask(__name__)

   @app.route('/')
   def hello_world():
      # Cookie authentication can be renewed automatically using ``auto_renew=True``
      # which is typically what you would require when running in an application
      # server where the connection may stay open for a long period of time

      # Note: Each time you instantiate an instance of the Cloudant client, an
      # authentication request will be made to Cloudant to retrieve the session cookie.
      # If the performance overhead of this call is a concern for you, consider
      # using vanilla python requests with a custom subclass of HTTPAdapter that
      # performs the authentication call to Cloudant when it establishes the http
      # connection during the creation of the connection pool.
      client = Cloudant(USERNAME, PASSWORD, url='https://acct.cloudant.com',
                        connect=True,
                        auto_renew=True)

      # do something with client
      return 'Hello World!'

   # When shutting down the app server, use ``client.disconnect()`` to properly
   # logout and end the ``client`` session
   @atexit.register
   def shutdown():
      client.disconnect()

*********
Databases
*********

Once a connection is established you can then create a database, open an 
existing database, or delete a database.  The following examples assume a client 
connection has already been established.

Creating a database
===================

.. code-block:: python

    # Create a database using an initialized client
    # The result is a new CloudantDatabase or CouchDatabase based on the client
    my_database = client.create_database('my_database')

    # You can check that the database exists
    if my_database.exists():
        print('SUCCESS!!')

Opening a database
==================

Opening an existing database is done by supplying the name of an existing 
database to the client.  Since the ``Cloudant`` and ``CouchDB`` classes are 
sub-classes of ``dict``, this can be accomplished through standard Python
``dict`` notation.

.. code-block:: python

    # Open an existing database
    my_database = client['my_database']

Deleting a database
===================

.. code-block:: python

    # Delete a database using an initialized client
    client.delete_database('my_database')


Partitioned Databases
=====================

Partitioned databases introduce the ability for a user to create logical groups
of documents called partitions by providing a partition key with each document.

.. warning:: Your Cloudant cluster must have the ``partitions`` feature enabled.
             A full list of enabled features can be retrieved by calling the
             client :func:`~cloudant.client.CouchDB.metadata` method.

Creating a partitioned database
-------------------------------

.. code-block:: python

    db = client.create_database('mydb', partitioned=True)

Handling documents
------------------

The document ID contains both the partition key and document key in the form
``<partitionkey>:<documentkey>`` where:

- Partition Key *(string)*. Must be non-empty. Must not contain colons (as this
  is the partition key delimiter) or begin with an underscore.
- Document Key *(string)*. Must be non-empty. Must not begin with an underscore.

Be aware that ``_design`` documents and ``_local`` documents must not contain a
partition key as they are global definitions.

**Create a document**

.. code-block:: python

    partition_key = 'Year2'
    document_key = 'julia30'
    db.create_document({
        '_id': ':'.join((partition_key, document_key)),
        'name': 'Jules',
        'age': 6
    })

**Get a document**

.. code-block:: python

    doc = db[':'.join((partition_key, document_key))]

Creating design documents
-------------------------

To define partitioned indexes you must set the ``partitioned=True`` optional
when constructing the new ``DesignDocument`` class.

.. code-block:: python

    ddoc = DesignDocument(db, document_id='view', partitioned=True)
    ddoc.add_view('myview','function(doc) { emit(doc.foo, doc.bar); }')
    ddoc.save()


To define a partitioned Cloudant Query index you may set the
``partitioned=True`` optional, but it is not required as the index will be
partitioned by default in a partitioned database. Conversely, you must
set the ``partitioned=False`` optional if you wish to create a global
(non-partitioned) index in a partitioned database.

.. code-block:: python

    index = db.create_query_index(
        design_document_id='query',
        index_name='foo-index',
        fields=['foo'],
        partitioned=True
    )
    index.create()

Querying data
-------------

A partition key can be specified when querying data so that results can be
constrained to a specific database partition.

.. warning:: To run partitioned queries the database itself must be partitioned.

**Query**

.. code-block:: python

    results = self.db.get_partitioned_query_result(
        partition_key, selector={'foo': {'$eq': 'bar'}})

    for result in results:
        ...

See :func:`~cloudant.database.CouchDatabase.get_partitioned_query_result` for a
full list of supported parameters.

**Search**

.. code-block:: python

    results = self.db.get_partitioned_search_result(
        partition_key, search_ddoc['_id'], 'search1', query='*:*')

    for result in results['rows']:
        ....

See :func:`~cloudant.database.CloudantDatabase.get_partitioned_search_result`
for a full list of supported parameters.

**Views (MapReduce)**

.. code-block:: python

    results = self.db.get_partitioned_view_result(
        partition_key, view_ddoc['_id'], 'view1')

    for result in results:
        ....

See :func:`~cloudant.database.CouchDatabase.get_partitioned_view_result` for a
full list of supported parameters.

*********
Documents
*********

Working with documents using this library is handled through the use of 
Document objects and Database API methods.  A document context 
manager is also provided to simplify the process.  This is discussed later in 
the `Context managers`_ section.  The examples that follow demonstrate how to 
create, read, update, and delete a document.  These examples assume that 
either a CloudantDatabase or a CouchDatabase object already exists.

Creating a document
===================

.. code-block:: python

    # Create document content data
    data = {
        '_id': 'julia30', # Setting _id is optional
        'name': 'Julia',
        'age': 30,
        'pets': ['cat', 'dog', 'frog']
        }

    # Create a document using the Database API
    my_document = my_database.create_document(data)

    # Check that the document exists in the database
    if my_document.exists():
        print('SUCCESS!!')

Retrieving a document
=====================

Accessing a document from a database is done by supplying the document 
identifier of an existing document to either a ``CloudantDatabase`` or a 
``CouchDatabase`` object.  Since the ``CloudantDatabase`` and ``CouchDatabase`` 
classes are sub-classes of ``dict``, this is accomplished through standard 
``dict`` notation.

.. code-block:: python

    my_document = my_database['julia30']

    # Display the document
    print(my_document)

Checking if a document exists
=============================

You can check if a document exists in a database the same way you would check
if a ``dict`` has a key-value pair by key.

.. code-block:: python

    doc_exists = 'julia30' in my_database

    if doc_exists:
        print('document with _id julia30 exists')

Retrieve all documents
======================

You can also iterate over a ``CloudantDatabase`` or a ``CouchDatabase`` object 
to retrieve all documents in a database.

.. code-block:: python

    # Get all of the documents from my_database
    for document in my_database:
        print(document)

Update a document
=================

.. code-block:: python

    # First retrieve the document
    my_document = my_database['julia30']

    # Update the document content
    # This can be done as you would any other dictionary
    my_document['name'] = 'Jules'
    my_document['age'] = 6

    # You must save the document in order to update it on the database
    my_document.save()

Delete a document
=================

.. code-block:: python

    # First retrieve the document
    my_document = my_database['julia30']

    # Delete the document
    my_document.delete()

********************
Dealing with results
********************

If you want to get Pythonic with your returned data content, we've added a 
``Result`` class that provides a key accessible, sliceable, and iterable 
interface to result collections.  To use it, construct a ``Result`` object 
passing in a reference to a raw data callable such as the ``all_docs`` method 
from a database object or a ``view`` object itself, which happens to be defined 
as callable and then access the data as you would using standard Python key 
access, slicing, and iteration techniques.  The following set of examples 
illustrate ``Result`` key access, slicing and iteration over a result collection 
in action.  It assumes that either a ``CloudantDatabase`` or a ``CouchDatabase`` 
object already exists.

.. code-block:: python

    from cloudant.result import Result, ResultByKey

    # Retrieve Result wrapped document content.
    # Note: The include_docs parameter is optional and is used to illustrate that view query 
    # parameters can be used to customize the result collection.
    result_collection = Result(my_database.all_docs, include_docs=True)

    # Get the result at a given location in the result collection
    # Note: Valid result collection indexing starts at 0
    result = result_collection[0]                   # result is the 1st in the collection
    result = result_collection[9]                   # result is the 10th in the collection

    # Get the result for matching a key
    result = result_collection['julia30']           # result is all that match key 'julia30'
    
    # If your key is an integer then use the ResultByKey class to differentiate your integer 
    # key from an indexed location within the result collection which is also an integer.
    result = result_collection[ResultByKey(9)]      # result is all that match key 9

    # Slice by key values
    result = result_collection['julia30': 'ruby99'] # result is between and including keys
    result = result_collection['julia30': ]         # result is after and including key
    result = result_collection[: 'ruby99']          # result is up to and including key

    # Slice by index values
    result = result_collection[100: 200]            # result is between 100 to 200, including 200th
    result = result_collection[: 200]               # result is up to and including the 200th
    result = result_collection[100: ]               # result is after the 100th

    # Iterate over the result collection
    for result in result_collection:
        print(result)

This example retrieves the query result from the specified database based on the query parameters provided, updates the
document, and saves the document in the remote database.
By default, the result is returned as a ``QueryResult`` which uses the skip and limit query parameters internally to
handle slicing and iteration through the query result collection.  For more detail on slicing and iteration, refer
to the :class:`~cloudant.result.QueryResult` documentation.

.. code-block:: python

  # Retrieve documents where the name field is 'foo'
  selector = {'name': {'$eq': 'foo'}}
  docs = my_database.get_query_result(selector)
  for doc in docs:
   # Create Document object from dict
   updated_doc = Document(my_database, doc['_id'])
   updated_doc.update(doc)
   # Update document field
   updated_doc['name'] = 'new_name'
   # Save document
   updated_doc.save()

****************
Context managers
****************

Now that we've gone through the basics, let's take a look at how to simplify 
the process of connection, database acquisition, and document management 
through the use of Python *with* blocks and this library's context managers.  

Handling your business using *with* blocks saves you from having to connect and
disconnect your client as well as saves you from having to perform a lot of 
fetch and save operations as the context managers handle these operations for 
you.

This example uses the ``cloudant`` context helper to illustrate the
process but identical functionality exists for CouchDB through the ``couchdb`` 
and ``couchdb_admin_party`` context helpers.

.. code-block:: python

    from cloudant import cloudant

    # ...or use CouchDB variant
    # from cloudant import couchdb

    # Perform a connect upon entry and a disconnect upon exit of the block
    with cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME) as client:

    # ...or use CouchDB variant
    # with couchdb(USERNAME, PASSWORD, url=COUCHDB_URL) as client:
    
        # Perform client tasks...
        session = client.session()
        print('Username: {0}'.format(session['userCtx']['name']))
        print('Databases: {0}'.format(client.all_dbs()))

        # Create a database
        my_database = client.create_database('my_database')
        if my_database.exists():
            print('SUCCESS!!')

        # You can open an existing database
        del my_database
        my_database = client['my_database']

The following example uses the ``Document`` context manager. Here we make
multiple updates to a single document. Note that we don't save to the server
after each update. We only save once to the server upon exiting the ``Document``
context manager.

.. warning:: Uncaught exceptions inside the ``with`` block will prevent your
             document changes being saved to the remote server. However, changes
             will still be applied to your local document object.

.. code-block:: python

   from cloudant import cloudant
   from cloudant.document import Document

   with cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME) as client:

       my_database = client.create_database('my_database')

       # Upon entry into the document context, fetches the document from the
       # remote database, if it exists. Upon exit from the context, saves the
       # document to the remote database with changes made within the context
       # or creates a new document.
       with Document(database, 'julia006') as document:
           # If document exists, it's fetched from the remote database
           # Changes are made locally
           document['name'] = 'Julia'
           document['age'] = 6
           # The document is saved to the remote database

       # Display a Document
       print(my_database['julia30'])

       # Delete the database
       client.delete_database('my_database')

       print('Databases: {0}'.format(client.all_dbs()))

Always use the ``_deleted`` document property to delete a document from within
a ``Document`` context manager. For example:

.. code-block:: python

   with Document(my_database, 'julia30') as doc:
       doc['_deleted'] = True

*You can also delete non underscore prefixed document keys to reduce the size of the request.*

.. warning:: Don't use the ``doc.delete()`` method inside your ``Document``
             context manager. This method immediately deletes the document on
             the server and clears the local document dictionary. A new, empty
             document is still saved to the server upon exiting the context
             manager.

****************
Endpoint access
****************

If for some reason you need to call a Cloudant/CouchDB endpoint directly rather 
using the API you can still benefit from the Cloudant/CouchDB client's 
authentication and session usage by directly accessing its underlying Requests_ 
session object.

Access the session object using the ``r_session`` attribute on your client 
object. From there, use the session to make requests as the user the client is 
set up with. The following example shows a ``GET`` to the ``_all_docs`` 
endpoint, but obviously you can use this for any HTTP request to the 
Cloudant/CouchDB server.  This example assumes that either a ``Cloudant`` or a 
``CouchDB`` client object already exists.

.. _Requests: http://docs.python-requests.org/en/latest/

.. code-block:: python

    # Define the end point and parameters
    end_point = '{0}/{1}'.format(client.server_url, 'my_database/_all_docs')
    params = {'include_docs': 'true'}

    # Issue the request
    response = client.r_session.get(end_point, params=params)

    # Display the response content
    print(response.json())

***************
TLS 1.2 Support
***************

The TLS protocol is used to encrypt communications across a network to ensure
that transmitted data remains private. There are three released versions of TLS:
1.0, 1.1, and 1.2. All HTTPS connections use TLS.

If your server enforces the use of TLS 1.2 then the python-cloudant client will
continue to work as expected (assuming you're running a version of
Python/OpenSSL that supports TLS 1.2).


================================================
FILE: docs/index.rst
================================================
This library is end-of-life and no longer supported.


================================================
FILE: docs/make.bat
================================================
@ECHO OFF

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
	set SPHINXBUILD=sphinx-build
)
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
set I18NSPHINXOPTS=%SPHINXOPTS% .
if NOT "%PAPER%" == "" (
	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)

if "%1" == "" goto help

if "%1" == "help" (
	:help
	echo.Please use `make ^<target^>` where ^<target^> is one of
	echo.  html       to make standalone HTML files
	echo.  dirhtml    to make HTML files named index.html in directories
	echo.  singlehtml to make a single large HTML file
	echo.  pickle     to make pickle files
	echo.  json       to make JSON files
	echo.  htmlhelp   to make HTML files and a HTML help project
	echo.  qthelp     to make HTML files and a qthelp project
	echo.  devhelp    to make HTML files and a Devhelp project
	echo.  epub       to make an epub
	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
	echo.  text       to make text files
	echo.  man        to make manual pages
	echo.  texinfo    to make Texinfo files
	echo.  gettext    to make PO message catalogs
	echo.  changes    to make an overview over all changed/added/deprecated items
	echo.  xml        to make Docutils-native XML files
	echo.  pseudoxml  to make pseudoxml-XML files for display purposes
	echo.  linkcheck  to check all external links for integrity
	echo.  doctest    to run all doctests embedded in the documentation if enabled
	echo.  coverage   to run coverage check of the documentation if enabled
	goto end
)

if "%1" == "clean" (
	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
	del /q /s %BUILDDIR%\*
	goto end
)


REM Check if sphinx-build is available and fallback to Python version if any
%SPHINXBUILD% 2> nul
if errorlevel 9009 goto sphinx_python
goto sphinx_ok

:sphinx_python

set SPHINXBUILD=python -m sphinx.__init__
%SPHINXBUILD% 2> nul
if errorlevel 9009 (
	echo.
	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
	echo.installed, then set the SPHINXBUILD environment variable to point
	echo.to the full path of the 'sphinx-build' executable. Alternatively you
	echo.may add the Sphinx directory to PATH.
	echo.
	echo.If you don't have Sphinx installed, grab it from
	echo.http://sphinx-doc.org/
	exit /b 1
)

:sphinx_ok


if "%1" == "html" (
	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
	goto end
)

if "%1" == "dirhtml" (
	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
	goto end
)

if "%1" == "singlehtml" (
	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
	goto end
)

if "%1" == "pickle" (
	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished; now you can process the pickle files.
	goto end
)

if "%1" == "json" (
	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished; now you can process the JSON files.
	goto end
)

if "%1" == "htmlhelp" (
	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
	goto end
)

if "%1" == "qthelp" (
	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\CloudantPythonclientlibrary.qhcp
	echo.To view the help file:
	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\CloudantPythonclientlibrary.ghc
	goto end
)

if "%1" == "devhelp" (
	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished.
	goto end
)

if "%1" == "epub" (
	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The epub file is in %BUILDDIR%/epub.
	goto end
)

if "%1" == "latex" (
	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
	goto end
)

if "%1" == "latexpdf" (
	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
	cd %BUILDDIR%/latex
	make all-pdf
	cd %~dp0
	echo.
	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
	goto end
)

if "%1" == "latexpdfja" (
	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
	cd %BUILDDIR%/latex
	make all-pdf-ja
	cd %~dp0
	echo.
	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
	goto end
)

if "%1" == "text" (
	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The text files are in %BUILDDIR%/text.
	goto end
)

if "%1" == "man" (
	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The manual pages are in %BUILDDIR%/man.
	goto end
)

if "%1" == "texinfo" (
	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
	goto end
)

if "%1" == "gettext" (
	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
	goto end
)

if "%1" == "changes" (
	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
	if errorlevel 1 exit /b 1
	echo.
	echo.The overview file is in %BUILDDIR%/changes.
	goto end
)

if "%1" == "linkcheck" (
	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
	if errorlevel 1 exit /b 1
	echo.
	echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
	goto end
)

if "%1" == "doctest" (
	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
	if errorlevel 1 exit /b 1
	echo.
	echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
	goto end
)

if "%1" == "coverage" (
	%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
	if errorlevel 1 exit /b 1
	echo.
	echo.Testing of coverage in the sources finished, look at the ^
results in %BUILDDIR%/coverage/python.txt.
	goto end
)

if "%1" == "xml" (
	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The XML files are in %BUILDDIR%/xml.
	goto end
)

if "%1" == "pseudoxml" (
	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
	if errorlevel 1 exit /b 1
	echo.
	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
	goto end
)

:end


================================================
FILE: docs/module_index.rst
================================================
index
=====

.. automodule:: cloudant.index
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/modules.rst
================================================
Modules
=======

.. toctree::
   :maxdepth: 2

   client
   database
   document
   design_document
   security_document
   view
   query
   module_index
   result
   replicator
   feed
   error
   adapters


================================================
FILE: docs/query.rst
================================================
query
=====

.. automodule:: cloudant.query
    :members:
    :undoc-members:
    :special-members: __call__
    :show-inheritance:


================================================
FILE: docs/replicator.rst
================================================
replicator
==========

.. automodule:: cloudant.replicator
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/result.rst
================================================
result
======

.. automodule:: cloudant.result
    :members:
    :undoc-members:
    :special-members: __getitem__, __iter__
    :exclude-members: type_or_none
    :show-inheritance:


================================================
FILE: docs/security_document.rst
================================================
security_document
=================

.. automodule:: cloudant.security_document
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/view.rst
================================================
view
====

.. automodule:: cloudant.view
    :members:
    :undoc-members:
    :special-members: __call__
    :show-inheritance:


================================================
FILE: pylintrc
================================================
[MASTER]

# Specify a configuration file.
rcfile=pylintrc

# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=

# Profiled execution.
profile=no

# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS

# Pickle collected data for later comparisons.
persistent=yes

# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=

# Use multiple processes to speed up Pylint.
jobs=1

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no

# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=

# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality.
optimize-ast=no


[MESSAGES CONTROL]

# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
#enable=

# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"

# Disable "redefined-variable-type" refactor warning messages
# Disable "too-many-..." and "too-few-..." refactor warning messages
# Disable "locally-disabled" message
# Disable Python 3 "useless-object-inheritance" message
disable=R0204,R0901,R0902,R0903,R0904,R0913,R0914,R0915,locally-disabled,keyword-arg-before-vararg,useless-object-inheritance


[REPORTS]

# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text

# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no

# Tells whether to display a full report or only the messages
reports=yes

# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)

# Add a comment according to your evaluation note. This is used by the global
# evaluation report (RP0004).
comment=no

# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=


[BASIC]

# Required attributes for module, separated by a comma
required-attributes=

# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,input

# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,db

# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata

# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=

# Include a hint for the correct naming format with invalid-name
include-naming-hint=no

# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$

# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$

# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$

# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=__.*__

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1


[FORMAT]

# Maximum number of characters on a single line.
max-line-length=100

# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$

# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no

# List of optional constructs for which whitespace checking is disabled
no-space-check=trailing-comma,dict-separator

# Maximum number of lines in a module
max-module-lines=2000

# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string='    '

# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4

# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=


[LOGGING]

# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging


[MISCELLANEOUS]

# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO


[SIMILARITIES]

# Minimum lines number of a similarity.
min-similarity-lines=5

# Ignore comments when computing similarities.
ignore-comments=yes

# Ignore docstrings when computing similarities.
ignore-docstrings=yes

# Ignore imports when computing similarities.
ignore-imports=no


[SPELLING]

# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=

# List of comma separated words that should not be checked.
spelling-ignore-words=

# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=

# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no


[TYPECHECK]

# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis
ignored-modules=

# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject

# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=no

# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent


[VARIABLES]

# Tells whether we should check for unused import in __init__ files.
init-import=no

# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_$|dummy

# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=

# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb


[CLASSES]

# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defines in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by

# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp

# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls

# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs

# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make


[DESIGN]

# Maximum number of arguments for function / method
max-args=5

# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*

# Maximum number of locals for function / method body
max-locals=15

# Maximum number of return / yield for function / method body
max-returns=6

# Maximum number of branch for function / method body
max-branches=12

# Maximum number of statements in function / method body
max-statements=50

# Maximum number of parents for a class (see R0901).
max-parents=7

# Maximum number of attributes for a class (see R0902).
max-attributes=7

# Minimum number of public methods for a class (see R0903).
min-public-methods=2

# Maximum number of public methods for a class (see R0904).
max-public-methods=20


[IMPORTS]

# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec

# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=

# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=

# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=


[EXCEPTIONS]

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception


================================================
FILE: requirements.txt
================================================
requests >=2.7.0, <3.0.0


================================================
FILE: setup.py
================================================
#!/usr/bin/env python
# Copyright (c) 2015 IBM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
_setup.py_

Cloudant / CouchDB Client Library

"""

from io import open
from os import path
from setuptools import setup, find_packages

requirements_file = open('requirements.txt')
requirements = requirements_file.read().strip().split('\n')
requirements_file.close()
version_file = open('VERSION')
version = version_file.read().strip()
version_file.close()

this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup_args = {
    'description': 'Cloudant / CouchDB Client Library',
    'long_description': long_description,
    'long_description_content_type': 'text/markdown',
    'include_package_data': True,
    'install_requires': requirements,
    'name': 'cloudant',
    'version': version,
    'author': 'IBM',
    'author_email': 'alfinkel@us.ibm.com',
    'url': 'https://github.com/cloudant/python-cloudant',
    'packages': find_packages('./src'),
    'provides': find_packages('./src'),
    'package_dir': {'': 'src'},
    'classifiers': [
          'Intended Audience :: Developers',
          'Natural Language :: English',
          'License :: OSI Approved :: Apache Software License',
          'Topic :: Software Development :: Libraries',
          'Development Status :: 5 - Production/Stable',
          'Programming Language :: Python',
          'Programming Language :: Python :: 3',
          'Programming Language :: Python :: 3.5'
      ]
}

setup(**setup_args)


================================================
FILE: src/cloudant/_2to3.py
================================================
# Copyright (c) 2016, 2017 IBM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Python 2 to 3 compatibility methods

The philosophy employed here is to treat py2 as the special case vs. py3 as
future Python releases presumably will retain new semamtics in py3.
"""
import sys

PY2 = sys.version_info[0] < 3
ENCODING = 'utf-8'
NONETYPE = type(None)

# pylint: disable=undefined-variable
STRTYPE = basestring if PY2 else str

# pylint: disable=undefined-variable
UNITYPE = unicode if PY2 else str

# pylint: disable=undefined-variable
LONGTYPE = long if PY2 else int

# pylint: disable=undefined-variable
UNICHR = unichr if PY2 else chr

if PY2:
    # pylint: disable=wrong-import-position,no-name-in-module,import-error,unused-import
    from urllib import quote as url_quote, quote_plus as url_quote_plus
    from urlparse import urlparse as url_parse
    from urlparse import urljoin as url_join
    from ConfigParser import RawConfigParser
    from cookielib import Cookie

    def iteritems_(adict):
        """
        iterate dict key, value tuples in a py2 and 3 compatible way

        :param dict adict:
        :return: iterator of (key, value) tuples
        """
        return adict.iteritems()

    def next_(itr):
        """
        return next item from an iterable is a py2 and 3 compatible way

        :param Iterable itr:
        :return: the next item in itr
        """
        return itr.next()
else:
    from urllib.parse import urlparse as url_parse  # pylint: disable=wrong-import-position,no-name-in-module,import-error,ungrouped-imports
    from urllib.parse import urljoin as url_join  # pylint: disable=wrong-import-position,no-name-in-module,import-error,ungrouped-imports
    from urllib.parse import quote as url_quote  # pylint: disable=wrong-import-position,no-name-in-module,import-error,ungrouped-imports
    from urllib.parse import quote_plus as url_quote_plus  # pylint: disable=wrong-import-position,no-name-in-module,import-error,ungrouped-imports
    from configparser import RawConfigParser  # pylint: disable=wrong-import-position,no-name-in-module,import-error
    from http.cookiejar import Cookie # pylint: disable=wrong-import-position,no-name-in-module,import-error

    def iteritems_(adict):
        """
        iterate dict key, value tuples in a py2 and 3 compatible way

        :param dict adict:
        :return: iterator of (key, value) tuples
        """
        return adict.items()

    def next_(itr):
        """
        return the next item in an iterable in a py2 and 3 compatible way

        :param Iterable itr:
        :return: the next item in itr
        """
        return next(itr)


def bytes_(astr):
    """
    return a bytes representation of astr in a py2 and 3 compatible way

    :param str astr:
    :return: bytes object
    """
    return astr.encode(ENCODING) if hasattr(astr, 'encode') else astr


def unicode_(astr):
    """
    return a unicode string representation of astr in a py2 and 3 compatible way

    :param bytes astr:
    :return: unicode string
    """
    return astr.decode(ENCODING) if hasattr(astr, 'decode') else astr


================================================
FILE: src/cloudant/__init__.py
================================================
#!/usr/bin/env python
# Copyright (c) 2015, 2018 IBM. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Cloudant / CouchDB Python client library API package
"""
__version__ = '2.15.1-SNAPSHOT'

# pylint: disable=wrong-import-position
import contextlib
import warnings
# pylint: disable=wrong-import-position
from .client import Cloudant, CouchDB
from ._common_util import CloudFoundryService

warnings.warn('The module cloudant is now end-of-life. The replacement is ibmcloudant.',
              DeprecationWarning)

@contextlib.contextmanager
def cloudant(user, passwd, **kwargs):
    """
    Provides a context manager to create a Cloudant session and
    provide access to databases, docs etc.

    :param str user: Username used to connect to Cloudant.
    :param str passwd: Authentication token used to connect to Cloudant.
    :param str account: The Cloudant account name.  If the account parameter
        is present, it will be used to construct the Cloudant service URL.
    :param str url: If the account is not present and the url parameter is
        present then it will be used to set the Cloudant service URL.  The
        url must be a fully qualified http/https URL.
    :param str x_cloudant_user: Override the X-Cloudant-User setting used to
        authenticate. This is needed to authenticate on one's behalf,
        eg with an admin account.  This parameter must be accompanied
        by the url parameter.  If the url parameter is omitted then
        the x_cloudant_user parameter setting is ignored.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage. Defaults to json.JSONEncoder.

    For example:

    .. code-block:: python

        # cloudant context manager
        from cloudant import cloudant

        with cloudant(USERNAME, PASSWORD, account=ACCOUNT_NAME) as client:
            # Context handles connect() and disconnect() for you.
            # Perform library operations within this context.  Such as:
            print client.all_dbs()
            # ...
    """
    cloudant_session = Cloudant(user, passwd, **kwargs)
    cloudant_session.connect()
    yield cloudant_session
    cloudant_session.disconnect()

@contextlib.contextmanager
def cloudant_iam(account_name, api_key, **kwargs):
    """
    Provides a context manager to create a Cloudant session using IAM
    authentication and provide access to databases, docs etc.

    :param account_name: Cloudant account name.
    :param api_key: IAM authentication API key.

    For example:

    .. code-block:: python

        # cloudant context manager
        from cloudant import cloudant_iam

        with cloudant_iam(ACCOUNT_NAME, API_KEY) as client:
            # Context handles connect() and disconnect() for you.
            # Perform library operations within this context.  Such as:
            print client.all_dbs()
            # ...

    """
    cloudant_session = Cloudant.iam(account_name, api_key, **kwargs)

    cloudant_session.connect()
    yield cloudant_session
    cloudant_session.disconnect()

@contextlib.contextmanager
def cloudant_bluemix(vcap_services, instance_name=None, service_name=None, **kwargs):
    """
    Provides a context manager to create a Cloudant session and provide access
    to databases, docs etc.

    :param vcap_services: VCAP_SERVICES environment variable
    :type vcap_services: dict or str
    :param str instance_name: Optional Bluemix instance name. Only required if
        multiple Cloudant instances are available.
    :param str service_name: Optional Bluemix service name.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage. Defaults to json.JSONEncoder.

    Loads all configuration from the specified VCAP_SERVICES Cloud Foundry
    environment variable. The VCAP_SERVICES variable contains connection
    information to access a service instance. For example:

    .. code-block:: json

        {
            "VCAP_SERVICES": {
                "cloudantNoSQLDB": [
                    {
                        "credentials": {
                            "apikey": "some123api456key"
                            "username": "example",
                            "password": "xxxxxxx",
                            "host": "example.cloudant.com",
                            "port": 443,
                            "url": "https://example:xxxxxxx@example.cloudant.com"
                        },
                        "syslog_drain_url": null,
                        "label": "cloudantNoSQLDB",
                        "provider": null,
                        "plan": "Lite",
                        "name": "Cloudant NoSQL DB"
                    }
                ]
            }
        }

    See `Cloud Foundry Environment Variables <http://docs.cloudfoundry.org/
    devguide/deploy-apps/environment-variable.html#VCAP-SERVICES>`_.

    Example usage:

    .. code-block:: python

        import os

        # cloudant_bluemix context manager
        from cloudant import cloudant_bluemix

        with cloudant_bluemix(os.getenv('VCAP_SERVICES'), 'Cloudant NoSQL DB') as client:
            # Context handles connect() and disconnect() for you.
            # Perform library operations within this context.  Such as:
            print client.all_dbs()
            # ...
    """
    cloudant_session = Cloudant.bluemix(
        vcap_services,
        instance_name=instance_name,
        service_name=service_name,
        **kwargs
    )
    cloudant_session.connect()
    yield cloudant_session
    cloudant_session.disconnect()

@contextlib.contextmanager
def couchdb(user, passwd, **kwargs):
    """
    Provides a context manager to create a CouchDB session and
    provide access to databases, docs etc.

    :param str user: Username used to connect to CouchDB.
    :param str passwd: Passcode used to connect to CouchDB.
    :param str url: URL for CouchDB server.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage.  Defaults to json.JSONEncoder.

    For example:

    .. code-block:: python

        # couchdb context manager
        from cloudant import couchdb

        with couchdb(USERNAME, PASSWORD, url=COUCHDB_URL) as client:
            # Context handles connect() and disconnect() for you.
            # Perform library operations within this context.  Such as:
            print client.all_dbs()
            # ...
    """
    couchdb_session = CouchDB(user, passwd, **kwargs)
    couchdb_session.connect()
    yield couchdb_session
    couchdb_session.disconnect()

@contextlib.contextmanager
def couchdb_admin_party(**kwargs):
    """
    Provides a context manager to create a CouchDB session in Admin Party mode
    and provide access to databases, docs etc.

    :param str url: URL for CouchDB server.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage.  Defaults to json.JSONEncoder.

    For example:

    .. code-block:: python

        # couchdb_admin_party context manager
        from cloudant import couchdb_admin_party

        with couchdb_admin_party(url=COUCHDB_URL) as client:
            # Context handles connect() and disconnect() for you.
            # Perform library operations within this context.  Such as:
            print client.all_dbs()
            # ...
    """
    couchdb_session = CouchDB(None, None, True, **kwargs)
    couchdb_session.connect()
    yield couchdb_session
    couchdb_session.disconnect()


================================================
FILE: src/cloudant/_client_session.py
================================================
#!/usr/bin/env python
# Copyright (c) 2015, 2019 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Module containing client session classes.
"""
import base64
import json
import os

from requests import RequestException, Session

from ._2to3 import bytes_, unicode_, url_join
from ._common_util import response_to_json_dict
from .error import CloudantException


class ClientSession(Session):
    """
    This class extends Session and provides a default timeout.
    """

    def __init__(self, username=None, password=None, session_url=None, **kwargs):
        super(ClientSession, self).__init__()

        self._username = username
        self._password = password
        self._session_url = session_url

        self._auto_renew = kwargs.get('auto_renew', False)
        self._timeout = kwargs.get('timeout', None)

    def base64_user_pass(self):
        """
        Composes a basic http auth string, suitable for use with the
        _replicator database, and other places that need it.

        :returns: Basic http authentication string
        """
        if self._username is None or self._password is None:
            return None

        hash_ = base64.urlsafe_b64encode(bytes_("{username}:{password}".format(
            username=self._username,
            password=self._password
        )))
        return "Basic {0}".format(unicode_(hash_))

    # pylint: disable=arguments-differ
    def request(self, method, url, **kwargs):
        """
        Overrides ``requests.Session.request`` to set the timeout.
        """
        resp = super(ClientSession, self).request(
            method, url, timeout=self._timeout, **kwargs)

        return resp

    def info(self):
        """
        Get session information.
        """
        if self._session_url is None:
            return None

        resp = self.get(self._session_url)
        resp.raise_for_status()
        return response_to_json_dict(resp)

    def set_credentials(self, username, password):
        """
        Set a new username and password.

        :param str username: New username.
        :param str password: New password.
        """
        if username is not None:
            self._username = username

        if password is not None:
            self._password = password

    def login(self):
        """
        No-op method - not implemented here.
        """
        # pylint: disable=unnecessary-pass
        pass

    def logout(self):
        """
        No-op method - not implemented here.
        """
        # pylint: disable=unnecessary-pass
        pass


class BasicSession(ClientSession):
    """
    This class extends ClientSession to provide basic access authentication.
    """

    def __init__(self, username, password, server_url, **kwargs):
        super(BasicSession, self).__init__(
            username=username,
            password=password,
            session_url=url_join(server_url, '_session'),
            **kwargs)

    def request(self, method, url, **kwargs):
        """
        Overrides ``requests.Session.request`` to provide basic access
        authentication.
        """
        auth = None
        if self._username is not None and self._password is not None:
            auth = (self._username, self._password)

        return super(BasicSession, self).request(
            method, url, auth=auth, **kwargs)


class CookieSession(ClientSession):
    """
    This class extends ClientSession and provides cookie authentication.
    """

    def __init__(self, username, password, server_url, **kwargs):
        super(CookieSession, self).__init__(
            username=username,
            password=password,
            session_url=url_join(server_url, '_session'),
            **kwargs)

    def login(self):
        """
        Perform cookie based user login.
        """
        resp = super(CookieSession, self).request(
            'POST',
            self._session_url,
            data={'name': self._username, 'password': self._password},
        )
        resp.raise_for_status()

    def logout(self):
        """
        Logout cookie based user.
        """
        resp = super(CookieSession, self).request('DELETE', self._session_url)
        resp.raise_for_status()

    def request(self, method, url, **kwargs):
        """
        Overrides ``requests.Session.request`` to renew the cookie and then
        retry the original request (if required).
        """
        resp = super(CookieSession, self).request(method, url, **kwargs)

        if not self._auto_renew:
            return resp

        is_expired = any((
            resp.status_code == 403 and
            response_to_json_dict(resp).get('error') == 'credentials_expired',
            resp.status_code == 401
        ))

        if is_expired:
            self.login()
            resp = super(CookieSession, self).request(method, url, **kwargs)

        return resp


class IAMSession(ClientSession):
    """
    This class extends ClientSession and provides IAM authentication.
    """

    def __init__(self, api_key, server_url, client_id=None, client_secret=None,
                 **kwargs):
        super(IAMSession, self).__init__(
            session_url=url_join(server_url, '_iam_session'),
            **kwargs)

        self._api_key = api_key
        self._token_url = os.environ.get(
            'IAM_TOKEN_URL', 'https://iam.cloud.ibm.com/identity/token')
        self._token_auth = None
        if client_id and client_secret:
            self._token_auth = (client_id, client_secret)

    @property
    def get_api_key(self):
        """
        Get IAM API key.

        :return: IAM API key.
        """
        return self._api_key

    def login(self):
        """
        Perform IAM cookie based user login.
        """
        access_token = self._get_access_token()
        try:
            super(IAMSession, self).request(
                'POST',
                self._session_url,
                headers={'Content-Type': 'application/json'},
                data=json.dumps({'access_token': access_token})
            ).raise_for_status()

        except RequestException:
            raise CloudantException(
                'Failed to exchange IAM token with Cloudant')

    def logout(self):
        """
        Logout IAM cookie based user.
        """
        self.cookies.clear()

    def request(self, method, url, **kwargs):
        """
        Overrides ``requests.Session.request`` to renew the IAM cookie
        and then retry the original request (if required).
        """
        # The CookieJar API prevents callers from getting an individual Cookie
        # object by name.
        # We are forced to use the only exposed method of discarding expired
        # cookies from the CookieJar. Internally this involves iterating over
        # the entire CookieJar and calling `.is_expired()` on each Cookie
        # object.
        self.cookies.clear_expired_cookies()

        if self._auto_renew and 'IAMSession' not in self.cookies.keys():
            self.login()

        resp = super(IAMSession, self).request(method, url, **kwargs)

        if not self._auto_renew:
            return resp

        if resp.status_code == 401:
            self.login()
            resp = super(IAMSession, self).request(method, url, **kwargs)

        return resp

    # pylint: disable=arguments-differ, unused-argument
    def set_credentials(self, username, api_key):
        """
        Set a new IAM API key.

        :param str username: Username parameter is unused.
        :param str api_key: New IAM API key.
        """
        if api_key is not None:
            self._api_key = api_key

    def _get_access_token(self):
        """
        Get IAM access token using API key.
        """
        err = 'Failed to contact IAM token service'
        try:
            resp = super(IAMSession, self).request(
                'POST',
                self._token_url,
                auth=self._token_auth,
                headers={'Accepts': 'application/json'},
                data={
                    'grant_type': 'urn:ibm:params:oauth:grant-type:apikey',
                    'response_type': 'cloud_iam',
                    'apikey': self._api_key
                }
            )
            err = response_to_json_dict(resp).get('errorMessage', err)
            resp.raise_for_status()

            return response_to_json_dict(resp)['access_token']

        except KeyError:
            raise CloudantException('Invalid response from IAM token service')

        except RequestException:
            raise CloudantException(err)


================================================
FILE: src/cloudant/_common_util.py
================================================
#!/usr/bin/env python
# Copyright © 2015, 2021 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Module containing miscellaneous classes, functions, and constants used
throughout the library.
"""

import sys
import platform
import json

from ._2to3 import LONGTYPE, STRTYPE, NONETYPE, UNITYPE, iteritems_
from .error import CloudantArgumentError, CloudantException, CloudantClientException

try:
    from collections.abc import Sequence
except ImportError:
    from collections import Sequence

# Library Constants

DESIGN_PREFIX = '_design/'
LOCAL_PREFIX = '_local/'
USER_AGENT = '/'.join([
    'python-cloudant',
    sys.modules['cloudant'].__version__,
    'Python',
    '{0}.{1}.{2}'.format(
        sys.version_info[0], sys.version_info[1], sys.version_info[2]),
    platform.system(),
    platform.machine()
])

QUERY_LANGUAGE = 'query'

# Index Types

JSON_INDEX_TYPE = 'json'
TEXT_INDEX_TYPE = 'text'
SPECIAL_INDEX_TYPE = 'special'

# Argument Types

ANY_ARG = object()
ANY_TYPE = object()

RESULT_ARG_TYPES = {
    'descending': (bool,),
    'endkey': (int, LONGTYPE, STRTYPE, Sequence, bool,),
    'endkey_docid': (STRTYPE,),
    'group': (bool,),
    'group_level': (int, LONGTYPE, NONETYPE,),
    'include_docs': (bool,),
    'inclusive_end': (bool,),
    'key': (int, LONGTYPE, STRTYPE, Sequence, bool,),
    'keys': (list,),
    'limit': (int, LONGTYPE, NONETYPE,),
    'reduce': (bool,),
    'skip': (int, LONGTYPE, NONETYPE,),
    'stable': (bool,),
    'stale': (STRTYPE,),
    'startkey': (int, LONGTYPE, STRTYPE, Sequence, bool,),
    'startkey_docid': (STRTYPE,),
    'update': (STRTYPE,),
}

# pylint: disable=unnecessary-lambda
TYPE_CONVERTERS = {
    STRTYPE: lambda x: json.dumps(x),
    str: lambda x: json.dumps(x),
    UNITYPE: lambda x: json.dumps(x),
    Sequence: lambda x: json.dumps(list(x)),
    list: lambda x: json.dumps(x),
    tuple: lambda x: json.dumps(list(x)),
    int: lambda x: x,
    LONGTYPE: lambda x: x,
    bool: lambda x: 'true' if x else 'false',
    NONETYPE: lambda x: x
}

_COUCH_DB_UPDATES_ARG_TYPES = {
    'feed': (STRTYPE,),
    'heartbeat': (bool,),
    'timeout': (int, LONGTYPE, NONETYPE,),
}

_DB_UPDATES_ARG_TYPES = {
    'descending': (bool,),
    'limit': (int, LONGTYPE, NONETYPE,),
    'since': (int, LONGTYPE, STRTYPE,),
}
_DB_UPDATES_ARG_TYPES.update(_COUCH_DB_UPDATES_ARG_TYPES)
_DB_UPDATES_ARG_TYPES['heartbeat'] = (int, LONGTYPE, NONETYPE,)

_CHANGES_ARG_TYPES = {
    'conflicts': (bool,),
    'doc_ids': (list,),
    'filter': (STRTYPE,),
    'include_docs': (bool,),
    'style': (STRTYPE,),
    ANY_ARG: ANY_TYPE  # pass arbitrary query parameters to a custom filter
}
_CHANGES_ARG_TYPES.update(_DB_UPDATES_ARG_TYPES)

QUERY_ARG_TYPES = {
    'selector': dict,
    'limit': (int, LONGTYPE, NONETYPE),
    'skip': (int, LONGTYPE, NONETYPE),
    'sort': list,
    'fields': list,
    'r': (int, LONGTYPE, NONETYPE),
    'bookmark': STRTYPE,
    'use_index': STRTYPE
}

TEXT_INDEX_ARGS = {'fields': list, 'default_field': dict, 'selector': dict}

SEARCH_INDEX_ARGS = {
    'bookmark': STRTYPE,
    'counts': list,
    'drilldown': list,
    'group_field': STRTYPE,
    'group_limit': (int, NONETYPE),
    'group_sort': (STRTYPE, list),
    'include_docs': bool,
    'limit': (int, NONETYPE),
    'query': (STRTYPE, int, LONGTYPE),
    'q': (STRTYPE, int, LONGTYPE),
    'ranges': dict,
    'sort': (STRTYPE, list),
    'stale': STRTYPE,
    'highlight_fields': list,
    'highlight_pre_tag': STRTYPE,
    'highlight_post_tag': STRTYPE,
    'highlight_number': (int, LONGTYPE, NONETYPE),
    'highlight_size': (int, LONGTYPE, NONETYPE),
    'include_fields': list,
    'partition': STRTYPE
}

# Functions

def feed_arg_types(feed_type):
    """
    Return the appropriate argument type dictionary based on the type of feed.
    """
    if feed_type == 'Cloudant':
        return _DB_UPDATES_ARG_TYPES
    if feed_type == 'CouchDB':
        return _COUCH_DB_UPDATES_ARG_TYPES
    return _CHANGES_ARG_TYPES

def python_to_couch(options, encoder=None):
    """
    Translates query options from python style options into CouchDB/Cloudant
    query options.  For example ``{'include_docs': True}`` will
    translate to ``{'include_docs': 'true'}``.  Primarily meant for use by
    code that formulates a query to retrieve results data from the
    remote database, such as the database API convenience method
    :func:`~cloudant.database.CouchDatabase.all_docs` or the View
    :func:`~cloudant.view.View.__call__` callable, both used to retrieve data.

    :param dict options: Python style parameters to be translated.
    :param encoder: Custom encoder, defaults to None

    :returns: Dictionary of translated CouchDB/Cloudant query parameters
    """
    translation = dict()
    for key, val in iteritems_(options):
        py_to_couch_validate(key, val)
        translation.update(_py_to_couch_translate(key, val, encoder))
    return translation

def py_to_couch_validate(key, val):
    """
    Validates the individual parameter key and value.
    """
    if key not in RESULT_ARG_TYPES:
        raise CloudantArgumentError(116, key)
    # pylint: disable=unidiomatic-typecheck
    # Validate argument values and ensure that a boolean is not passed in
    # if an integer is expected
    if (not isinstance(val, RESULT_ARG_TYPES[key]) or
            (type(val) is bool and bool not in RESULT_ARG_TYPES[key] and
             int in RESULT_ARG_TYPES[key])):
        raise CloudantArgumentError(117, key, RESULT_ARG_TYPES[key])
    if key == 'keys':
        for key_list_val in val:
            if (not isinstance(key_list_val, RESULT_ARG_TYPES['key']) or
                    isinstance(key_list_val, bool)):
                raise CloudantArgumentError(134, RESULT_ARG_TYPES['key'])
    if key == 'stale':
        if val not in ('ok', 'update_after'):
            raise CloudantArgumentError(135, val)

def _py_to_couch_translate(key, val, encoder=None):
    """
    Performs the conversion of the Python parameter value to its CouchDB
    equivalent.
    """
    try:
        if key in ['keys', 'endkey_docid', 'startkey_docid', 'stale', 'update']:
            return {key: val}
        if key in ['endkey', 'key', 'startkey']:
            return {key: json.dumps(val, cls=encoder)}
        if val is None:
            return {key: None}
        arg_converter = TYPE_CONVERTERS.get(type(val))
        return {key: arg_converter(val)}
    except Exception as ex:
        raise CloudantArgumentError(136, key, ex)

def type_or_none(typerefs, value):
    """
    Provides a helper function to check that a value is of the types passed or
    None.
    """
    return isinstance(value, typerefs) or value is None

def codify(code_or_str):
    """
    Provides a helper to rationalize code content.
    """
    if code_or_str is None:
        return None
    if not isinstance(code_or_str, _Code):
        return _Code(code_or_str)
    return code_or_str

def get_docs(r_session, url, encoder=None, headers=None, **params):
    """
    Provides a helper for functions that require GET or POST requests
    with a JSON, text, or raw response containing documents.

    :param r_session: Authentication session from the client
    :param str url: URL containing the endpoint
    :param JSONEncoder encoder: Custom encoder from the client
    :param dict headers: Optional HTTP Headers to send with the request

    :returns: Raw response content from the specified endpoint
    """
    keys_list = params.pop('keys', None)
    keys = None
    if keys_list is not None:
        keys = json.dumps({'keys': keys_list}, cls=encoder)
    f_params = python_to_couch(params, encoder)
    resp = None
    if keys is not None:
        # If we're using POST we are sending JSON so add the header
        if headers is None:
            headers = {}
        headers['Content-Type'] = 'application/json'
        resp = r_session.post(url, headers=headers, params=f_params, data=keys)
    else:
        resp = r_session.get(url, headers=headers, params=f_params)
    resp.raise_for_status()
    return resp

#pylint: disable=unused-argument
def append_response_error_content(response, **kwargs):
    """
    Provides a helper to act as callback function for the response event hook
    and add a HTTP response error with reason message to ``response.reason``.
    The ``response`` and ``**kwargs`` are necessary for this function to
    properly operate as the callback.

    :param response: HTTP response object
    :param kwargs: HTTP request parameters
    """
    if response.status_code >= 400:
        try:
            resp_dict = response_to_json_dict(response)
            error = resp_dict.get('error', '')
            reason = resp_dict.get('reason', '')
            # Append to the existing response's reason
            response.reason += ' {0} {1}'.format(error, reason)
        except ValueError:
            pass
    return response

def response_to_json_dict(response, **kwargs):
    """
    Standard place to convert responses to JSON.

    :param response: requests response object
    :param **kwargs: arguments accepted by json.loads

    :returns: dict of JSON response
    """
    if response.encoding is None:
        response.encoding = 'utf-8'
    return json.loads(response.text, **kwargs)

def assert_document_type_id(docid):
    """
    Validate the document ID.  Raises an error if the ID is an `_` prefixed name
    that isn't either `_design` or `_local`.
    :return:
    """
    invalid = False
    if docid.startswith('_'):
        if docid.startswith(DESIGN_PREFIX) and DESIGN_PREFIX != docid:
            invalid = False
        elif docid.startswith(LOCAL_PREFIX) and LOCAL_PREFIX != docid:
            invalid = False
        else:
            invalid = True
    if invalid:
        raise CloudantArgumentError(137, docid)

def assert_attachment_name(attname):
    """
    Validate the document attachment's name.  Raises an error if `_` prefixed name exists.
    :return:
    """
    if attname.startswith('_'):
        raise CloudantArgumentError(138, attname)
# Classes


class _Code(str):
    """
    Wraps a ``str`` object as a _Code object providing the means to handle
    Javascript blob content.  Used internally by the View object when
    codifying map and reduce Javascript content.
    """
    def __new__(cls, code):
        if type(code).__name__ == 'unicode':
            return str.__new__(cls, code.encode('utf8'))
        return str.__new__(cls, code)


class CloudFoundryService(object):
    """ Manages Cloud Foundry service configuration. """

    def __init__(self, vcap_services, instance_name=None, service_name=None):
        try:
            services = vcap_services
            if not isinstance(vcap_services, dict):
                services = json.loads(vcap_services)

            cloudant_services = services.get(service_name, [])

            # use first service if no name given and only one service present
            use_first = instance_name is None and len(cloudant_services) == 1
            for service in cloudant_services:
                if use_first or service.get('name') == instance_name:
                    credentials = service['credentials']
                    self._host = credentials['host']
                    self._name = service.get('name')
                    self._port = credentials.get('port', 443)
                    self._username = credentials['username']
                    if 'apikey' in credentials:
                        self._iam_api_key = credentials['apikey']
                    elif 'username' in credentials and 'password' in credentials:
                        self._password = credentials['password']
                    else:
                        raise CloudantClientException(103)
                    break
            else:
                raise CloudantException('Missing service in VCAP_SERVICES')

        except KeyError as ex:
            raise CloudantException(
                "Invalid service: '{0}' missing".format(ex.args[0])
            )

        except TypeError:
            raise CloudantException(
                'Failed to decode VCAP_SERVICES service credentials'
            )

        except ValueError:
            raise CloudantException('Failed to decode VCAP_SERVICES JSON')

    @property
    def host(self):
        """ Return service host. """
        return self._host

    @property
    def name(self):
        """ Return service name. """
        return self._name

    @property
    def password(self):
        """ Return service password. """
        return self._password

    @property
    def port(self):
        """ Return service port. """
        return str(self._port)

    @property
    def url(self):
        """ Return service url. """
        return 'https://{0}:{1}'.format(self._host, self._port)

    @property
    def username(self):
        """ Return service username. """
        return self._username

    @property
    def iam_api_key(self):
        """ Return service IAM API key. """
        return self._iam_api_key


================================================
FILE: src/cloudant/_messages.py
================================================
#!/usr/bin/env python
# Copyright © 2016, 2021 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Module that contains exception messages for the Cloudant Python client
library.
"""
ARGUMENT_ERROR = {
    100: 'A general Cloudant argument error was raised.',
    # Client
    101: 'Invalid year and/or month supplied.  Found: year - {0}, month - {1}',
    # Database
    102: 'Invalid role(s) provided: {0}.  Valid roles are: {1}',
    103: 'Invalid index type: {0}.  Index type must be '
         'either \"json\" or \"text\".',
    104: 'A single query/q parameter is required.  Found: {0}',
    105: 'Invalid argument: {0}',
    106: 'Argument {0} is not an instance of expected type: {1}',
    # Design document
    107: 'View {0} already exists in this design doc.',
    108: 'An index with name {0} already exists in this design doc.',
    109: 'A list with name {0} already exists in this design doc.',
    110: 'A show function with name {0} already exists in this design doc.',
    111: 'View {0} does not exist in this design doc.',
    112: 'An index with name {0} does not exist in this design doc.',
    113: 'A list with name {0} does not exist in this design doc.',
    114: 'A show function with name {0} does not exist in this design doc.',
    # Feed
    115: 'Error converting argument {0}: {1}',
    116: 'Invalid argument {0}',
    117: 'Argument {0} not instance of expected type: {1}',
    118: 'Argument {0} must be > 0.  Found: {1}',
    119: 'Invalid value ({0}) for feed option.  Must be one of {1}',
    120: 'Invalid value ({0}) for style option.  Must be main_only, '
         'or all_docs.',
    121: 'Invalid infinite feed option: {0}.  Must be set to continuous.',
    # Index
    122: 'The design document id: {0} is not a string.',
    123: 'The index name: {0} is not a string.',
    124: '{0} provided as argument(s).  A JSON index requires that '
         'only a \'fields\' argument is provided.',
    125: 'Deleting an index requires a design document id be provided.',
    126: 'Deleting an index requires an index name be provided.',
    127: 'Invalid argument: {0}',
    128: 'Argument {0} is not an instance of expected type: {1}',
    # Query
    129: 'Invalid argument: {0}',
    130: 'Argument {0} is not an instance of expected type: {1}',
    131: 'No selector in the query or the selector was empty.  '
         'Add a selector to define the query and retry.',
    # View
    132: 'The map property must be a dictionary.',
    133: 'The reduce property must be a string.',
    # Common_util
    134: 'Key list element not of expected type: {0}',
    135: 'Invalid value for stale option {0} must be ok or update_after.',
    136: 'Error converting argument {0}: {1}',
    137: 'Invalid document ID: {0}',
    138: 'Invalid attachment name: {0}'
}

CLIENT = {
    100: 'A general Cloudant client exception was raised.',
    101: 'Value must be set to a Database object. Found type: {0}',
    102: 'You must provide a url or an account.',
    103: 'Invalid service: IAM API key or username/password credentials are required.',
    404: 'Database {0} does not exist. Verify that the client is valid and try again.',
    412: 'Database {0} already exists.'
}

DATABASE = {
    100: 'A general Cloudant database exception was raised.',
    101: 'Unexpected index type. Found: {0}',
    400: 'Invalid database name during creation. Found: {0}',
    401: 'Unauthorized to create database {0}',
    409: 'Document with id {0} already exists.',
    412: 'Database {0} already exists.'
}

DESIGN_DOCUMENT = {
    100: 'A general Cloudant design document exception was raised.',
    101: 'Cannot add a MapReduce view to a design document for query indexes.',
    102: 'Cannot update a query index view using this method.',
    103: 'Cannot delete a query index view using this method.',
    104: 'View {0} must be of type View.',
    105: 'View {0} must be of type QueryIndexView.',
    106: 'Function for search index {0} must be of type string.',
    107: 'Definition for query text index {0} must be of type dict.'
}

DOCUMENT = {
    100: 'A general Cloudant document exception was raised.',
    101: 'A document id is required to fetch document contents. '
         'Add an _id key and value to the document and re-try.',
    102: 'The field {0} is not a list.',
    103: 'Attempting to delete a doc with no _rev. Try running .fetch and re-try.'
}

FEED = {
    100: 'A general Cloudant feed exception was raised.',
    101: 'Infinite _db_updates feed not supported for CouchDB.'
}

INDEX = {
    100: 'A general Cloudant index exception was raised.',
    101: 'Creating the \"special\" index is not allowed.',
    102: 'Deleting the \"special\" index is not allowed.'
}

REPLICATOR = {
    100: 'A general Cloudant replicator exception was raised.',
    101: 'You must specify either a source_db Database object or a manually composed'
         ' \'source\' string/dict.',
    102: 'You must specify either a target_db Database object or a manually composed'
         ' \'target\' string/dict.',
    404: 'Replication with id {0} not found.'
}

RESULT = {
    100: 'A general result exception was raised.',
    101: 'Failed to interpret the argument {0} as a valid key value or as a valid slice.',
    102: 'Cannot use {0} when performing key access or key slicing. Found {1}',
    103: 'Cannot use {0} for iteration. Found {1}',
    104: 'Invalid page_size: {0}'
}

VIEW = {
    100: 'A general view exception was raised.',
    101: 'A QueryIndexView is not callable.  If you wish to execute a query '
         'use the database \'get_query_result\' convenience method.',
    102: 'Cannot create a custom result context manager using a '
         'QueryIndexView.  If you wish to execute a query use the '
         'database \'get_query_result\' convenience method instead.'
}


================================================
FILE: src/cloudant/adapters.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright © 2016 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Module that contains default transport adapters for use with requests.
"""
from requests.adapters import HTTPAdapter

from requests.packages import urllib3

class Replay429Adapter(HTTPAdapter):
    """
    A requests TransportAdapter that extends the default HTTPAdapter with configuration
    to replay requests that receive a 429 Too Many Requests response from the server.
    The duration of the sleep between requests will be doubled for each 429 response
    received.

    Parameters can be passed in to control behavior:

    :param int retries: the number of times the request can be replayed before failing.
    :param float initialBackoff: time in seconds for the first backoff.
    """
    def __init__(self, retries=3, initialBackoff=0.25):
        super(Replay429Adapter, self).__init__(max_retries=urllib3.util.Retry(
            # Configure the number of retries for status codes
            total=retries,
            # No retries for connect|read errors
            connect=0,
            read=0,
            # Allow retries for all the CouchDB HTTP method types
            method_whitelist=frozenset(['GET', 'HEAD', 'PUT', 'POST',
                                        'DELETE', 'COPY']),
            # Only retry for a 429 too many requests status code
            status_forcelist=[429],
            # Configure the start value of the doubling backoff
            backoff_factor=initialBackoff))


================================================
FILE: src/cloudant/client.py
================================================
#!/usr/bin/env python
# Copyright (c) 2015, 2021 IBM Corp. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Top level API module that maps to a Cloudant or CouchDB client connection
instance.
"""
import json
from ._2to3 import url_parse

from ._client_session import (
    BasicSession,
    ClientSession,
    CookieSession,
    IAMSession
)
from .database import CloudantDatabase, CouchDatabase
from .feed import Feed, InfiniteFeed
from .error import (
    CloudantArgumentError,
    CloudantClientException,
    CloudantDatabaseException, CloudantException)
from ._common_util import (
    USER_AGENT,
    append_response_error_content,
    CloudFoundryService,
    response_to_json_dict,
    )


class CouchDB(dict):
    """
    Encapsulates a CouchDB client, handling top level user API calls having to
    do with session and database management.

    Maintains a requests.Session for working with the instance specified in the
    constructor.

    Parameters can be passed in to control behavior:

    :param str user: Username used to connect to CouchDB.
    :param str auth_token: Authentication token used to connect to CouchDB.
    :param bool admin_party: Setting to allow the use of Admin Party mode in
        CouchDB.  Defaults to ``False``.
    :param str url: URL for CouchDB server.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage.  Defaults to json.JSONEncoder.
    :param requests.HTTPAdapter adapter: Optional adapter to use for
        configuring requests.
    :param bool connect: Keyword argument, if set to True performs the call to
        connect as part of client construction.  Default is False.
    :param bool auto_renew: Keyword argument, if set to True performs
        automatic renewal of expired session authentication settings.
        Default is False.
    :param float timeout: Timeout in seconds (use float for milliseconds, for
        example 0.1 for 100 ms) for connecting to and reading bytes from the
        server.  If a single value is provided it will be applied to both the
        connect and read timeouts.  To specify different values for each timeout
        use a tuple.  For example, a 10 second connect timeout and a 1 minute
        read timeout would be (10, 60).  This follows the same behaviour as the
        `Requests library timeout argument
        <http://docs.python-requests.org/en/master/user/quickstart/#timeouts>`_.
        but will apply to every request made using this client.
    :param bool use_basic_auth: Keyword argument, if set to True performs basic
        access authentication with server. Default is False.
    :param bool use_iam: Keyword argument, if set to True performs
        IAM authentication with server. Default is False.
        Use :func:`~cloudant.client.CouchDB.iam` to construct an IAM
        authenticated client.
    :param string iam_client_id: Keyword argument, client ID to use when
        authenticating with the IAM token server. Default is ``None``.
    :param string iam_client_secret: Keyword argument, client secret to use when
        authenticating with the IAM token server. Default is ``None``.
    """
    _DATABASE_CLASS = CouchDatabase

    def __init__(self, user, auth_token, admin_party=False, **kwargs):
        super(CouchDB, self).__init__()
        self._user = user
        self._auth_token = auth_token
        self.server_url = kwargs.get('url')
        self._client_user_header = None
        self.admin_party = admin_party
        self.encoder = kwargs.get('encoder') or json.JSONEncoder
        self.adapter = kwargs.get('adapter')
        self._timeout = kwargs.get('timeout', None)
        self.r_session = None
        self._auto_renew = kwargs.get('auto_renew', False)
        self._use_basic_auth = kwargs.get('use_basic_auth', False)
        self._use_iam = kwargs.get('use_iam', False)
        self._iam_client_id = kwargs.get('iam_client_id', None)
        self._iam_client_secret = kwargs.get('iam_client_secret', None)
        # If user/pass exist in URL, remove and set variables
        if not self._use_basic_auth and self.server_url:
            parsed_url = url_parse(kwargs.get('url'))
            # Note: To prevent conflicts with field names, the method
            # and attribute names of `url_parse` start with an underscore
            if parsed_url.port is None:
                self.server_url = parsed_url._replace(
                    netloc="{}".format(parsed_url.hostname)).geturl()
            else:
                self.server_url = parsed_url._replace(
                    netloc="{}:{}".format(parsed_url.hostname, parsed_url.port)).geturl()
            if (not user and not auth_token) and (parsed_url.username and parsed_url.password):
                self._user = parsed_url.username
                self._auth_token = parsed_url.password
        self._features = None

        connect_to_couch = kwargs.get('connect', False)
        if connect_to_couch and self._DATABASE_CLASS == CouchDatabase:
            self.connect()

    @property
    def is_iam_authenticated(self):
        """
        Show if a client has authenticated using an IAM API key.

        :return: True if client is IAM authenticated. False otherwise.
        """
        return self._use_iam

    def features(self):
        """
        lazy fetch and cache features
        """
        if self._features is None:
            metadata = self.metadata()
            if "features" in metadata:
                self._features = metadata["features"]
            else:
                self._features = []
        return self._features

    def connect(self):
        """
        Starts up an authentication session for the client using cookie
        authentication if necessary.
        """
        if self.r_session:
            self.session_logout()

        if self.admin_party:
            self._use_iam = False
            self.r_session = ClientSession(
                timeout=self._timeout
            )
        elif self._use_basic_auth:
            self._use_iam = False
            self.r_session = BasicSession(
                self._user,
                self._auth_token,
                self.server_url,
                timeout=self._timeout
            )
        elif self._use_iam:
            self.r_session = IAMSession(
                self._auth_token,
                self.server_url,
                auto_renew=self._auto_renew,
                client_id=self._iam_client_id,
                client_secret=self._iam_client_secret,
                timeout=self._timeout
            )
        else:
            self.r_session = CookieSession(
                self._user,
                self._auth_token,
                self.server_url,
                auto_renew=self._auto_renew,
                timeout=self._timeout
            )

        # If a Transport Adapter was supplied add it to the session
        if self.adapter is not None:
            self.r_session.mount(self.server_url, self.adapter)
        if self._client_user_header is not None:
            self.r_session.headers.update(self._client_user_header)

        self.session_login()

        # Utilize an event hook to append to the response message
        # using :func:`~cloudant.common_util.append_response_error_content`
        self.r_session.hooks['response'].append(append_response_error_content)

    def disconnect(self):
        """
        Ends a client authentication session, performs a logout and a clean up.
        """
        if self.r_session:
            self.session_logout()

        self.r_session = None
        self.clear()

    def session(self):
        """
        Retrieves information about the current login session
        to verify data related to sign in.

        :returns: Dictionary of session info for the current session.
        """
        return self.r_session.info()

    def session_cookie(self):
        """
        Retrieves the current session cookie.

        :returns: Session cookie for the current session
        """
        return self.r_session.cookies.get('AuthSession')

    def session_login(self, user=None, passwd=None):
        """
        Performs a session login by posting the auth information
        to the _session endpoint.

        :param str user: Username used to connect to server.
        :param str auth_token: Authentication token used to connect to server.
        """
        self.change_credentials(user=user, auth_token=passwd)

    def change_credentials(self, user=None, auth_token=None):
        """
        Change login credentials.

        :param str user: Username used to connect to server.
        :param str auth_token: Authentication token used to connect to server.
        """
        self.r_session.set_credentials(user, auth_token)
        self.r_session.login()

    def session_logout(self):
        """
        Performs a session logout and clears the current session by
        sending a delete request to the _session endpoint.
        """
        self.r_session.logout()

    def basic_auth_str(self):
        """
        Composes a basic http auth string, suitable for use with the
        _replicator database, and other places that need it.

        :returns: Basic http authentication string
        """
        return self.r_session.base64_user_pass()

    def all_dbs(self):
        """
        Retrieves a list of all database names for the current client.

        :returns: List of database names for the client
        """
        url = '/'.join((self.server_url, '_all_dbs'))
        resp = self.r_session.get(url)
        resp.raise_for_status()
        return response_to_json_dict(resp)

    def create_database(self, dbname, partitioned=False, **kwargs):
        """
        Creates a new database on the remote server with the name provided
        and adds the new database object to the client's locally cached
        dictionary before returning it to the caller.  The method will
        optionally throw a CloudantClientException if the database
        exists remotely.

        :param str dbname: Name used to create the database.
        :param bool throw_on_exists: Boolean flag dictating whether or
            not to throw a CloudantClientException when attempting to
            create a database that already exists.
        :param bool partitioned: Create as a partitioned database. Defaults to
            ``False``.

        :returns: The newly created database object
        """
        new_db = self._DATABASE_CLASS(self, dbname, partitioned=partitioned)
        try:
            new_db.create(kwargs.get('throw_on_exists', False))
        except CloudantDatabaseException as ex:
            if ex.status_code == 412:
                raise CloudantClientException(412, dbname)
            raise ex
        super(CouchDB, self).__setitem__(dbname, new_db)
        return new_db

    def delete_database(self, dbname):
        """
        Removes the named database remotely and locally. The method will throw
        a CloudantClientException if the database does not exist.

        :param str dbname: Name of the database to delete.
        """
        db = self._DATABASE_CLASS(self, dbname)
        if not db.exists():
            raise CloudantClientException(404, dbname)
        db.delete()
        if dbname in list(self.keys()):
            super(CouchDB, self).__delitem__(dbname)

    def db_updates(self, raw_data=False, **kwargs):
        """
        Returns the ``_db_updates`` feed iterator.  While iterating over the
        feed, if necessary, the iteration can be stopped by issuing a call to
        the ``stop()`` method on the returned iterator object.

        For example:

        .. code-block:: python

            # Iterate over a "longpoll" _db_updates feed
            db_updates = client.db_updates()
            for db_update in db_updates:
                if some_condition:
                    db_updates.stop()
                print(db_update)

            # Iterate over a "continuous" _db_updates feed with additional options
            db_updates = client.db_updates(feed='continuous', heartbeat=False)
            for db_update in db_updates:
                if some_condition:
                    db_updates.stop()
                print(db_update)

        :param bool raw_data: If set to True then the raw response data will be
            streamed otherwise if set to False then JSON formatted data will be
            streamed.  Default is False.
        :param str feed: Type of feed.  Valid values are ``continuous``, and
            ``longpoll``.  Default is ``longpoll``.
        :param bool heartbeat: Whether CouchDB will send a newline character
            on timeout. Default is True.
        :param int timeout: Number of seconds to wait for data before
            terminating the response.
        :param int chunk_size: The HTTP response stream chunk size.  Defaults to
            512.

        :returns: Feed object that can be iterated over as a ``_db_updates``
            feed.
        """
        return Feed(self, raw_data, **kwargs)

    def metadata(self):
        """
        Retrieves the remote server metadata dictionary.

        :returns: Dictionary containing server metadata details
        """
        resp = self.r_session.get(self.server_url)
        resp.raise_for_status()
        return response_to_json_dict(resp)

    def keys(self, remote=False):
        """
        Returns the database names for this client. Default is
        to return only the locally cached database names, specify
        ``remote=True`` to make a remote request to include all databases.

        :param bool remote: Dictates whether the list of locally cached
            database names are returned or a remote request is made to include
            an up to date list of databases from the server.  Defaults to False.

        :returns: List of database names
        """
        if not remote:
            return list(super(CouchDB, self).keys())
        return self.all_dbs()

    def __getitem__(self, key):
        """
        Overrides dictionary __getitem__ behavior to provide a database
        instance for the specified key.

        If the database instance does not exist locally, then a remote request
        is made and the database is subsequently added to the local cache and
        returned to the caller.

        If the database instance already exists locally then it is returned and
        a remote request is not performed.

        A KeyError will result if the database does not exist locally or on the
        server.

        :param str key: Database name used to retrieve the database object.

        :returns: Database object
        """
        if key in list(self.keys()):
            return super(CouchDB, self).__getitem__(key)
        db = self._DATABASE_CLASS(self, key)
        if db.exists():
            super(CouchDB, self).__setitem__(key, db)
        else:
            raise KeyError(key)
        return db

    def __delitem__(self, key, remote=False):
        """
        Overrides dictionary __delitem__ behavior to make deleting the
        database key a proxy for deleting the database.  If remote=True then
        it will delete the database on the remote server, otherwise only
        the local cached object will be removed.

        :param str key: Database name of the database to be deleted.
        :param bool remote: Dictates whether the locally cached
            database is deleted or a remote request is made to delete
            the database from the server.  Defaults to False.
        """
        super(CouchDB, self).__delitem__(key)
        if remote:
            self.delete_database(key)

    def get(self, key, default=None, remote=False):
        """
        Overrides dictionary get behavior to retrieve database objects with
        support for returning a default.  If remote=True then a remote
        request is made to retrieve the database from the remote server,
        otherwise the client's locally cached database object is returned.

        :param str key: Database name used to retrieve the database object.
        :param str default: Default database name.  Defaults to None.
        :param bool remote: Dictates whether the locally cached
            database is returned or a remote request is made to retrieve
            the database from the server.  Defaults to False.

        :returns: Database object
        """
        if not remote:
            return super(CouchDB, self).get(key, default)
        db = self._DATABASE_CLASS(self, key)
        if db.exists():
            super(CouchDB, self).__setitem__(key, db)
            return db

        return default

    def __setitem__(self, key, value, remote=False):
        """
        Override dictionary __setitem__ behavior to verify that only
        database instances are added as keys.  If remote=True then also create
        the database remotely if the database does not exist.

        Note:  The only way to override the default for the ``remote`` argument
        setting it to True is to call __setitem__ directly.  A much simpler
        approach is to use
        :func:`~cloudant.client.CouchDB.create_database` instead, if your
        intention is to create a database remotely.

        :param str key: Database name to be used as the key for the database in
            the locally cached dictionary.
        :param value: Database object to be used in the locally cached
            dictionary.
        :param bool remote: Dictates whether the method will attempt to
            create the database remotely or not.  Defaults to False.
        """
        if not isinstance(value, self._DATABASE_CLASS):
            raise CloudantClientException(101, type(value).__name__)
        if remote and not value.exists():
            value.create()
        super(CouchDB, self).__setitem__(key, value)

class Cloudant(CouchDB):
    """
    Encapsulates a Cloudant client, handling top level user API calls having to
    do with session and database management.

    Maintains a requests.Session for working with the
    instance specified in the constructor.

    Parameters can be passed in to control behavior:

    :param str cloudant_user: Username used to connect to Cloudant.
    :param str auth_token: Authentication token used to connect to Cloudant.
    :param str account: The Cloudant account name.  If the account parameter
        is present, it will be used to construct the Cloudant service URL.
    :param str url: If the account is not present and the url parameter is
        present then it will be used to set the Cloudant service URL.  The
        url must be a fully qualified http/https URL.
    :param str x_cloudant_user: Override the X-Cloudant-User setting used to
        authenticate. This is needed to authenticate on one's behalf,
        eg with an admin account.  This parameter must be accompanied
        by the url parameter.  If the url parameter is omitted then
        the x_cloudant_user parameter setting is ignored.
    :param str encoder: Optional json Encoder object used to encode
        documents for storage. Defaults to json.JSONEncoder.
    :param requests.HTTPAdapter adapter: Optional adapter to use for configuring requests.
    """
    _DATABASE_CLASS = CloudantDatabase

    def __init__(self, cloudant_user, auth_token, **kwargs):
        super(Cloudant, self).__init__(cloudant_user, auth_token, **kwargs)
        self._client_user_header = {'User-Agent': USER_AGENT}
        account = kwargs.get('account')
        if account is not None:
            self.server_url = 'https://{0}.cloudant.com'.format(account)
        if kwargs.get('x_cloudant_user') is not None:
            self._client_user_header['X-Cloudant-User'] = kwargs.get('x_cloudant_user')

        if self.server_url is None:
            raise CloudantClientException(102)

        if kwargs.get('connect', False):
            self.connect()

    def db_updates(self, raw_data=False, **kwargs):
        """
        Returns the ``_db_updates`` feed iterator.  The ``_db_updates`` feed can
        be iterated over and once complete can also provide the last sequence
        identifier of the feed.  If necessary, the iteration can be stopped by
        issuing a call to the ``stop()`` method on the returned iterator object.

        For example:

        .. code-block:: python

            # Iterate over a "normal" _db_updates feed
            db_updates = client.db_updates()
            for db_update in db_updates:
                print(db_update)
            print(db_updates.last_seq)

            # Iterate over a "continuous" _db_updates feed with additional options
            db_updates = client.db_updates(feed='continuous', since='now', descending=True)
            for db_update in db_updates:
                if some_condition:
                    db_updates.stop()
                print(db_update)

        :param bool raw_data: If set to True then the raw response data will be
            streamed otherwise if set to False then JSON formatted data will be
            streamed.  Default is False.
        :param bool descending: Whether results should be returned in
            descending order, i.e. the latest event first. By default, the
            oldest event is returned first.
        :param str feed: Type of feed.  Valid values are ``continuous``,
            ``longpoll``, and ``normal``.  Default is ``normal``.
        :param int heartbeat: Time in milliseconds after which an empty line is
            sent during ``longpoll`` or ``continuous`` if there have been no
            changes.  Must be a positive number.  Default is no heartbeat.
        :param int limit: Maximum number of rows to return.  Must be a positive
            number.  Default is no limit.
        :param since: Start the results from changes after the specified
            sequence identifier. In other words, using since excludes from the
            list all changes up to and including the specified sequence
            identifier. If since is 0 (the default), or omitted, the request
            returns all changes. If it is ``now``, only changes made after the
            time of the request will be emitted.
        :param int timeout: Number of milliseconds to wait for data before
            terminating the response. ``heartbeat`` supersedes ``timeout`` if
            both are supplied.
        :param int chunk_size: The HTTP response stream chunk size.  Defaults to
            512.

        :returns: Feed object that can be iterated over as a ``_db_updates``
            feed.
        """
        return Feed(self, raw_data, **kwargs)

    def infinite_db_updates(self, **kwargs):
        """
        Returns an infinite (perpetually refreshed) ``_db_updates`` feed
        iterator.  If necessary, the iteration can be stopped by issuing a call
        to the ``stop()`` method on the returned iterator object.

        For example:

        .. code-block:: python

            # Iterate over an infinite _db_updates feed
            db_updates = client.infinite_db_updates()
            for db_update in db_updates:
                if some_condition:
                    db_updates.stop()
                print(db_update)

        :param bool descending: Whether results should be returned in
            descending order, i.e. the latest event first. By default, the
            oldest event is returned first.
        :param int heartbeat: Time in milliseconds after which an empty line is
            sent if there have been no changes.  Must be a positive number.
            Default is no heartbeat.
        :param since: Start the results from changes after the specified
            sequence identifier. In other words, using since excludes from the
            list all changes up to and including the specified sequence
            identifier. If since is 0 (the default), or omitted, the request
            returns all changes. If it is ``now``, only changes made after the
            time of the request will be emitted.
        :param int timeout: Number of milliseconds to wait for data before
            terminating the response. ``heartbeat`` supersedes ``timeout`` if
            both are supplied.
        :param int chunk_size: The HTTP response stream chunk size.  Defaults to
            512.

        :returns: Feed object that can be iterated over as a ``_db_updates``
            feed.
        """
        return InfiniteFeed(self, **kwargs)

    def _usage_endpoint(self, endpoint, year=None, month=None):
        """
        Common helper for getting usage and billing reports with
        optional year and month URL elements.

        :param str endpoint: Cloudant usage endpoint.
        :param int year: Year to query against.  Optional parameter.
            Defaults to None.  If used, it must be accompanied by ``month``.
        :param int month: Month to query against that must be an integer
            between 1 and 12. Optional parameter. Defaults to None.
            If used, it must be accompanied by ``year``.
        """
        err = False
        if year is None and month is None:
            resp = self.r_session.get(endpoint)
        else:
            try:
                if int(year) > 0 and int(month) in range(1, 13):
                    resp = self.r_session.get(
                        '/'.join((endpoint, str(int(year)), str(int(month)))))
                else:
                    err = True
            except (ValueError, TypeError):
                err = True

        if err:
            raise CloudantArgumentError(101, year, month)

        resp.raise_for_status()
        return response_to_json_dict(resp)

    def bill(self, year=None, month=None):
        """
        Retrieves Cloudant billing data, optionally for a given year and month.

        :param int year: Year to query against, for example 2014.
            Optional parameter.  Defaults to None.  If used, it must be
            accompanied by ``month``.
        :param int month: Month to query against that must be an integer
            between 1 and 12.  Optional parameter.  Defaults to None.
            If used, it must be accompanied by ``year``.

        :returns: Billing data in JSON format
        """
        endpoint = '/'.join((self.server_url, '_api', 'v2', 'bill'))
        return self._usage_endpoint(endpoint, year, month)

    def volume_usage(self, year=None, month=None):
        """
        Retrieves Cloudant volume usage data, optionally for a given
        year and month.

        :param int year: Year to query against, for example 2014.
            Optional parameter.  Defaults to None.  If used, it must be
            accompanied by ``month``.
        :param int month: Month to query against that must be an integer
            between 1 and 12.  Optional parameter.  Defaults to None.
            If used, it must be accompanied by ``year``.

        :returns: Volume usage data in JSON format
        """
        endpoint = '/'.join((
            self.server_url, '_api', 'v2', 'usage', 'data_volume'))
        return self._usage_endpoint(endpoint, year, month)

    def requests_usage(self, year=None, month=None):
        """
        Retrieves Cloudant requests usage data, optionally for a given
        year and month.

        :param int year: Year to query against, for example 2014.
            Optional parameter.  Defaults to None.  If used, it must be
            accompanied by ``month``.
        :param int month: Month to query against that must be an integer
            between 1 and 12.  Optional parameter.  Defaults to None.
            If used, it must be accompanied by ``year``.

        :returns: Requests usage data in JSON format
        """
        endpoint = '/'.join((
            self.server_url, '_api', 'v2', 'usage', 'requests'))
        return self._usage_endpoint(endpoint, year, month)

    def shared_databases(self):
        """
        Retrieves a list containing the names of databases shared
        with this account.

        :returns: List of database names
        """
        endpoint = '/'.join((
            self.server_url, '_api', 'v2', 'user', 'shared_databases'))
        resp = self.r_session.get(endpoint)
        resp.raise_for_status()
        data = response_to_json_dict(resp)
        return data.get('shared_databases', [])

    def generate_api_key(self):
        """
        Creates and returns a new API Key/pass pair.

        :returns: API key/pass pair in JSON format
        """
        endpoint = '/'.join((self.server_url, '_api', 'v2', 'api_keys'))
        resp = self.r_session.post(endpoint)
        resp.raise_for_status()
        return response_to_json_dict(resp)

    def cors_configuration(self):
        """
        Retrieves the current CORS configuration.

        :returns: CORS data in JSON format
        """
        endpoint = '/'.join((
            self.server_url, '_api', 'v2', 'user', 'config', 'cors'))
        resp = self.r_session.get(endpoint)
        resp.raise_for_status()

        return response_to_json_dict(resp)

    def disable_cors(self):
        """
        Switches CORS off.

        :returns: CORS status in JSON format
        """
        return self.update_cors_configuration(
            enable_cors=False,
            allow_credentials=False,
            origins=[],
            overwrite_origins=True
        )

    def cors_origins(self):
        """
        Retrieves a list of CORS origins.

        :returns: List of CORS origins
        """
        cors = self.cors_configuration()

        return cors['origins']

    def update_cors_configuration(
            self,
            enable_cors=True,
            allow_credentials=True,
            origins=None,
            overwrite_origins=False):
        """
        Merges existing CORS configuration with updated values.

        :param bool enable_cors: Enables/disables CORS.  Defaults to True.
        :param bool allow_credentials: Allows authentication credentials.
            Defaults to True.
        :param list origins: List of allowed CORS origin(s).  Special cases are
            a list containing a single "*" which will allow any origin and
            an empty list which will not allow any origin.  Defaults to None.
        :param bool overwrite_origins: Dictates whether the origins list is
            overwritten of appended to.  Defaults to False.

        :returns: CORS configuration update status in JSON format
        """
        if origins is None:
            origins = []

        cors_config = {
            'enable_cors': enable_cors,
            'allow_credentials': allow_credentials,
            'origins': origins
        }

        if overwrite_origins:
            return self._write_cors_c
Download .txt
gitextract_yhao7vs7/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .travis.yml
├── CHANGES.md
├── CONTRIBUTING.md
├── DCO1.1.txt
├── Jenkinsfile
├── LICENSE
├── MANIFEST.in
├── MIGRATION.md
├── README.md
├── VERSION
├── docs/
│   ├── Makefile
│   ├── adapters.rst
│   ├── client.rst
│   ├── cloudant.rst
│   ├── compatibility.rst
│   ├── conf.py
│   ├── database.rst
│   ├── design_document.rst
│   ├── document.rst
│   ├── error.rst
│   ├── feed.rst
│   ├── getting_started.rst
│   ├── index.rst
│   ├── make.bat
│   ├── module_index.rst
│   ├── modules.rst
│   ├── query.rst
│   ├── replicator.rst
│   ├── result.rst
│   ├── security_document.rst
│   └── view.rst
├── pylintrc
├── requirements.txt
├── setup.py
├── src/
│   └── cloudant/
│       ├── _2to3.py
│       ├── __init__.py
│       ├── _client_session.py
│       ├── _common_util.py
│       ├── _messages.py
│       ├── adapters.py
│       ├── client.py
│       ├── database.py
│       ├── design_document.py
│       ├── document.py
│       ├── error.py
│       ├── feed.py
│       ├── index.py
│       ├── query.py
│       ├── replicator.py
│       ├── result.py
│       ├── scheduler.py
│       ├── security_document.py
│       └── view.py
├── test-requirements.txt
└── tests/
    ├── __init__.py
    ├── credentials.py
    ├── integration/
    │   ├── __init__.py
    │   ├── changes_test.py
    │   ├── document_test.py
    │   ├── end_to_end_example_test.py
    │   ├── iter_test.py
    │   └── replicator_test.py
    └── unit/
        ├── __init__.py
        ├── _test_util.py
        ├── adapter_tests.py
        ├── auth_renewal_tests.py
        ├── changes_tests.py
        ├── client_tests.py
        ├── cloud_foundry_tests.py
        ├── database_partition_tests.py
        ├── database_tests.py
        ├── db_updates_tests.py
        ├── design_document_tests.py
        ├── document_tests.py
        ├── document_validation_tests.py
        ├── fixtures/
        │   └── __init__.py
        ├── iam_auth_tests.py
        ├── index_tests.py
        ├── infinite_feed_tests.py
        ├── param_translation_tests.py
        ├── query_result_tests.py
        ├── query_tests.py
        ├── replicator_mock_tests.py
        ├── replicator_tests.py
        ├── result_tests.py
        ├── scheduler_tests.py
        ├── security_document_tests.py
        ├── unit_t_db_base.py
        ├── view_execution_tests.py
        └── view_tests.py
Download .txt
SYMBOL INDEX (1203 symbols across 50 files)

FILE: src/cloudant/_2to3.py
  function iteritems_ (line 46) | def iteritems_(adict):
  function next_ (line 55) | def next_(itr):
  function iteritems_ (line 71) | def iteritems_(adict):
  function next_ (line 80) | def next_(itr):
  function bytes_ (line 90) | def bytes_(astr):
  function unicode_ (line 100) | def unicode_(astr):

FILE: src/cloudant/__init__.py
  function cloudant (line 31) | def cloudant(user, passwd, **kwargs):
  function cloudant_iam (line 70) | def cloudant_iam(account_name, api_key, **kwargs):
  function cloudant_bluemix (line 99) | def cloudant_bluemix(vcap_services, instance_name=None, service_name=Non...
  function couchdb (line 169) | def couchdb(user, passwd, **kwargs):
  function couchdb_admin_party (line 199) | def couchdb_admin_party(**kwargs):

FILE: src/cloudant/_client_session.py
  class ClientSession (line 29) | class ClientSession(Session):
    method __init__ (line 34) | def __init__(self, username=None, password=None, session_url=None, **k...
    method base64_user_pass (line 44) | def base64_user_pass(self):
    method request (line 61) | def request(self, method, url, **kwargs):
    method info (line 70) | def info(self):
    method set_credentials (line 81) | def set_credentials(self, username, password):
    method login (line 94) | def login(self):
    method logout (line 101) | def logout(self):
  class BasicSession (line 109) | class BasicSession(ClientSession):
    method __init__ (line 114) | def __init__(self, username, password, server_url, **kwargs):
    method request (line 121) | def request(self, method, url, **kwargs):
  class CookieSession (line 134) | class CookieSession(ClientSession):
    method __init__ (line 139) | def __init__(self, username, password, server_url, **kwargs):
    method login (line 146) | def login(self):
    method logout (line 157) | def logout(self):
    method request (line 164) | def request(self, method, url, **kwargs):
  class IAMSession (line 187) | class IAMSession(ClientSession):
    method __init__ (line 192) | def __init__(self, api_key, server_url, client_id=None, client_secret=...
    method get_api_key (line 206) | def get_api_key(self):
    method login (line 214) | def login(self):
    method logout (line 231) | def logout(self):
    method request (line 237) | def request(self, method, url, **kwargs):
    method set_credentials (line 265) | def set_credentials(self, username, api_key):
    method _get_access_token (line 275) | def _get_access_token(self):

FILE: src/cloudant/_common_util.py
  function feed_arg_types (line 155) | def feed_arg_types(feed_type):
  function python_to_couch (line 165) | def python_to_couch(options, encoder=None):
  function py_to_couch_validate (line 186) | def py_to_couch_validate(key, val):
  function _py_to_couch_translate (line 208) | def _py_to_couch_translate(key, val, encoder=None):
  function type_or_none (line 225) | def type_or_none(typerefs, value):
  function codify (line 232) | def codify(code_or_str):
  function get_docs (line 242) | def get_docs(r_session, url, encoder=None, headers=None, **params):
  function append_response_error_content (line 272) | def append_response_error_content(response, **kwargs):
  function response_to_json_dict (line 293) | def response_to_json_dict(response, **kwargs):
  function assert_document_type_id (line 306) | def assert_document_type_id(docid):
  function assert_attachment_name (line 323) | def assert_attachment_name(attname):
  class _Code (line 333) | class _Code(str):
    method __new__ (line 339) | def __new__(cls, code):
  class CloudFoundryService (line 345) | class CloudFoundryService(object):
    method __init__ (line 348) | def __init__(self, vcap_services, instance_name=None, service_name=None):
    method host (line 389) | def host(self):
    method name (line 394) | def name(self):
    method password (line 399) | def password(self):
    method port (line 404) | def port(self):
    method url (line 409) | def url(self):
    method username (line 414) | def username(self):
    method iam_api_key (line 419) | def iam_api_key(self):

FILE: src/cloudant/adapters.py
  class Replay429Adapter (line 23) | class Replay429Adapter(HTTPAdapter):
    method __init__ (line 35) | def __init__(self, retries=3, initialBackoff=0.25):

FILE: src/cloudant/client.py
  class CouchDB (line 42) | class CouchDB(dict):
    method __init__ (line 88) | def __init__(self, user, auth_token, admin_party=False, **kwargs):
    method is_iam_authenticated (line 125) | def is_iam_authenticated(self):
    method features (line 133) | def features(self):
    method connect (line 145) | def connect(self):
    method disconnect (line 196) | def disconnect(self):
    method session (line 206) | def session(self):
    method session_cookie (line 215) | def session_cookie(self):
    method session_login (line 223) | def session_login(self, user=None, passwd=None):
    method change_credentials (line 233) | def change_credentials(self, user=None, auth_token=None):
    method session_logout (line 243) | def session_logout(self):
    method basic_auth_str (line 250) | def basic_auth_str(self):
    method all_dbs (line 259) | def all_dbs(self):
    method create_database (line 270) | def create_database(self, dbname, partitioned=False, **kwargs):
    method delete_database (line 297) | def delete_database(self, dbname):
    method db_updates (line 311) | def db_updates(self, raw_data=False, **kwargs):
    method metadata (line 352) | def metadata(self):
    method keys (line 362) | def keys(self, remote=False):
    method __getitem__ (line 378) | def __getitem__(self, key):
    method __delitem__ (line 406) | def __delitem__(self, key, remote=False):
    method get (line 422) | def get(self, key, default=None, remote=False):
    method __setitem__ (line 446) | def __setitem__(self, key, value, remote=False):
  class Cloudant (line 471) | class Cloudant(CouchDB):
    method __init__ (line 499) | def __init__(self, cloudant_user, auth_token, **kwargs):
    method db_updates (line 514) | def db_updates(self, raw_data=False, **kwargs):
    method infinite_db_updates (line 568) | def infinite_db_updates(self, **kwargs):
    method _usage_endpoint (line 608) | def _usage_endpoint(self, endpoint, year=None, month=None):
    method bill (line 639) | def bill(self, year=None, month=None):
    method volume_usage (line 655) | def volume_usage(self, year=None, month=None):
    method requests_usage (line 673) | def requests_usage(self, year=None, month=None):
    method shared_databases (line 691) | def shared_databases(self):
    method generate_api_key (line 705) | def generate_api_key(self):
    method cors_configuration (line 716) | def cors_configuration(self):
    method disable_cors (line 729) | def disable_cors(self):
    method cors_origins (line 742) | def cors_origins(self):
    method update_cors_configuration (line 752) | def update_cors_configuration(
    method _write_cors_configuration (line 803) | def _write_cors_configuration(self, config):
    method bluemix (line 825) | def bluemix(cls, vcap_services, instance_name=None, service_name=None,...
    method iam (line 866) | def iam(cls, account_name, api_key, **kwargs):

FILE: src/cloudant/database.py
  class CouchDatabase (line 42) | class CouchDatabase(dict):
    method __init__ (line 56) | def __init__(self, client, database_name, fetch_limit=100,
    method r_session (line 67) | def r_session(self):
    method admin_party (line 76) | def admin_party(self):
    method database_url (line 86) | def database_url(self):
    method creds (line 96) | def creds(self):
    method database_partition_url (line 112) | def database_partition_url(self, partition_key):
    method exists (line 124) | def exists(self):
    method metadata (line 136) | def metadata(self):
    method partition_metadata (line 146) | def partition_metadata(self, partition_key):
    method doc_count (line 158) | def doc_count(self):
    method create_document (line 166) | def create_document(self, data, throw_on_exists=False):
    method new_document (line 201) | def new_document(self):
    method design_documents (line 214) | def design_documents(self):
    method list_design_documents (line 228) | def list_design_documents(self):
    method get_design_document (line 242) | def get_design_document(self, ddoc_id):
    method get_security_document (line 262) | def get_security_document(self):
    method get_partitioned_view_result (line 275) | def get_partitioned_view_result(self, partition_key, ddoc_id, view_name,
    method get_view_result (line 302) | def get_view_result(self, ddoc_id, view_name, raw_result=False, **kwar...
    method _get_view_result (line 400) | def _get_view_result(view, raw_result, **kwargs):
    method create (line 409) | def create(self, throw_on_exists=False):
    method delete (line 434) | def delete(self):
    method all_docs (line 441) | def all_docs(self, **kwargs):
    method partitioned_all_docs (line 474) | def partitioned_all_docs(self, partition_key, **kwargs):
    method custom_result (line 498) | def custom_result(self, **options):
    method keys (line 536) | def keys(self, remote=False):
    method changes (line 555) | def changes(self, raw_data=False, **kwargs):
    method infinite_changes (line 622) | def infinite_changes(self, **kwargs):
    method __getitem__ (line 675) | def __getitem__(self, key):
    method get (line 709) | def get(self, key, remote=False):
    method __contains__ (line 727) | def __contains__(self, key):
    method __iter__ (line 753) | def __iter__(self, remote=True):
    method bulk_docs (line 807) | def bulk_docs(self, docs):
    method missing_revisions (line 830) | def missing_revisions(self, doc_id, *revisions):
    method revisions_diff (line 859) | def revisions_diff(self, doc_id, *revisions):
    method get_revision_limit (line 883) | def get_revision_limit(self):
    method set_revision_limit (line 901) | def set_revision_limit(self, limit):
    method view_cleanup (line 918) | def view_cleanup(self):
    method get_list_function_result (line 934) | def get_list_function_result(self, ddoc_id, list_name, view_name, **kw...
    method get_show_function_result (line 977) | def get_show_function_result(self, ddoc_id, show_name, doc_id):
    method update_handler_result (line 1014) | def update_handler_result(self, ddoc_id, handler_name, doc_id=None, da...
    method get_query_indexes (line 1066) | def get_query_indexes(self, raw_result=False):
    method create_query_index (line 1116) | def create_query_index(
    method delete_query_index (line 1169) | def delete_query_index(self, design_document_id, index_type, index_name):
    method get_partitioned_query_result (line 1188) | def get_partitioned_query_result(self, partition_key, selector, fields...
    method get_query_result (line 1218) | def get_query_result(self, selector, fields=None, raw_result=False,
    method _get_query_result (line 1293) | def _get_query_result(query, raw_result, **kwargs):
  class CloudantDatabase (line 1303) | class CloudantDatabase(CouchDatabase):
    method __init__ (line 1317) | def __init__(self, client, database_name, fetch_limit=100,
    method security_document (line 1326) | def security_document(self):
    method security_url (line 1337) | def security_url(self):
    method share_database (line 1347) | def share_database(self, username, roles=None):
    method unshare_database (line 1395) | def unshare_database(self, username):
    method shards (line 1420) | def shards(self):
    method get_partitioned_search_result (line 1432) | def get_partitioned_search_result(self, partition_key, ddoc_id, index_...
    method get_search_result (line 1462) | def get_search_result(self, ddoc_id, index_name, **query_params):
    method _get_search_result (line 1568) | def _get_search_result(self, query_url, **query_params):

FILE: src/cloudant/design_document.py
  class DesignDocument (line 25) | class DesignDocument(Document):
    method __init__ (line 47) | def __init__(self, database, document_id=None, partitioned=False):
    method validate_doc_update (line 64) | def validate_doc_update(self):
    method filters (line 90) | def filters(self):
    method updates (line 127) | def updates(self):
    method st_indexes (line 165) | def st_indexes(self):
    method lists (line 205) | def lists(self):
    method shows (line 215) | def shows(self):
    method rewrites (line 226) | def rewrites(self):
    method views (line 264) | def views(self):
    method indexes (line 274) | def indexes(self):
    method document_partition_url (line 284) | def document_partition_url(self, partition_key):
    method add_view (line 298) | def add_view(self, view_name, map_func, reduce_func=None, **kwargs):
    method add_search_index (line 318) | def add_search_index(self, index_name, search_func, analyzer=None):
    method add_list_function (line 336) | def add_list_function(self, list_name, list_func):
    method add_show_function (line 349) | def add_show_function(self, show_name, show_func):
    method update_view (line 362) | def update_view(self, view_name, map_func, reduce_func=None, **kwargs):
    method update_search_index (line 385) | def update_search_index(self, index_name, search_func, analyzer=None):
    method update_list_function (line 404) | def update_list_function(self, list_name, list_func):
    method update_show_function (line 417) | def update_show_function(self, show_name, show_func):
    method delete_view (line 430) | def delete_view(self, view_name):
    method delete_index (line 448) | def delete_index(self, index_name):
    method delete_list_function (line 461) | def delete_list_function(self, list_name):
    method delete_show_function (line 470) | def delete_show_function(self, show_name):
    method fetch (line 482) | def fetch(self):
    method save (line 515) | def save(self):
    method __setitem__ (line 556) | def __setitem__(self, key, value):
    method iterviews (line 569) | def iterviews(self):
    method iterindexes (line 586) | def iterindexes(self):
    method iterlists (line 604) | def iterlists(self):
    method itershows (line 615) | def itershows(self):
    method list_views (line 626) | def list_views(self):
    method list_indexes (line 635) | def list_indexes(self):
    method list_list_functions (line 644) | def list_list_functions(self):
    method list_show_functions (line 653) | def list_show_functions(self):
    method get_view (line 662) | def get_view(self, view_name):
    method get_index (line 673) | def get_index(self, index_name):
    method get_list_function (line 684) | def get_list_function(self, list_name):
    method get_show_function (line 695) | def get_show_function(self, show_name):
    method info (line 706) | def info(self):
    method search_info (line 717) | def search_info(self, search_index):
    method search_disk_size (line 729) | def search_disk_size(self, search_index):

FILE: src/cloudant/document.py
  class Document (line 27) | class Document(dict):
    method __init__ (line 60) | def __init__(self, database, document_id=None, **kwargs):
    method r_session (line 72) | def r_session(self):
    method document_url (line 81) | def document_url(self):
    method exists (line 115) | def exists(self):
    method json (line 133) | def json(self):
    method create (line 143) | def create(self):
    method fetch (line 166) | def fetch(self):
    method save (line 182) | def save(self):
    method list_field_append (line 209) | def list_field_append(doc, field, value):
    method list_field_remove (line 227) | def list_field_remove(doc, field, value):
    method field_set (line 241) | def field_set(doc, field, value):
    method _update_field (line 256) | def _update_field(self, action, field, value, max_tries, tries=0):
    method update_field (line 277) | def update_field(self, action, field, value, max_tries=10):
    method delete (line 314) | def delete(self):
    method __enter__ (line 336) | def __enter__(self):
    method __exit__ (line 356) | def __exit__(self, exc_type, exc_value, traceback):
    method get_attachment (line 364) | def get_attachment(
    method delete_attachment (line 423) | def delete_attachment(self, attachment, headers=None):
    method put_attachment (line 461) | def put_attachment(self, attachment, content_type, data, headers=None):

FILE: src/cloudant/error.py
  class CloudantException (line 31) | class CloudantException(Exception):
    method __init__ (line 42) | def __init__(self, msg, code=None):
  class CloudantArgumentError (line 47) | class CloudantArgumentError(CloudantException):
    method __init__ (line 59) | def __init__(self, code=100, *args):
  class ResultException (line 67) | class ResultException(CloudantException):
    method __init__ (line 77) | def __init__(self, code=100, *args):
  class CloudantClientException (line 86) | class CloudantClientException(CloudantException):
    method __init__ (line 93) | def __init__(self, code=100, *args):
  class CloudantDatabaseException (line 101) | class CloudantDatabaseException(CloudantException):
    method __init__ (line 108) | def __init__(self, code=100, *args):
  class CloudantDesignDocumentException (line 122) | class CloudantDesignDocumentException(CloudantException):
    method __init__ (line 129) | def __init__(self, code=100, *args):
  class CloudantDocumentException (line 137) | class CloudantDocumentException(CloudantException):
    method __init__ (line 144) | def __init__(self, code=100, *args):
  class CloudantFeedException (line 152) | class CloudantFeedException(CloudantException):
    method __init__ (line 159) | def __init__(self, code=100, *args):
  class CloudantIndexException (line 167) | class CloudantIndexException(CloudantException):
    method __init__ (line 174) | def __init__(self, code=100, *args):
  class CloudantReplicatorException (line 182) | class CloudantReplicatorException(CloudantException):
    method __init__ (line 189) | def __init__(self, code=100, *args):
  class CloudantViewException (line 197) | class CloudantViewException(CloudantException):
    method __init__ (line 204) | def __init__(self, code=100, *args):

FILE: src/cloudant/feed.py
  class Feed (line 26) | class Feed(object):
    method __init__ (line 44) | def __init__(self, source, raw_data=False, **options):
    method last_seq (line 67) | def last_seq(self):
    method stop (line 76) | def stop(self):
    method _start (line 82) | def _start(self):
    method _translate (line 91) | def _translate(self, options):
    method _validate (line 109) | def _validate(self, key, val, arg_types):
    method __iter__ (line 137) | def __iter__(self):
    method __next__ (line 143) | def __next__(self):
    method next (line 149) | def next(self):
    method _process_data (line 166) | def _process_data(self, line):
  class InfiniteFeed (line 200) | class InfiniteFeed(Feed):
    method __init__ (line 226) | def __init__(self, source, **options):
    method _validate (line 231) | def _validate(self, key, val, arg_types):
    method next (line 240) | def next(self):

FILE: src/cloudant/index.py
  class Index (line 29) | class Index(object):
    method __init__ (line 50) | def __init__(self, database, design_document_id=None, name=None, parti...
    method index_url (line 60) | def index_url(self):
    method design_document_id (line 69) | def design_document_id(self):
    method name (line 78) | def name(self):
    method type (line 87) | def type(self):
    method definition (line 96) | def definition(self):
    method partitioned (line 107) | def partitioned(self):
    method as_a_dict (line 117) | def as_a_dict(self):
    method create (line 136) | def create(self):
    method _def_check (line 170) | def _def_check(self):
    method delete (line 177) | def delete(self):
  class TextIndex (line 192) | class TextIndex(Index):
    method __init__ (line 210) | def __init__(self, database, design_document_id=None, name=None, **kwa...
    method _def_check (line 219) | def _def_check(self):
  class SpecialIndex (line 231) | class SpecialIndex(Index):
    method __init__ (line 239) | def __init__(
    method create (line 254) | def create(self):
    method delete (line 261) | def delete(self):

FILE: src/cloudant/query.py
  class Query (line 28) | class Query(dict):
    method __init__ (line 93) | def __init__(self, database, **kwargs):
    method url (line 106) | def url(self):
    method __call__ (line 120) | def __call__(self, **kwargs):
    method custom_result (line 188) | def custom_result(self, **options):

FILE: src/cloudant/replicator.py
  class Replicator (line 27) | class Replicator(object):
    method __init__ (line 38) | def __init__(self, client):
    method create_replication (line 46) | def create_replication(self, source_db=None, target_db=None,
    method list_replications (line 113) | def list_replications(self):
    method replication_state (line 129) | def replication_state(self, repl_id):
    method follow_replication (line 155) | def follow_replication(self, repl_id):
    method stop_replication (line 214) | def stop_replication(self, repl_id):

FILE: src/cloudant/result.py
  class ResultByKey (line 24) | class ResultByKey(object):
    method __init__ (line 41) | def __init__(self, value):
    method __call__ (line 44) | def __call__(self):
  class Result (line 47) | class Result(object):
    method __init__ (line 174) | def __init__(self, method_ref, **options):
    method __getitem__ (line 179) | def __getitem__(self, arg):
    method _handle_result_by_index (line 236) | def _handle_result_by_index(self, idx):
    method _handle_result_by_key (line 252) | def _handle_result_by_key(self, key):
    method _handle_result_by_idx_slice (line 261) | def _handle_result_by_idx_slice(self, idx_slice):
    method _handle_result_by_key_slice (line 300) | def _handle_result_by_key_slice(self, key_slice):
    method __iter__ (line 329) | def __iter__(self):
    method _real_page_size (line 369) | def _real_page_size(self):
    method _iterator (line 376) | def _iterator(self, response):
    method _parse_data (line 412) | def _parse_data(self, data):
    method all (line 418) | def all(self):
  class QueryResult (line 430) | class QueryResult(Result):
    method __init__ (line 511) | def __init__(self, query, **options):
    method __getitem__ (line 519) | def __getitem__(self, arg):
    method _parse_data (line 549) | def _parse_data(self, data):
    method _real_page_size (line 557) | def _real_page_size(self):
    method _iterator (line 563) | def _iterator(self, response):

FILE: src/cloudant/scheduler.py
  class Scheduler (line 21) | class Scheduler(object):
    method __init__ (line 29) | def __init__(self, client):
    method list_docs (line 34) | def list_docs(self, limit=None, skip=None):
    method get_doc (line 54) | def get_doc(self, doc_id):
    method list_jobs (line 63) | def list_jobs(self, limit=None, skip=None):

FILE: src/cloudant/security_document.py
  class SecurityDocument (line 23) | class SecurityDocument(dict):
    method __init__ (line 55) | def __init__(self, database):
    method document_url (line 64) | def document_url(self):
    method r_session (line 77) | def r_session(self):
    method json (line 85) | def json(self):
    method fetch (line 95) | def fetch(self):
    method save (line 107) | def save(self):
    method __enter__ (line 119) | def __enter__(self):
    method __exit__ (line 128) | def __exit__(self, *args):

FILE: src/cloudant/view.py
  class View (line 25) | class View(dict):
    method __init__ (line 93) | def __init__(
    method map (line 115) | def map(self):
    method map (line 134) | def map(self, js_func):
    method reduce (line 141) | def reduce(self):
    method reduce (line 161) | def reduce(self, js_func):
    method url (line 168) | def url(self):
    method __call__ (line 186) | def __call__(self, **kwargs):
    method custom_result (line 243) | def custom_result(self, **options):
  class QueryIndexView (line 302) | class QueryIndexView(View):
    method __init__ (line 311) | def __init__(self, ddoc, view_name, map_fields, reduce_func, **kwargs):
    method map (line 328) | def map(self):
    method map (line 339) | def map(self, map_func):
    method reduce (line 349) | def reduce(self):
    method reduce (line 361) | def reduce(self, reduce_func):
    method __call__ (line 370) | def __call__(self, **kwargs):
    method custom_result (line 378) | def custom_result(self, **options):

FILE: tests/__init__.py
  function unicode_ (line 27) | def unicode_(s):
  function iteritems_ (line 30) | def iteritems_(d):
  function bytes_ (line 33) | def bytes_(astr):
  function str_ (line 36) | def str_(astr):

FILE: tests/credentials.py
  function read_dot_couch (line 25) | def read_dot_couch(
  function read_dot_cloudant (line 48) | def read_dot_cloudant(
  function _read_dot_file (line 72) | def _read_dot_file(filename, section, username, password):

FILE: tests/integration/changes_test.py
  function setup_logging (line 32) | def setup_logging():
  class ChangesTest (line 44) | class ChangesTest(unittest.TestCase):
    method setUp (line 52) | def setUp(self):
    method tearDown (line 56) | def tearDown(self):
    method test_changes (line 61) | def test_changes(self):
    method test_changes_include_docs (line 99) | def test_changes_include_docs(self):

FILE: tests/integration/document_test.py
  class DocumentTest (line 31) | class DocumentTest(unittest.TestCase):
    method setUp (line 37) | def setUp(self):
    method tearDown (line 43) | def tearDown(self):
    method test_delete (line 47) | def test_delete(self):

FILE: tests/integration/end_to_end_example_test.py
  class E2ECouchTest (line 27) | class E2ECouchTest(unittest.TestCase):
    method setUp (line 31) | def setUp(self):
    method test_end_to_end (line 35) | def test_end_to_end(self):
  class E2ECloudantTest (line 86) | class E2ECloudantTest(unittest.TestCase):
    method setUp (line 92) | def setUp(self):
    method test_end_to_end (line 96) | def test_end_to_end(self):

FILE: tests/integration/iter_test.py
  class IterTest (line 30) | class IterTest(unittest.TestCase):
    method setUp (line 37) | def setUp(self):
    method tearDown (line 41) | def tearDown(self):
    method test_database_with_two_docs (line 46) | def test_database_with_two_docs(self):
    method test_database_with_many_docs (line 77) | def test_database_with_many_docs(self):

FILE: tests/integration/replicator_test.py
  function setup_logging (line 34) | def setup_logging():
  class ReplicatorTest (line 46) | class ReplicatorTest(unittest.TestCase):
    method setUp (line 51) | def setUp(self):
    method tearDown (line 56) | def tearDown(self):
    method test_init (line 67) | def test_init(self):
    method test_create_replication (line 78) | def test_create_replication(self):
    method test_follow_replication (line 148) | def test_follow_replication(self):
    method test_replication_state (line 193) | def test_replication_state(self):
    method test_list_replications (line 252) | def test_list_replications(self):

FILE: tests/unit/adapter_tests.py
  class AdapterTests (line 21) | class AdapterTests(UnitTestDbBase):
    method test_new_Replay429Adapter (line 26) | def test_new_Replay429Adapter(self):
    method test_retries_arg_Replay429Adapter (line 36) | def test_retries_arg_Replay429Adapter(self):
    method test_backoff_arg_Replay429Adapter (line 48) | def test_backoff_arg_Replay429Adapter(self):
    method test_args_Replay429Adapter (line 58) | def test_args_Replay429Adapter(self):

FILE: tests/unit/auth_renewal_tests.py
  class AuthRenewalTests (line 34) | class AuthRenewalTests(UnitTestDbBase):
    method setUp (line 39) | def setUp(self):
    method tearDown (line 45) | def tearDown(self):
    method test_client_db_doc_stack_success (line 52) | def test_client_db_doc_stack_success(self):
    method test_client_db_doc_stack_failure (line 117) | def test_client_db_doc_stack_failure(self):

FILE: tests/unit/changes_tests.py
  class ChangesTests (line 36) | class ChangesTests(UnitTestDbBase):
    method setUp (line 41) | def setUp(self):
    method tearDown (line 48) | def tearDown(self):
    method test_constructor_changes (line 55) | def test_constructor_changes(self):
    method test_get_last_seq (line 66) | def test_get_last_seq(self):
    method test_stop_iteration (line 75) | def test_stop_iteration(self):
    method test_get_raw_content (line 94) | def test_get_raw_content(self):
    method test_get_normal_feed_default (line 119) | def test_get_normal_feed_default(self):
    method test_get_normal_feed_explicit (line 133) | def test_get_normal_feed_explicit(self):
    method test_get_continuous_feed (line 147) | def test_get_continuous_feed(self):
    method test_get_longpoll_feed (line 167) | def test_get_longpoll_feed(self):
    method test_get_feed_with_heartbeat (line 182) | def test_get_feed_with_heartbeat(self):
    method test_get_raw_feed_with_heartbeat (line 203) | def test_get_raw_feed_with_heartbeat(self):
    method test_get_feed_descending (line 225) | def test_get_feed_descending(self):
    method test_get_feed_include_docs (line 252) | def test_get_feed_include_docs(self):
    method test_get_feed_using_style_main_only (line 266) | def test_get_feed_using_style_main_only(self):
    method test_get_feed_using_style_all_docs (line 288) | def test_get_feed_using_style_all_docs(self):
    method test_get_feed_using_since (line 309) | def test_get_feed_using_since(self):
    method test_get_feed_using_since_now (line 327) | def test_get_feed_using_since_now(self):
    method test_get_feed_using_since_zero (line 352) | def test_get_feed_using_since_zero(self):
    method test_get_feed_using_timeout (line 366) | def test_get_feed_using_timeout(self):
    method test_get_feed_using_limit (line 384) | def test_get_feed_using_limit(self):
    method test_get_feed_using_filter (line 400) | def test_get_feed_using_filter(self):
    method test_get_feed_using_conflicts_true (line 419) | def test_get_feed_using_conflicts_true(self):
    method test_get_feed_using_conflicts_false (line 436) | def test_get_feed_using_conflicts_false(self):
    method test_get_feed_using_doc_ids (line 451) | def test_get_feed_using_doc_ids(self):
    method test_get_feed_with_custom_filter_query_params (line 466) | def test_get_feed_with_custom_filter_query_params(self):
    method test_invalid_argument_type (line 481) | def test_invalid_argument_type(self):
    method test_invalid_non_positive_integer_argument (line 492) | def test_invalid_non_positive_integer_argument(self):
    method test_invalid_feed_value (line 503) | def test_invalid_feed_value(self):
    method test_invalid_style_value (line 514) | def test_invalid_style_value(self):

FILE: tests/unit/client_tests.py
  class CloudantClientExceptionTests (line 48) | class CloudantClientExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 53) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 61) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 69) | def test_raise_without_args(self):
    method test_raise_with_proper_code_and_args (line 78) | def test_raise_with_proper_code_and_args(self):
  class ClientTests (line 86) | class ClientTests(UnitTestDbBase):
    method test_couchdb_context_helper (line 96) | def test_couchdb_context_helper(self):
    method test_couchdb_admin_party_context_helper (line 112) | def test_couchdb_admin_party_context_helper(self):
    method test_constructor_with_url (line 123) | def test_constructor_with_url(self):
    method test_constructor_with_creds_removed_from_url (line 134) | def test_constructor_with_creds_removed_from_url(self):
    method test_connect (line 148) | def test_connect(self):
    method test_auto_connect (line 159) | def test_auto_connect(self):
    method test_multiple_connect (line 170) | def test_multiple_connect(self):
    method test_auto_renew_enabled (line 185) | def test_auto_renew_enabled(self):
    method test_auto_renew_enabled_with_auto_connect (line 200) | def test_auto_renew_enabled_with_auto_connect(self):
    method test_session (line 215) | def test_session(self):
    method test_session_cookie (line 231) | def test_session_cookie(self):
    method test_session_basic (line 246) | def test_session_basic(self, m_req):
    method test_session_basic_with_no_credentials (line 272) | def test_session_basic_with_no_credentials(self, m_req):
    method test_change_credentials_basic (line 297) | def test_change_credentials_basic(self, m_req):
    method test_basic_auth_str (line 339) | def test_basic_auth_str(self):
    method test_all_dbs (line 358) | def test_all_dbs(self):
    method test_create_delete_database (line 373) | def test_create_delete_database(self):
    method test_create_existing_database (line 389) | def test_create_existing_database(self):
    method test_create_invalid_database_name (line 403) | def test_create_invalid_database_name(self):
    method test_create_with_server_error (line 417) | def test_create_with_server_error(self, m_req):
    method test_delete_non_existing_database (line 454) | def test_delete_non_existing_database(self):
    method test_keys (line 468) | def test_keys(self):
    method test_get_non_existing_db_via_getitem (line 489) | def test_get_non_existing_db_via_getitem(self):
    method test_get_db_via_getitem (line 502) | def test_get_db_via_getitem(self):
    method test_delete_cached_db_object_via_delitem (line 517) | def test_delete_cached_db_object_via_delitem(self):
    method test_delete_remote_db_via_delitem (line 537) | def test_delete_remote_db_via_delitem(self):
    method test_get_cached_db_object_via_get (line 558) | def test_get_cached_db_object_via_get(self):
    method test_get_remote_db_via_get (line 576) | def test_get_remote_db_via_get(self):
    method test_set_non_db_value_via_setitem (line 596) | def test_set_non_db_value_via_setitem(self):
    method test_local_set_db_value_via_setitem (line 611) | def test_local_set_db_value_via_setitem(self):
    method test_create_db_via_setitem (line 625) | def test_create_db_via_setitem(self):
    method test_db_updates_feed_call (line 639) | def test_db_updates_feed_call(self):
  class CloudantClientTests (line 656) | class CloudantClientTests(UnitTestDbBase):
    method test_constructor_with_creds_removed_from_url (line 661) | def test_constructor_with_creds_removed_from_url(self):
    method test_cloudant_session_login (line 675) | def test_cloudant_session_login(self):
    method test_cloudant_session_login_with_new_credentials (line 688) | def test_cloudant_session_login_with_new_credentials(self):
    method test_cloudant_context_helper (line 701) | def test_cloudant_context_helper(self):
    method test_cloudant_bluemix_context_helper_with_legacy_creds (line 713) | def test_cloudant_bluemix_context_helper_with_legacy_creds(self):
    method test_cloudant_bluemix_context_helper_with_iam (line 739) | def test_cloudant_bluemix_context_helper_with_iam(self):
    method test_cloudant_bluemix_context_helper_raise_error_for_missing_iam_and_creds (line 762) | def test_cloudant_bluemix_context_helper_raise_error_for_missing_iam_a...
    method test_cloudant_bluemix_dedicated_context_helper (line 788) | def test_cloudant_bluemix_dedicated_context_helper(self):
    method test_constructor_with_account (line 816) | def test_constructor_with_account(self):
    method test_bluemix_constructor_with_legacy_creds (line 829) | def test_bluemix_constructor_with_legacy_creds(self):
    method test_bluemix_constructor_with_iam (line 864) | def test_bluemix_constructor_with_iam(self):
    method test_bluemix_constructor_specify_instance_name (line 895) | def test_bluemix_constructor_specify_instance_name(self):
    method test_bluemix_constructor_with_multiple_services (line 928) | def test_bluemix_constructor_with_multiple_services(self):
    method test_connect_headers (line 971) | def test_connect_headers(self):
    method test_connect_timeout (line 996) | def test_connect_timeout(self):
    method test_db_updates_infinite_feed_call (line 1005) | def test_db_updates_infinite_feed_call(self):
    method test_billing_data (line 1023) | def test_billing_data(self):
    method test_set_year_without_month_for_billing_data (line 1051) | def test_set_year_without_month_for_billing_data(self):
    method test_set_month_without_year_for_billing_data (line 1067) | def test_set_month_without_year_for_billing_data(self):
    method test_set_invalid_type_year_for_billing_data (line 1083) | def test_set_invalid_type_year_for_billing_data(self):
    method test_set_year_with_invalid_month_for_billing_data (line 1100) | def test_set_year_with_invalid_month_for_billing_data(self):
    method test_volume_usage_data (line 1118) | def test_volume_usage_data(self):
    method test_set_year_without_month_for_volume_usage_data (line 1143) | def test_set_year_without_month_for_volume_usage_data(self):
    method test_set_month_without_year_for_volume_usage_data (line 1159) | def test_set_month_without_year_for_volume_usage_data(self):
    method test_set_invalid_type_year_for_volume_usage_data (line 1175) | def test_set_invalid_type_year_for_volume_usage_data(self):
    method test_set_year_with_invalid_month_for_volume_usage_data (line 1192) | def test_set_year_with_invalid_month_for_volume_usage_data(self):
    method test_requests_usage_data (line 1210) | def test_requests_usage_data(self):
    method test_set_year_without_month_for_requests_usage_data (line 1235) | def test_set_year_without_month_for_requests_usage_data(self):
    method test_set_month_without_year_for_requests_usage_data (line 1251) | def test_set_month_without_year_for_requests_usage_data(self):
    method test_set_invalid_type_year_for_requests_usage_data (line 1267) | def test_set_invalid_type_year_for_requests_usage_data(self):
    method test_set_year_with_invalid_month_for_requests_usage_data (line 1284) | def test_set_year_with_invalid_month_for_requests_usage_data(self):
    method test_shared_databases (line 1302) | def test_shared_databases(self):
    method test_generate_api_key (line 1313) | def test_generate_api_key(self):
    method test_cors_configuration (line 1327) | def test_cors_configuration(self):
    method test_cors_origins (line 1341) | def test_cors_origins(self):
    method test_disable_cors (line 1353) | def test_disable_cors(self):
    method test_update_cors_configuration (line 1374) | def test_update_cors_configuration(self):

FILE: tests/unit/cloud_foundry_tests.py
  class CloudFoundryServiceTests (line 28) | class CloudFoundryServiceTests(unittest.TestCase):
    method __init__ (line 30) | def __init__(self, *args, **kwargs):
    method test_get_vcap_service_legacy_creds_success (line 135) | def test_get_vcap_service_legacy_creds_success(self):
    method test_get_vcap_service_iam_api_no_creds_success (line 142) | def test_get_vcap_service_iam_api_no_creds_success(self):
    method test_get_vcap_service_default_success_as_dict (line 153) | def test_get_vcap_service_default_success_as_dict(self):
    method test_get_vcap_service_default_failure_multiple_services (line 160) | def test_get_vcap_service_default_failure_multiple_services(self):
    method test_get_vcap_service_instance_host (line 168) | def test_get_vcap_service_instance_host(self):
    method test_get_vcap_service_instance_password (line 176) | def test_get_vcap_service_instance_password(self):
    method test_get_vcap_service_instance_port (line 184) | def test_get_vcap_service_instance_port(self):
    method test_get_vcap_service_instance_port_default (line 192) | def test_get_vcap_service_instance_port_default(self):
    method test_get_vcap_service_instance_url (line 200) | def test_get_vcap_service_instance_url(self):
    method test_get_vcap_service_instance_username (line 208) | def test_get_vcap_service_instance_username(self):
    method test_get_vcap_service_instance_iam_api_key (line 216) | def test_get_vcap_service_instance_iam_api_key(self):
    method test_raise_error_for_missing_host (line 224) | def test_raise_error_for_missing_host(self):
    method test_raise_error_for_missing_password (line 232) | def test_raise_error_for_missing_password(self):
    method test_raise_error_for_missing_username (line 244) | def test_raise_error_for_missing_username(self):
    method test_raise_error_for_invalid_credentials_type (line 256) | def test_raise_error_for_invalid_credentials_type(self):
    method test_raise_error_for_missing_iam_api_key_and_credentials (line 268) | def test_raise_error_for_missing_iam_api_key_and_credentials(self):
    method test_raise_error_for_missing_service (line 280) | def test_raise_error_for_missing_service(self):
    method test_raise_error_for_invalid_vcap (line 289) | def test_raise_error_for_invalid_vcap(self):
    method test_get_vcap_service_with_dedicated_service_name_success (line 294) | def test_get_vcap_service_with_dedicated_service_name_success(self):

FILE: tests/unit/database_partition_tests.py
  class DatabasePartitionTests (line 28) | class DatabasePartitionTests(UnitTestDbBase):
    method setUp (line 30) | def setUp(self):
    method tearDown (line 34) | def tearDown(self):
    method test_is_partitioned_database (line 38) | def test_is_partitioned_database(self):
    method test_create_partitioned_design_document (line 41) | def test_create_partitioned_design_document(self):
    method test_create_non_partitioned_design_document (line 52) | def test_create_non_partitioned_design_document(self):
    method test_partitioned_all_docs (line 63) | def test_partitioned_all_docs(self):
    method test_partition_metadata (line 71) | def test_partition_metadata(self):
    method test_partitioned_search (line 77) | def test_partitioned_search(self):
    method test_get_partitioned_index (line 96) | def test_get_partitioned_index(self):
    method test_partitioned_query (line 114) | def test_partitioned_query(self):
    method test_partitioned_view (line 127) | def test_partitioned_view(self):

FILE: tests/unit/database_tests.py
  class CloudantDatabaseExceptionTests (line 47) | class CloudantDatabaseExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 52) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 60) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 68) | def test_raise_without_args(self):
    method test_raise_with_proper_code_and_args (line 77) | def test_raise_with_proper_code_and_args(self):
  class DatabaseTests (line 86) | class DatabaseTests(UnitTestDbBase):
    method setUp (line 91) | def setUp(self):
    method tearDown (line 98) | def tearDown(self):
    method test_constructor (line 105) | def test_constructor(self):
    method test_bulk_docs_uses_custom_encoder (line 114) | def test_bulk_docs_uses_custom_encoder(self):
    method test_missing_revisions_uses_custom_encoder (line 128) | def test_missing_revisions_uses_custom_encoder(self):
    method test_revs_diff_uses_custom_encoder (line 139) | def test_revs_diff_uses_custom_encoder(self):
    method test_retrieve_db_url (line 149) | def test_retrieve_db_url(self):
    method test_retrieve_creds (line 159) | def test_retrieve_creds(self):
    method test_exists (line 174) | def test_exists(self):
    method test_exists_raises_httperror (line 184) | def test_exists_raises_httperror(self):
    method test_create_db_delete_db (line 198) | def test_create_db_delete_db(self):
    method test_delete_exception (line 221) | def test_delete_exception(self):
    method test_retrieve_db_metadata (line 232) | def test_retrieve_db_metadata(self):
    method test_retrieve_document_count (line 245) | def test_retrieve_document_count(self):
    method test_create_document_with_id (line 252) | def test_create_document_with_id(self):
    method test_get_non_existing_document_from_remote (line 276) | def test_get_non_existing_document_from_remote(self):
    method test_get_non_existing_document_from_cache (line 283) | def test_get_non_existing_document_from_cache(self):
    method test_get_document_from_cache (line 290) | def test_get_document_from_cache(self):
    method test_get_document_from_remote (line 301) | def test_get_document_from_remote(self):
    method test_create_document_that_already_exists (line 312) | def test_create_document_that_already_exists(self):
    method test_create_document_without_id (line 325) | def test_create_document_without_id(self):
    method test_create_design_document (line 340) | def test_create_design_document(self):
    method test_create_empty_document (line 357) | def test_create_empty_document(self):
    method test_retrieve_design_documents (line 368) | def test_retrieve_design_documents(self):
    method test_retrieve_design_document_list (line 395) | def test_retrieve_design_document_list(self):
    method test_retrieve_design_document (line 407) | def test_retrieve_design_document(self):
    method test_get_security_document (line 425) | def test_get_security_document(self):
    method test_retrieve_view_results (line 434) | def test_retrieve_view_results(self):
    method test_retrieve_grouped_view_result_with_page_size (line 457) | def test_retrieve_grouped_view_result_with_page_size(self):
    method test_retrieve_raw_view_results (line 485) | def test_retrieve_raw_view_results(self):
    method test_all_docs_post (line 499) | def test_all_docs_post(self):
    method test_all_docs_post_empty_key_list (line 514) | def test_all_docs_post_empty_key_list(self):
    method test_all_docs_post_multiple_params (line 523) | def test_all_docs_post_multiple_params(self):
    method test_all_docs_get (line 539) | def test_all_docs_get(self):
    method test_all_docs_get_with_long_type (line 550) | def test_all_docs_get_with_long_type(self):
    method test_all_docs_get_uses_custom_encoder (line 561) | def test_all_docs_get_uses_custom_encoder(self):
    method test_custom_result_context_manager (line 570) | def test_custom_result_context_manager(self):
    method test_keys (line 581) | def test_keys(self):
    method test_doc_id_in_db (line 592) | def test_doc_id_in_db(self):
    method test_doc_id_not_in_db (line 599) | def test_doc_id_not_in_db(self):
    method test_get_non_existing_doc_via_getitem (line 606) | def test_get_non_existing_doc_via_getitem(self):
    method test_get_db_via_getitem (line 616) | def test_get_db_via_getitem(self):
    method test_document_iteration_under_fetch_limit (line 643) | def test_document_iteration_under_fetch_limit(self):
    method test_document_iteration_over_fetch_limit (line 677) | def test_document_iteration_over_fetch_limit(self):
    method test_document_iteration_completeness (line 710) | def test_document_iteration_completeness(self):
    method test_document_iteration_returns_valid_documents (line 743) | def test_document_iteration_returns_valid_documents(self):
    method test_bulk_docs_creation (line 781) | def test_bulk_docs_creation(self):
    method test_bulk_docs_update (line 794) | def test_bulk_docs_update(self):
    method test_missing_revisions (line 819) | def test_missing_revisions(self):
    method test_revisions_diff (line 838) | def test_revisions_diff(self):
    method test_get_set_revision_limit (line 860) | def test_get_set_revision_limit(self, m_req):
    method test_view_clean_up (line 891) | def test_view_clean_up(self):
    method test_changes_feed_call (line 897) | def test_changes_feed_call(self):
    method test_changes_inifinite_feed_call (line 908) | def test_changes_inifinite_feed_call(self):
    method test_get_list_function_result_with_invalid_argument (line 920) | def test_get_list_function_result_with_invalid_argument(self):
    method test_get_list_function_result (line 929) | def test_get_list_function_result(self):
    method test_get_show_result (line 962) | def test_get_show_result(self):
    method test_create_doc_with_update_handler (line 987) | def test_create_doc_with_update_handler(self):
    method test_update_doc_with_update_handler (line 1008) | def test_update_doc_with_update_handler(self):
    method test_update_handler_raises_httperror (line 1043) | def test_update_handler_raises_httperror(self):
    method test_database_request_fails_after_client_disconnects (line 1063) | def test_database_request_fails_after_client_disconnects(self):
    method test_create_json_index (line 1078) | def test_create_json_index(self):
    method test_delete_json_index (line 1102) | def test_delete_json_index(self):
  class CloudantDatabaseTests (line 1117) | class CloudantDatabaseTests(UnitTestDbBase):
    method setUp (line 1122) | def setUp(self):
    method tearDown (line 1129) | def tearDown(self):
    method test_share_database_uses_custom_encoder (line 1136) | def test_share_database_uses_custom_encoder(self):
    method test_unshare_database_uses_custom_encoder (line 1147) | def test_unshare_database_uses_custom_encoder(self):
    method test_security_document (line 1158) | def test_security_document(self):
    method test_share_database_default_permissions (line 1168) | def test_share_database_default_permissions(self):
    method test_share_database (line 1179) | def test_share_database(self):
    method test_share_database_with_redundant_role_entries (line 1190) | def test_share_database_with_redundant_role_entries(self):
    method test_share_database_invalid_role (line 1201) | def test_share_database_invalid_role(self):
    method test_share_database_empty_role_list (line 1217) | def test_share_database_empty_role_list(self):
    method test_unshare_database (line 1233) | def test_unshare_database(self):
    method test_retrieve_shards (line 1244) | def test_retrieve_shards(self):
    method test_get_raw_query_result (line 1249) | def test_get_raw_query_result(self):
    method test_get_query_result_with_kwargs (line 1269) | def test_get_query_result_with_kwargs(self):
    method test_get_query_result_without_kwargs (line 1289) | def test_get_query_result_without_kwargs(self):
    method test_get_query_result_without_fields (line 1308) | def test_get_query_result_without_fields(self):
    method test_get_query_result_with_empty_fields_list (line 1333) | def test_get_query_result_with_empty_fields_list(self):
    method test_create_text_index (line 1359) | def test_create_text_index(self):
    method test_create_all_fields_text_index (line 1390) | def test_create_all_fields_text_index(self):
    method test_create_multiple_indexes_one_ddoc (line 1417) | def test_create_multiple_indexes_one_ddoc(self):
    method test_create_query_index_failure (line 1462) | def test_create_query_index_failure(self):
    method test_delete_text_index (line 1481) | def test_delete_text_index(self):
    method test_delete_query_index_failure (line 1492) | def test_delete_query_index_failure(self):
    method test_get_query_indexes_raw (line 1506) | def test_get_query_indexes_raw(self):
    method test_get_query_indexes (line 1540) | def test_get_query_indexes(self):
    method test_get_search_result_with_invalid_argument (line 1558) | def test_get_search_result_with_invalid_argument(self):
    method test_get_search_result_with_both_q_and_query (line 1568) | def test_get_search_result_with_both_q_and_query(self):
    method test_get_search_result_with_invalid_value_types (line 1578) | def test_get_search_result_with_invalid_value_types(self):
    method test_get_search_result_without_query (line 1613) | def test_get_search_result_without_query(self):
    method test_get_search_result_with_invalid_query_type (line 1627) | def test_get_search_result_with_invalid_query_type(self):
    method test_get_search_result_executes_search_query (line 1640) | def test_get_search_result_executes_search_query(self):
    method test_get_search_result_executes_search_q (line 1673) | def test_get_search_result_executes_search_q(self):
    method test_get_search_result_executes_search_query_with_group_option (line 1700) | def test_get_search_result_executes_search_query_with_group_option(self):

FILE: tests/unit/db_updates_tests.py
  class DbUpdatesTestsBase (line 33) | class DbUpdatesTestsBase(UnitTestDbBase):
    method setUp (line 38) | def setUp(self):
    method tearDown (line 50) | def tearDown(self):
    method create_dbs (line 71) | def create_dbs(self):
    method assert_changes_in_db_updates_feed (line 88) | def assert_changes_in_db_updates_feed(self, changes):
  class CouchDbUpdatesTests (line 109) | class CouchDbUpdatesTests(DbUpdatesTestsBase):
    method test_constructor_db_updates (line 113) | def test_constructor_db_updates(self):
    method test_stop_iteration_of_continuous_feed_with_heartbeat (line 125) | def test_stop_iteration_of_continuous_feed_with_heartbeat(self):
    method test_get_raw_content (line 142) | def test_get_raw_content(self):
    method test_get_longpoll_feed_as_default (line 159) | def test_get_longpoll_feed_as_default(self):
    method test_get_longpoll_feed_explicit (line 180) | def test_get_longpoll_feed_explicit(self):
    method test_get_continuous_with_timeout (line 202) | def test_get_continuous_with_timeout(self):
    method test_invalid_argument (line 220) | def test_invalid_argument(self):
    method test_invalid_argument_type (line 239) | def test_invalid_argument_type(self):
    method test_invalid_non_positive_integer_argument (line 251) | def test_invalid_non_positive_integer_argument(self):
    method test_invalid_feed_value (line 262) | def test_invalid_feed_value(self):
  class CloudantDbUpdatesTests (line 281) | class CloudantDbUpdatesTests(DbUpdatesTestsBase):
    method test_constructor_db_updates (line 286) | def test_constructor_db_updates(self):
    method test_get_last_seq (line 298) | def test_get_last_seq(self):
    method test_stop_iteration_of_continuous_feed_using_since_now (line 308) | def test_stop_iteration_of_continuous_feed_using_since_now(self):
    method test_get_raw_content (line 326) | def test_get_raw_content(self):
    method test_get_normal_feed_default (line 342) | def test_get_normal_feed_default(self):
    method test_get_normal_feed_explicit (line 356) | def test_get_normal_feed_explicit(self):
    method test_get_longpoll_feed (line 370) | def test_get_longpoll_feed(self):
    method test_get_feed_with_heartbeat (line 382) | def test_get_feed_with_heartbeat(self):
    method test_get_raw_feed_with_heartbeat (line 404) | def test_get_raw_feed_with_heartbeat(self):
    method test_get_feed_descending (line 427) | def test_get_feed_descending(self):
    method test_get_feed_using_since (line 441) | def test_get_feed_using_since(self):
    method test_get_feed_using_timeout (line 455) | def test_get_feed_using_timeout(self):
    method test_invalid_argument (line 478) | def test_invalid_argument(self):
    method test_invalid_argument_type (line 492) | def test_invalid_argument_type(self):
    method test_invalid_non_positive_integer_argument (line 504) | def test_invalid_non_positive_integer_argument(self):
    method test_invalid_feed_value (line 515) | def test_invalid_feed_value(self):

FILE: tests/unit/design_document_tests.py
  class CloudantDesignDocumentExceptionTests (line 40) | class CloudantDesignDocumentExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 45) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 53) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 61) | def test_raise_without_args(self):
    method test_raise_with_proper_code_and_args (line 70) | def test_raise_with_proper_code_and_args(self):
  class DesignDocumentTests (line 79) | class DesignDocumentTests(UnitTestDbBase):
    method setUp (line 84) | def setUp(self):
    method tearDown (line 91) | def tearDown(self):
    method test_constructor_with_docid (line 98) | def test_constructor_with_docid(self):
    method test_constructor_with_design_docid (line 108) | def test_constructor_with_design_docid(self):
    method test_constructor_without_docid (line 118) | def test_constructor_without_docid(self):
    method test_create_design_document_with_docid_encoded_url (line 127) | def test_create_design_document_with_docid_encoded_url(self):
    method test_fetch_existing_design_document_with_docid_encoded_url (line 138) | def test_fetch_existing_design_document_with_docid_encoded_url(self):
    method test_update_design_document_with_encoded_url (line 149) | def test_update_design_document_with_encoded_url(self):
    method test_delete_design_document_success_with_encoded_url (line 164) | def test_delete_design_document_success_with_encoded_url(self):
    method test_add_a_view (line 176) | def test_add_a_view(self):
    method test_adding_existing_view (line 194) | def test_adding_existing_view(self):
    method test_adding_query_index_view (line 212) | def test_adding_query_index_view(self):
    method test_update_a_view (line 227) | def test_update_a_view(self):
    method test_update_non_existing_view (line 247) | def test_update_non_existing_view(self):
    method test_update_query_index_view (line 264) | def test_update_query_index_view(self):
    method test_delete_a_view (line 295) | def test_delete_a_view(self):
    method test_delete_a_query_index_view (line 308) | def test_delete_a_query_index_view(self):
    method test_fetch_map_reduce (line 336) | def test_fetch_map_reduce(self):
    method test_fetch_dbcopy (line 369) | def test_fetch_dbcopy(self):
    method test_fetch_no_views (line 409) | def test_fetch_no_views(self):
    method test_fetch_query_views (line 426) | def test_fetch_query_views(self):
    method test_fetch_text_indexes (line 458) | def test_fetch_text_indexes(self):
    method test_fetch_text_indexes_and_query_views (line 493) | def test_fetch_text_indexes_and_query_views(self):
    method test_text_index_save_fails_when_lang_is_not_query (line 535) | def test_text_index_save_fails_when_lang_is_not_query(self):
    method test_text_index_save_fails_with_existing_search_index (line 559) | def test_text_index_save_fails_with_existing_search_index(self):
    method test_mr_view_save_fails_when_lang_is_query (line 594) | def test_mr_view_save_fails_when_lang_is_query(self):
    method test_mr_view_save_succeeds (line 613) | def test_mr_view_save_succeeds(self):
    method test_query_view_save_fails_when_lang_is_not_query (line 626) | def test_query_view_save_fails_when_lang_is_not_query(self):
    method test_query_view_save_succeeds (line 659) | def test_query_view_save_succeeds(self):
    method test_save_with_no_views (line 684) | def test_save_with_no_views(self):
    method test_setting_id (line 707) | def test_setting_id(self):
    method test_iterating_over_views (line 720) | def test_iterating_over_views(self):
    method test_list_views (line 737) | def test_list_views(self):
    method test_get_view (line 754) | def test_get_view(self):
    method test_get_info (line 773) | def test_get_info(self):
    method test_get_info_raises_httperror (line 805) | def test_get_info_raises_httperror(self):
    method test_get_search_info (line 822) | def test_get_search_info(self):
    method test_get_search_disk_size (line 853) | def test_get_search_disk_size(self):
    method test_get_search_info_raises_httperror (line 891) | def test_get_search_info_raises_httperror(self):
    method test_add_a_search_index (line 908) | def test_add_a_search_index(self):
    method test_add_a_search_index_with_analyzer (line 927) | def test_add_a_search_index_with_analyzer(self):
    method test_adding_existing_search_index (line 950) | def test_adding_existing_search_index(self):
    method test_update_a_search_index (line 973) | def test_update_a_search_index(self):
    method test_update_a_search_index_with_analyzer (line 996) | def test_update_a_search_index_with_analyzer(self):
    method test_update_non_existing_search_index (line 1024) | def test_update_non_existing_search_index(self):
    method test_delete_a_search_index (line 1042) | def test_delete_a_search_index(self):
    method test_fetch_search_index (line 1062) | def test_fetch_search_index(self):
    method test_fetch_no_search_index (line 1095) | def test_fetch_no_search_index(self):
    method test_search_index_save_fails_when_lang_is_query (line 1115) | def test_search_index_save_fails_when_lang_is_query(self):
    method test_search_index_save_fails_with_existing_text_index (line 1136) | def test_search_index_save_fails_with_existing_text_index(self):
    method test_search_index_save_succeeds (line 1169) | def test_search_index_save_succeeds(self):
    method test_save_with_no_search_indexes (line 1182) | def test_save_with_no_search_indexes(self):
    method test_iterating_over_search_indexes (line 1203) | def test_iterating_over_search_indexes(self):
    method test_list_search_indexes (line 1222) | def test_list_search_indexes(self):
    method test_get_search_index (line 1241) | def test_get_search_index(self):
    method test_rewrite_rule (line 1260) | def test_rewrite_rule(self):
    method test_add_a_list_function (line 1286) | def test_add_a_list_function(self):
    method test_adding_existing_list_function (line 1309) | def test_adding_existing_list_function(self):
    method test_update_a_list_function (line 1332) | def test_update_a_list_function(self):
    method test_update_non_existing_list_function (line 1358) | def test_update_non_existing_list_function(self):
    method test_delete_a_list_function (line 1377) | def test_delete_a_list_function(self):
    method test_fetch_list_functions (line 1399) | def test_fetch_list_functions(self):
    method test_fetch_no_list_functions (line 1433) | def test_fetch_no_list_functions(self):
    method test_save_with_no_list_functions (line 1453) | def test_save_with_no_list_functions(self):
    method test_iterating_over_list_functions (line 1473) | def test_iterating_over_list_functions(self):
    method test_listing_list_functions (line 1493) | def test_listing_list_functions(self):
    method test_get_list_function (line 1513) | def test_get_list_function(self):
    method test_geospatial_index (line 1534) | def test_geospatial_index(self):
    method test_add_a_show_function (line 1589) | def test_add_a_show_function(self):
    method test_adding_existing_show_functions (line 1612) | def test_adding_existing_show_functions(self):
    method test_update_a_show_function (line 1635) | def test_update_a_show_function(self):
    method test_update_non_existing_show_function (line 1661) | def test_update_non_existing_show_function(self):
    method test_delete_a_show_function (line 1680) | def test_delete_a_show_function(self):
    method test_fetch_show_functions (line 1702) | def test_fetch_show_functions(self):
    method test_fetch_no_show_functions (line 1736) | def test_fetch_no_show_functions(self):
    method test_save_with_no_show_functions (line 1756) | def test_save_with_no_show_functions(self):
    method test_iterating_over_show_functions (line 1776) | def test_iterating_over_show_functions(self):
    method test_listing_show_functions (line 1796) | def test_listing_show_functions(self):
    method test_get_show_function (line 1816) | def test_get_show_function(self):
    method test_update_validator (line 1836) | def test_update_validator(self):

FILE: tests/unit/document_tests.py
  function find_fixture (line 43) | def find_fixture(name):
  class CloudantDocumentExceptionTests (line 49) | class CloudantDocumentExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 54) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 62) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 70) | def test_raise_without_args(self):
    method test_raise_with_proper_code_and_args (line 79) | def test_raise_with_proper_code_and_args(self):
  class DocumentTests (line 88) | class DocumentTests(UnitTestDbBase):
    method setUp (line 93) | def setUp(self):
    method tearDown (line 100) | def tearDown(self):
    method test_constructor_with_docid (line 107) | def test_constructor_with_docid(self):
    method test_document_url (line 116) | def test_document_url(self):
    method test_document_url_encodes_correctly (line 125) | def test_document_url_encodes_correctly(self):
    method test_design_document_url (line 135) | def test_design_document_url(self):
    method test_design_document_url_encodes_correctly (line 146) | def test_design_document_url_encodes_correctly(self):
    method test_constructor_without_docid (line 156) | def test_constructor_without_docid(self):
    method test_document_exists (line 166) | def test_document_exists(self):
    method test_document_exists_raises_httperror (line 178) | def test_document_exists_raises_httperror(self):
    method test_retrieve_document_json (line 194) | def test_retrieve_document_json(self):
    method test_create_document_with_docid (line 206) | def test_create_document_with_docid(self):
    method test_create_document_with_docid_encoded_url (line 219) | def test_create_document_with_docid_encoded_url(self):
    method test_create_document_without_docid (line 232) | def test_create_document_without_docid(self):
    method test_create_existing_document (line 247) | def test_create_existing_document(self):
    method test_fetch_document_without_docid (line 261) | def test_fetch_document_without_docid(self):
    method test_fetch_non_existing_document (line 276) | def test_fetch_non_existing_document(self):
    method test_fetch_existing_document_with_docid (line 287) | def test_fetch_existing_document_with_docid(self):
    method test_appended_error_message_using_save_with_invalid_key (line 299) | def test_appended_error_message_using_save_with_invalid_key(self):
    method test_fetch_existing_document_with_docid_encoded_url (line 331) | def test_fetch_existing_document_with_docid_encoded_url(self):
    method test_create_document_using_save (line 344) | def test_create_document_using_save(self):
    method test_update_document_using_save (line 360) | def test_update_document_using_save(self):
    method test_update_document_with_encoded_url (line 379) | def test_update_document_with_encoded_url(self):
    method test_list_field_append_successfully (line 398) | def test_list_field_append_successfully(self):
    method test_list_field_append_failure (line 411) | def test_list_field_append_failure(self):
    method test_list_field_remove_successfully (line 425) | def test_list_field_remove_successfully(self):
    method test_list_field_remove_failure (line 437) | def test_list_field_remove_failure(self):
    method test_field_set_and_replace (line 451) | def test_field_set_and_replace(self):
    method test_update_field (line 466) | def test_update_field(self):
    method test_update_field_maxretries (line 483) | def test_update_field_maxretries(self, m_save):
    method test_update_field_success_on_retry (line 512) | def test_update_field_success_on_retry(self):
    method test_delete_document_failure (line 547) | def test_delete_document_failure(self):
    method test_delete_document_success (line 566) | def test_delete_document_success(self):
    method test_delete_document_success_with_encoded_url (line 581) | def test_delete_document_success_with_encoded_url(self):
    method test_document_context_manager (line 596) | def test_document_context_manager(self):
    method test_document_context_manager_no_doc_id (line 613) | def test_document_context_manager_no_doc_id(self):
    method test_document_context_manager_creation_failure_on_error (line 625) | def test_document_context_manager_creation_failure_on_error(self):
    method test_document_context_manager_update_failure_on_error (line 643) | def test_document_context_manager_update_failure_on_error(self):
    method test_document_context_manager_doc_create (line 666) | def test_document_context_manager_doc_create(self):
    method test_setting_id (line 677) | def test_setting_id(self):
    method test_removing_id (line 686) | def test_removing_id(self):
    method test_get_text_attachment (line 695) | def test_get_text_attachment(self):
    method test_get_json_attachment (line 721) | def test_get_json_attachment(self):
    method test_get_binary_attachment (line 745) | def test_get_binary_attachment(self):
    method test_attachment_management (line 766) | def test_attachment_management(self):
    method test_document_request_fails_after_client_disconnects (line 897) | def test_document_request_fails_after_client_disconnects(self):
    method test_document_custom_json_encoder_and_decoder (line 914) | def test_document_custom_json_encoder_and_decoder(self):

FILE: tests/unit/document_validation_tests.py
  class ValidationExceptionMsg (line 29) | class ValidationExceptionMsg(Enum):
  class Expect (line 33) | class Expect(Enum):
  class ValidationTests (line 41) | class ValidationTests(unittest.TestCase):
    method setUp (line 45) | def setUp(self):
    method teardown (line 60) | def teardown(self):
    method test_get_invalid_all_docs (line 70) | def test_get_invalid_all_docs(self):
    method test_get_valid_ddoc (line 78) | def test_get_valid_ddoc(self):
    method test_get_invalid_design (line 87) | def test_get_invalid_design(self):
    method test_get_missing_ddoc_with_slash (line 96) | def test_get_missing_ddoc_with_slash(self):
    method test_get_invalid_view (line 104) | def test_get_invalid_view(self):
    method test_get_invalid_view_info (line 113) | def test_get_invalid_view_info(self):
    method test_get_invalid_search (line 122) | def test_get_invalid_search(self):
    method test_get_invalid_search_info (line 131) | def test_get_invalid_search_info(self):
    method test_get_missing_geo (line 140) | def test_get_missing_geo(self):
    method test_get_missing_geo_info (line 154) | def test_get_missing_geo_info(self):
    method test_get_local_doc (line 163) | def test_get_local_doc(self):
    method test_get_invalid_local (line 171) | def test_get_invalid_local(self):
    method test_get_invalid_local_docs (line 179) | def test_get_invalid_local_docs(self):
    method test_get_invalid_design_docs (line 187) | def test_get_invalid_design_docs(self):
    method test_get_invalid_changes (line 195) | def test_get_invalid_changes(self):
    method test_get_invalid_ensure_full_commit (line 203) | def test_get_invalid_ensure_full_commit(self):
    method test_get_invalid_index (line 211) | def test_get_invalid_index(self):
    method test_get_invalid_revs_limit (line 219) | def test_get_invalid_revs_limit(self):
    method test_get_invalid_security (line 227) | def test_get_invalid_security(self):
    method test_get_invalid_shards (line 235) | def test_get_invalid_shards(self):
    method test_delete_invalid_index (line 243) | def test_delete_invalid_index(self):
    method test_delete_valid_ddoc (line 251) | def test_delete_valid_ddoc(self):
    method test_delete_invalid_ddoc (line 259) | def test_delete_invalid_ddoc(self):
    method test_delete_valid_local_doc (line 268) | def test_delete_valid_local_doc(self):
    method test_delete_invalid_local (line 276) | def test_delete_invalid_local(self):
    method test_put_valid_ddoc (line 285) | def test_put_valid_ddoc(self):
    method test_put_invalid_ddoc (line 293) | def test_put_invalid_ddoc(self):
    method test_put_valid_local_doc (line 301) | def test_put_valid_local_doc(self):
    method test_put_invalid_local_doc (line 309) | def test_put_invalid_local_doc(self):
    method test_put_invalid_revs_limit (line 317) | def test_put_invalid_revs_limit(self):
    method test_put_invalid_security (line 325) | def test_put_invalid_security(self):
    method test_get_valid_ddoc_attachment (line 333) | def test_get_valid_ddoc_attachment(self):
    method test_put_valid_ddoc_attachment (line 341) | def test_put_valid_ddoc_attachment(self):
    method test_delete_valid_ddoc_attachment (line 349) | def test_delete_valid_ddoc_attachment(self):
    method test_get_invalid_ddoc_attachment (line 357) | def test_get_invalid_ddoc_attachment(self):
    method test_put_invalid_ddoc_attachment (line 367) | def test_put_invalid_ddoc_attachment(self):
    method test_delete_invalid_ddoc_attachment (line 377) | def test_delete_invalid_ddoc_attachment(self):
    method test_delete_index_via_attachment (line 387) | def test_delete_index_via_attachment(self):
    method test_get_view_via_ddoc_attachment (line 405) | def test_get_view_via_ddoc_attachment(self):
    method test_put_view_via_ddoc_attachment (line 423) | def test_put_view_via_ddoc_attachment(self):
    method test_delete_view_via_ddoc_attachment (line 436) | def test_delete_view_via_ddoc_attachment(self):
    method test_get_view_info_via_ddoc_attachment (line 449) | def test_get_view_info_via_ddoc_attachment(self):
    method test_get_search_via_ddoc_attachment (line 462) | def test_get_search_via_ddoc_attachment(self):
    method test_get_search_info_via_ddoc_attachment (line 483) | def test_get_search_info_via_ddoc_attachment(self):
    method test_get_geo_via_ddoc_attachment (line 497) | def test_get_geo_via_ddoc_attachment(self):
    method test_get_geo_info_via_ddoc_attachment (line 514) | def test_get_geo_info_via_ddoc_attachment(self):
    method test_get_invalid_partition_info (line 529) | def test_get_invalid_partition_info(self):
    method test_get_invalid_partition_info_via_attachment (line 537) | def test_get_invalid_partition_info_via_attachment(self):
    method test_get_partition_info (line 545) | def test_get_partition_info(self):
    method test_get_invalid_partition_all_docs_via_attachment (line 553) | def test_get_invalid_partition_all_docs_via_attachment(self):
    method mocked_get_requests (line 561) | def mocked_get_requests(self, rev=None, override_status_code=None):
    method mocked_get_att_requests (line 586) | def mocked_get_att_requests(self):
    method mocked_head_requests (line 602) | def mocked_head_requests(self, override_status_code=None):
    method mocked_delete_requests (line 613) | def mocked_delete_requests(self):
    method mocked_delete_att_requests (line 623) | def mocked_delete_att_requests(self):
    method mocked_put_doc_requests (line 640) | def mocked_put_doc_requests(self):
    method mocked_put_att_requests (line 655) | def mocked_put_att_requests(self):
    method get_document_variants (line 674) | def get_document_variants(self, doc_id, expected_enum, is_ddoc=False,
    method get_doc_attachment_variants (line 688) | def get_doc_attachment_variants(self, doc_id, att_name, expected_enum,...
    method put_document_variants (line 701) | def put_document_variants(self, doc_id, expected_enum, is_ddoc=False,
    method put_doc_attachment_variants (line 713) | def put_doc_attachment_variants(self, doc_id, att_name, expected_enum,...
    method delete_document_variants (line 726) | def delete_document_variants(self, doc_id, expected_enum, is_ddoc=False,
    method delete_doc_attachment_variants (line 738) | def delete_doc_attachment_variants(self, doc_id, attname, expected_enu...
    method head_document (line 752) | def head_document(self):
    method delete_document (line 762) | def delete_document(self):
    method fetch_document (line 778) | def fetch_document(self):
    method put_document (line 793) | def put_document(self):
    method delete_doc_attachment (line 808) | def delete_doc_attachment(self):
    method get_doc_attachment (line 825) | def get_doc_attachment(self):
    method put_doc_attachment (line 841) | def put_doc_attachment(self):
    method create_doc (line 860) | def create_doc(self, doc_id=None, is_ddoc=False):
    method assert_exception_msg (line 876) | def assert_exception_msg(self, cae):
    method assert_path_segments (line 892) | def assert_path_segments(self, actual_call_args_list, exp_segment_count):

FILE: tests/unit/iam_auth_tests.py
  class IAMAuthTests (line 64) | class IAMAuthTests(unittest.TestCase):
    method _mock_cookie (line 68) | def _mock_cookie(expires_secs=300):
    method test_iam_set_credentials (line 89) | def test_iam_set_credentials(self):
    method test_iam_get_access_token (line 99) | def test_iam_get_access_token(self, m_req):
    method test_iam_get_access_token_with_iam_client_id_and_secret (line 125) | def test_iam_get_access_token_with_iam_client_id_and_secret(self, m_req):
    method test_iam_login (line 157) | def test_iam_login(self, m_token, m_req):
    method test_iam_logout (line 175) | def test_iam_logout(self):
    method test_iam_get_session_info (line 184) | def test_iam_get_session_info(self, m_get):
    method test_iam_first_request (line 201) | def test_iam_first_request(self, m_req, m_login):
    method test_iam_renew_cookie_on_expiry (line 226) | def test_iam_renew_cookie_on_expiry(self, m_req, m_login):
    method test_iam_renew_cookie_on_401_success (line 248) | def test_iam_renew_cookie_on_401_success(self, m_req, m_login):
    method test_iam_renew_cookie_on_401_failure (line 278) | def test_iam_renew_cookie_on_401_failure(self, m_req, m_login):
    method test_iam_renew_cookie_disabled (line 304) | def test_iam_renew_cookie_disabled(self, m_req, m_login):
    method test_iam_client_create (line 327) | def test_iam_client_create(self, m_req, m_login):
    method test_iam_client_session_login (line 350) | def test_iam_client_session_login(self, m_set, m_login):
    method test_iam_client_session_login_with_new_credentials (line 366) | def test_iam_client_session_login_with_new_credentials(self, m_set, m_...

FILE: tests/unit/index_tests.py
  class CloudantIndexExceptionTests (line 42) | class CloudantIndexExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 47) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 55) | def test_raise_using_invalid_code(self):
    method test_raise_with_proper_code_and_args (line 63) | def test_raise_with_proper_code_and_args(self):
  class IndexTests (line 73) | class IndexTests(UnitTestDbBase):
    method setUp (line 77) | def setUp(self):
    method tearDown (line 84) | def tearDown(self):
    method test_constructor_with_args (line 91) | def test_constructor_with_args(self):
    method test_constructor_with_only_a_db (line 104) | def test_constructor_with_only_a_db(self):
    method test_retrieve_index_url (line 117) | def test_retrieve_index_url(self):
    method test_index_to_dictionary (line 127) | def test_index_to_dictionary(self):
    method test_index_as_a_dict_with_none_attributes (line 140) | def test_index_as_a_dict_with_none_attributes(self):
    method test_create_an_index_using_ddoc_index_name (line 153) | def test_create_an_index_using_ddoc_index_name(self):
    method test_create_an_index_without_ddoc_index_name (line 180) | def test_create_an_index_without_ddoc_index_name(self):
    method test_create_an_index_with_empty_ddoc_index_name (line 208) | def test_create_an_index_with_empty_ddoc_index_name(self):
    method test_create_an_index_using_design_prefix (line 236) | def test_create_an_index_using_design_prefix(self):
    method test_create_uses_custom_encoder (line 264) | def test_create_uses_custom_encoder(self):
    method test_create_fails_due_to_ddocid_validation (line 275) | def test_create_fails_due_to_ddocid_validation(self):
    method test_create_fails_due_to_index_name_validation (line 288) | def test_create_fails_due_to_index_name_validation(self):
    method test_create_fails_due_to_def_validation (line 301) | def test_create_fails_due_to_def_validation(self):
    method test_deleting_index (line 313) | def test_deleting_index(self):
    method test_deleting_non_existing_index (line 325) | def test_deleting_non_existing_index(self):
    method test_deleting_index_without_ddoc (line 337) | def test_deleting_index_without_ddoc(self):
    method test_deleting_index_without_index_name (line 353) | def test_deleting_index_without_index_name(self):
    method test_index_via_query (line 369) | def test_index_via_query(self):
    method test_index_usage_via_query (line 383) | def test_index_usage_via_query(self):
  class TextIndexTests (line 396) | class TextIndexTests(UnitTestDbBase):
    method setUp (line 400) | def setUp(self):
    method tearDown (line 407) | def tearDown(self):
    method test_constructor_with_args (line 414) | def test_constructor_with_args(self):
    method test_constructor_with_only_a_db (line 427) | def test_constructor_with_only_a_db(self):
    method test_create_a_search_index_no_kwargs (line 440) | def test_create_a_search_index_no_kwargs(self):
    method test_create_a_search_index_with_kwargs (line 467) | def test_create_a_search_index_with_kwargs(self):
    method test_create_a_search_index_invalid_argument (line 502) | def test_create_a_search_index_invalid_argument(self):
    method test_create_a_search_index_invalid_fields_value (line 512) | def test_create_a_search_index_invalid_fields_value(self):
    method test_create_a_search_index_invalid_default_field_value (line 527) | def test_create_a_search_index_invalid_default_field_value(self):
    method test_create_a_search_index_invalid_selector_value (line 542) | def test_create_a_search_index_invalid_selector_value(self):
    method test_create_unpartitioned_query_index (line 557) | def test_create_unpartitioned_query_index(self):
    method test_search_index_via_query (line 572) | def test_search_index_via_query(self):
  class SpecialIndexTests (line 588) | class SpecialIndexTests(unittest.TestCase):
    method setUp (line 592) | def setUp(self):
    method test_constructor (line 600) | def test_constructor(self):
    method test_create_disabled (line 612) | def test_create_disabled(self):
    method test_delete_disabled (line 625) | def test_delete_disabled(self):

FILE: tests/unit/infinite_feed_tests.py
  class MethodCallCount (line 31) | class MethodCallCount(object):
    method __init__ (line 37) | def __init__(self, meth_ref):
    method __call__ (line 41) | def __call__(self):
  class CloudantFeedExceptionTests (line 45) | class CloudantFeedExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 50) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 58) | def test_raise_using_invalid_code(self):
    method test_raise_with_proper_code_and_args (line 66) | def test_raise_with_proper_code_and_args(self):
  class InfiniteFeedTests (line 75) | class InfiniteFeedTests(UnitTestDbBase):
    method setUp (line 80) | def setUp(self):
    method tearDown (line 87) | def tearDown(self):
    method test_constructor_no_feed_option (line 94) | def test_constructor_no_feed_option(self):
    method test_constructor_with_feed_option (line 105) | def test_constructor_with_feed_option(self):
    method test_constructor_with_invalid_feed_option (line 117) | def test_constructor_with_invalid_feed_option(self):
    method test_invalid_source_couchdb (line 131) | def test_invalid_source_couchdb(self):
    method test_constructor_db_updates (line 142) | def test_constructor_db_updates(self):
    method test_infinite_feed (line 153) | def test_infinite_feed(self):
    method test_infinite_db_updates_feed (line 190) | def test_infinite_db_updates_feed(self):

FILE: tests/unit/param_translation_tests.py
  class PythonToCouchTests (line 25) | class PythonToCouchTests(unittest.TestCase):
    method test_valid_descending (line 30) | def test_valid_descending(self):
    method test_valid_endkey (line 43) | def test_valid_endkey(self):
    method test_valid_endkey_docid (line 63) | def test_valid_endkey_docid(self):
    method test_valid_group (line 72) | def test_valid_group(self):
    method test_valid_group_level (line 79) | def test_valid_group_level(self):
    method test_valid_include_docs (line 97) | def test_valid_include_docs(self):
    method test_valid_inclusive_end (line 110) | def test_valid_inclusive_end(self):
    method test_valid_key (line 123) | def test_valid_key(self):
    method test_valid_keys (line 140) | def test_valid_keys(self):
    method test_valid_limit (line 163) | def test_valid_limit(self):
    method test_valid_reduce (line 172) | def test_valid_reduce(self):
    method test_valid_skip (line 182) | def test_valid_skip(self):
    method test_valid_stale (line 191) | def test_valid_stale(self):
    method test_valid_startkey (line 201) | def test_valid_startkey(self):
    method test_valid_startkey_docid (line 221) | def test_valid_startkey_docid(self):
    method test_valid_update (line 230) | def test_valid_update(self):
    method test_invalid_argument (line 238) | def test_invalid_argument(self):
    method test_invalid_descending (line 246) | def test_invalid_descending(self):
    method test_invalid_endkey (line 255) | def test_invalid_endkey(self):
    method test_invalid_endkey_docid (line 265) | def test_invalid_endkey_docid(self):
    method test_invalid_group (line 274) | def test_invalid_group(self):
    method test_invalid_group_level (line 283) | def test_invalid_group_level(self):
    method test_invalid_include_docs (line 292) | def test_invalid_include_docs(self):
    method test_invalid_inclusive_end (line 301) | def test_invalid_inclusive_end(self):
    method test_invalid_key (line 310) | def test_invalid_key(self):
    method test_invalid_keys_not_list (line 320) | def test_invalid_keys_not_list(self):
    method test_invalid_keys_invalid_key (line 329) | def test_invalid_keys_invalid_key(self):
    method test_invalid_limit (line 339) | def test_invalid_limit(self):
    method test_invalid_reduce (line 348) | def test_invalid_reduce(self):
    method test_invalid_skip (line 357) | def test_invalid_skip(self):
    method test_invalid_stale (line 366) | def test_invalid_stale(self):
    method test_invalid_startkey (line 380) | def test_invalid_startkey(self):
    method test_invalid_startkey_docid (line 390) | def test_invalid_startkey_docid(self):

FILE: tests/unit/query_result_tests.py
  class QueryResultTests (line 35) | class QueryResultTests(UnitTestDbBase):
    method setUp (line 40) | def setUp(self):
    method tearDown (line 48) | def tearDown(self):
    method create_result (line 55) | def create_result(self, selector={'_id': {'$gt': 0}},
    method test_constructor_with_options (line 67) | def test_constructor_with_options(self):
    method test_constructor_without_options (line 78) | def test_constructor_without_options(self):
    method test_constructor_with_query_skip_limit (line 89) | def test_constructor_with_query_skip_limit(self):
    method test_constructor_with_query_skip_limit_options_skip_limit (line 100) | def test_constructor_with_query_skip_limit_options_skip_limit(self):
    method test_key_value_access_is_not_supported (line 111) | def test_key_value_access_is_not_supported(self):
    method test_key_value_slicing_is_not_supported (line 120) | def test_key_value_slicing_is_not_supported(self):
    method test_get_item_by_index (line 130) | def test_get_item_by_index(self):
    method test_get_item_by_index_using_skip_limit (line 144) | def test_get_item_by_index_using_skip_limit(self):
    method test_get_item_by_index_using_limit (line 164) | def test_get_item_by_index_using_limit(self):
    method test_get_item_by_index_using_skip (line 183) | def test_get_item_by_index_using_skip(self):
    method test_get_item_by_negative_index (line 202) | def test_get_item_by_negative_index(self):
    method test_get_item_slice_no_start_no_stop (line 211) | def test_get_item_slice_no_start_no_stop(self):
    method test_get_item_invalid_index_slice (line 222) | def test_get_item_invalid_index_slice(self):
    method test_get_item_index_slice_using_start_stop (line 248) | def test_get_item_index_slice_using_start_stop(self):
    method test_get_item_index_slice_using_start_stop_limit (line 259) | def test_get_item_index_slice_using_start_stop_limit(self):
    method test_get_item_index_slice_using_start_stop_skip (line 275) | def test_get_item_index_slice_using_start_stop_skip(self):
    method test_get_item_index_slice_using_start_stop_limit_skip (line 291) | def test_get_item_index_slice_using_start_stop_limit_skip(self):
    method test_get_item_index_slice_using_start_only (line 308) | def test_get_item_index_slice_using_start_only(self):
    method test_get_item_index_slice_using_start_only_limit (line 318) | def test_get_item_index_slice_using_start_only_limit(self):
    method test_get_item_index_slice_using_start_only_skip (line 333) | def test_get_item_index_slice_using_start_only_skip(self):
    method test_get_item_index_slice_using_start_only_limit_skip (line 348) | def test_get_item_index_slice_using_start_only_limit_skip(self):
    method test_get_item_index_slice_using_stop_only (line 364) | def test_get_item_index_slice_using_stop_only(self):
    method test_get_item_index_slice_using_stop_only_limit (line 377) | def test_get_item_index_slice_using_stop_only_limit(self):
    method test_get_item_index_slice_using_stop_only_skip (line 395) | def test_get_item_index_slice_using_stop_only_skip(self):
    method test_get_item_index_slice_using_stop_only_limit_skip (line 410) | def test_get_item_index_slice_using_stop_only_limit_skip(self):
    method test_iteration_with_invalid_options (line 426) | def test_iteration_with_invalid_options(self):
    method test_iteration_invalid_page_size (line 436) | def test_iteration_invalid_page_size(self):
    method test_iteration_using_valid_page_size (line 451) | def test_iteration_using_valid_page_size(self):
    method test_iteration_using_default_page_size (line 475) | def test_iteration_using_default_page_size(self):
    method test_iteration_no_data (line 488) | def test_iteration_no_data(self):

FILE: tests/unit/query_tests.py
  class QueryTests (line 36) | class QueryTests(UnitTestDbBase):
    method setUp (line 41) | def setUp(self):
    method tearDown (line 48) | def tearDown(self):
    method test_constructor_with_kwargs (line 55) | def test_constructor_with_kwargs(self):
    method test_constructor_without_kwargs (line 64) | def test_constructor_without_kwargs(self):
    method test_retrieve_query_url (line 73) | def test_retrieve_query_url(self):
    method test_callable_with_invalid_argument (line 83) | def test_callable_with_invalid_argument(self):
    method test_callable_with_invalid_value_types (line 94) | def test_callable_with_invalid_value_types(self):
    method test_callable_without_selector (line 121) | def test_callable_without_selector(self):
    method test_callable_with_empty_selector (line 136) | def test_callable_with_empty_selector(self):
    method test_callable_executes_query (line 151) | def test_callable_executes_query(self):
    method test_custom_result_context_manager (line 170) | def test_custom_result_context_manager(self):

FILE: tests/unit/replicator_mock_tests.py
  class ReplicatorDocumentValidationMockTests (line 31) | class ReplicatorDocumentValidationMockTests(unittest.TestCase):
    method setUp (line 36) | def setUp(self):
    method setUpClientMocks (line 48) | def setUpClientMocks(self, admin_party=False, iam_api_key=None):
    method test_using_admin_party_source_and_target (line 73) | def test_using_admin_party_source_and_target(self):
    method test_using_basic_auth_source_and_target (line 102) | def test_using_basic_auth_source_and_target(self):
    method test_using_iam_auth_source_and_target (line 141) | def test_using_iam_auth_source_and_target(self):

FILE: tests/unit/replicator_tests.py
  class CloudantReplicatorExceptionTests (line 41) | class CloudantReplicatorExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 46) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 54) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 62) | def test_raise_without_args(self):
    method test_raise_with_proper_code_and_args (line 71) | def test_raise_with_proper_code_and_args(self):
  class ReplicatorTests (line 80) | class ReplicatorTests(UnitTestDbBase):
    method setUp (line 85) | def setUp(self):
    method tearDown (line 100) | def tearDown(self):
    method test_constructor (line 127) | def test_constructor(self):
    method test_constructor_failure (line 138) | def test_constructor_failure(self):
    method test_replication_with_generated_id (line 158) | def test_replication_with_generated_id(self):
    method test_create_replication (line 167) | def test_create_replication(self):
    method test_timeout_in_create_replication (line 220) | def test_timeout_in_create_replication(self):
    method test_create_replication_without_a_source (line 263) | def test_create_replication_without_a_source(self):
    method test_create_replication_without_a_target (line 278) | def test_create_replication_without_a_target(self):
    method test_list_replications (line 293) | def test_list_replications(self):
    method test_retrieve_replication_state (line 312) | def test_retrieve_replication_state(self):
    method test_retrieve_replication_state_using_invalid_id (line 338) | def test_retrieve_replication_state_using_invalid_id(self):
    method test_stop_replication (line 355) | def test_stop_replication(self):
    method test_stop_replication_using_invalid_id (line 384) | def test_stop_replication_using_invalid_id(self):
    method test_follow_replication (line 399) | def test_follow_replication(self):

FILE: tests/unit/result_tests.py
  class ResultExceptionTests (line 30) | class ResultExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 35) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 43) | def test_raise_using_invalid_code(self):
    method test_raise_without_args (line 51) | def test_raise_without_args(self):
    method test_raise_without_insufficient_args (line 60) | def test_raise_without_insufficient_args(self):
    method test_raise_with_proper_code_and_args (line 70) | def test_raise_with_proper_code_and_args(self):
  class ResultTests (line 79) | class ResultTests(UnitTestDbBase):
    method setUp (line 84) | def setUp(self):
    method tearDown (line 93) | def tearDown(self):
    method test_constructor (line 100) | def test_constructor(self):
    method test_get_item_by_index (line 113) | def test_get_item_by_index(self):
    method test_get_item_by_index_using_skip_limit (line 128) | def test_get_item_by_index_using_skip_limit(self):
    method test_get_item_by_index_using_limit (line 143) | def test_get_item_by_index_using_limit(self):
    method test_get_item_by_index_using_skip (line 158) | def test_get_item_by_index_using_skip(self):
    method test_get_item_by_negative_index (line 173) | def test_get_item_by_negative_index(self):
    method test_get_item_by_key_using_invalid_options (line 182) | def test_get_item_by_key_using_invalid_options(self):
    method test_get_item_by_key (line 197) | def test_get_item_by_key(self):
    method test_get_item_by_missing_key (line 207) | def test_get_item_by_missing_key(self):
    method test_get_item_by_complex_key (line 216) | def test_get_item_by_complex_key(self):
    method test_get_item_by_integer_key (line 226) | def test_get_item_by_integer_key(self):
    method test_get_item_by_missing_integer_key (line 236) | def test_get_item_by_missing_integer_key(self):
    method test_get_item_slice_no_start_no_stop (line 244) | def test_get_item_slice_no_start_no_stop(self):
    method test_get_all_items (line 255) | def test_get_all_items(self):
    method test_get_item_invalid_index_slice (line 265) | def test_get_item_invalid_index_slice(self):
    method test_get_item_index_slice_using_start_stop (line 291) | def test_get_item_index_slice_using_start_stop(self):
    method test_get_item_index_slice_using_start_only (line 323) | def test_get_item_index_slice_using_start_only(self):
    method test_get_item_index_slice_using_stop_only (line 351) | def test_get_item_index_slice_using_stop_only(self):
    method test_get_item_key_slice_using_invalid_options (line 385) | def test_get_item_key_slice_using_invalid_options(self):
    method test_get_item_invalid_key_slice (line 410) | def test_get_item_invalid_key_slice(self):
    method test_get_item_key_slice_using_start_stop (line 426) | def test_get_item_key_slice_using_start_stop(self):
    method test_get_item_key_slice_start_greater_than_stop (line 477) | def test_get_item_key_slice_start_greater_than_stop(self):
    method test_get_item_key_slice_using_start_only (line 489) | def test_get_item_key_slice_using_start_only(self):
    method test_get_item_key_slice_using_stop_only (line 519) | def test_get_item_key_slice_using_stop_only(self):
    method test_iteration_with_invalid_options (line 567) | def test_iteration_with_invalid_options(self):
    method test_iteration_invalid_page_size (line 577) | def test_iteration_invalid_page_size(self):
    method test_iteration_using_valid_page_size (line 592) | def test_iteration_using_valid_page_size(self):
    method test_iteration_using_default_page_size (line 618) | def test_iteration_using_default_page_size(self):
    method test_iteration_no_data (line 631) | def test_iteration_no_data(self):
    method test_iteration_integer_keys (line 638) | def test_iteration_integer_keys(self):
    method test_iteration_pagination (line 645) | def test_iteration_pagination(self):

FILE: tests/unit/scheduler_tests.py
  class SchedulerTests (line 28) | class SchedulerTests(UnitTestDbBase):
    method setUp (line 30) | def setUp(self):
    method tearDown (line 37) | def tearDown(self):
    method test_scheduler_docs (line 44) | def test_scheduler_docs(self):
    method test_scheduler_doc (line 159) | def test_scheduler_doc(self):
    method test_scheduler_jobs (line 192) | def test_scheduler_jobs(self):

FILE: tests/unit/security_document_tests.py
  class SecurityDocumentTests (line 32) | class SecurityDocumentTests(UnitTestDbBase):
    method setUp (line 37) | def setUp(self):
    method tearDown (line 45) | def tearDown(self):
    method test_constructor (line 52) | def test_constructor(self):
    method test_document_url (line 60) | def test_document_url(self):
    method test_json (line 70) | def test_json(self):
    method test_fetch (line 81) | def test_fetch(self):
    method test_save (line 89) | def test_save(self):
    method test_context_manager (line 101) | def test_context_manager(self):

FILE: tests/unit/unit_t_db_base.py
  function skip_if_not_cookie_auth (line 73) | def skip_if_not_cookie_auth(f):
  function skip_if_iam (line 81) | def skip_if_iam(f):
  class UnitTestDbBase (line 88) | class UnitTestDbBase(unittest.TestCase):
    method setUpClass (line 94) | def setUpClass(cls):
    method tearDownClass (line 140) | def tearDownClass(cls):
    method setUp (line 171) | def setUp(self):
    method set_up_client (line 177) | def set_up_client(self, auto_connect=False, auto_renew=False, encoder=...
    method tearDown (line 250) | def tearDown(self):
    method db_set_up (line 256) | def db_set_up(self, partitioned=False):
    method db_tear_down (line 266) | def db_tear_down(self):
    method dbname (line 275) | def dbname(self, database_name='db'):
    method populate_db_with_documents (line 278) | def populate_db_with_documents(self, doc_count=100, **kwargs):
    method populate_db_with_partitioned_documents (line 286) | def populate_db_with_partitioned_documents(self, key_count, docs_per_p...
    method create_views (line 300) | def create_views(self):
    method create_search_index (line 345) | def create_search_index(self):
    method load_security_document_data (line 359) | def load_security_document_data(self):
    method create_db_updates (line 392) | def create_db_updates(self):
    method delete_db_updates (line 403) | def delete_db_updates(self):
    method is_couchdb_1x_version (line 412) | def is_couchdb_1x_version(self):

FILE: tests/unit/view_execution_tests.py
  class QueryParmExecutionTests (line 26) | class QueryParmExecutionTests(UnitTestDbBase):
    method setUp (line 31) | def setUp(self):
    method tearDown (line 40) | def tearDown(self):
    method test_descending_true (line 47) | def test_descending_true(self):
    method test_descending_false (line 64) | def test_descending_false(self):
    method test_endkey_int (line 81) | def test_endkey_int(self):
    method test_endkey_str (line 104) | def test_endkey_str(self):
    method test_endkey_complex (line 123) | def test_endkey_complex(self):
    method test_endkey_docid (line 142) | def test_endkey_docid(self):
    method test_group_true (line 167) | def test_group_true(self):
    method test_group_false (line 185) | def test_group_false(self):
    method test_group_level (line 196) | def test_group_level(self):
    method test_include_docs_true (line 211) | def test_include_docs_true(self):
    method test_include_docs_false (line 238) | def test_include_docs_false(self):
    method test_inclusive_end_true (line 253) | def test_inclusive_end_true(self):
    method test_inclusive_end_false (line 270) | def test_inclusive_end_false(self):
    method test_key_int (line 287) | def test_key_int(self):
    method test_key_str (line 307) | def test_key_str(self):
    method test_key_complex (line 322) | def test_key_complex(self):
    method test_keys_int (line 337) | def test_keys_int(self):
    method test_keys_str (line 361) | def test_keys_str(self):
    method test_keys_complex (line 378) | def test_keys_complex(self):
    method test_limit (line 395) | def test_limit(self):
    method test_reduce_true (line 412) | def test_reduce_true(self):
    method test_reduce_false (line 423) | def test_reduce_false(self):
    method test_skip (line 446) | def test_skip(self):
    method test_stale_ok (line 463) | def test_stale_ok(self):
    method test_stale_update_after (line 476) | def test_stale_update_after(self):
    method test_stable_true (line 489) | def test_stable_true(self):
    method test_stable_update_lazy (line 503) | def test_stable_update_lazy(self):
    method test_stable_update_true (line 516) | def test_stable_update_true(self):
    method test_startkey_int (line 529) | def test_startkey_int(self):
    method test_startkey_str (line 552) | def test_startkey_str(self):
    method test_startkey_complex (line 571) | def test_startkey_complex(self):
    method test_startkey_docid (line 590) | def test_startkey_docid(self):

FILE: tests/unit/view_tests.py
  class CodeTests (line 39) | class CodeTests(unittest.TestCase):
    method test_constructor (line 44) | def test_constructor(self):
  class CloudantViewExceptionTests (line 53) | class CloudantViewExceptionTests(unittest.TestCase):
    method test_raise_without_code (line 58) | def test_raise_without_code(self):
    method test_raise_using_invalid_code (line 66) | def test_raise_using_invalid_code(self):
    method test_raise_with_proper_code (line 74) | def test_raise_with_proper_code(self):
  class ViewTests (line 83) | class ViewTests(UnitTestDbBase):
    method setUp (line 88) | def setUp(self):
    method tearDown (line 95) | def tearDown(self):
    method test_constructor (line 102) | def test_constructor(self):
    method test_map_setter (line 133) | def test_map_setter(self):
    method test_map_getter (line 146) | def test_map_getter(self):
    method test_reduce_setter (line 157) | def test_reduce_setter(self):
    method test_reduce_getter (line 167) | def test_reduce_getter(self):
    method test_retrieve_view_url (line 178) | def test_retrieve_view_url(self):
    method test_get_view_callable_raw_json (line 189) | def test_get_view_callable_raw_json(self):
    method test_post_view_callable_raw_json (line 210) | def test_post_view_callable_raw_json(self):
    method test_post_view_callable_raw_json_multiple_params (line 234) | def test_post_view_callable_raw_json_multiple_params(self):
    method test_view_callable_view_result (line 258) | def test_view_callable_view_result(self):
    method test_view_callable_with_non_existing_view (line 280) | def test_view_callable_with_non_existing_view(self):
    method test_custom_result_context_manager (line 298) | def test_custom_result_context_manager(self):
  class QueryIndexViewTests (line 322) | class QueryIndexViewTests(unittest.TestCase):
    method setUp (line 329) | def setUp(self):
    method test_constructor (line 345) | def test_constructor(self):
    method test_map_getter (line 359) | def test_map_getter(self):
    method test_map_setter (line 369) | def test_map_setter(self):
    method test_map_setter_failure (line 380) | def test_map_setter_failure(self):
    method test_reduce_getter (line 393) | def test_reduce_getter(self):
    method test_reduce_setter (line 400) | def test_reduce_setter(self):
    method test_reduce_setter_failure (line 408) | def test_reduce_setter_failure(self):
    method test_callable_disabled (line 417) | def test_callable_disabled(self):
    method test_custom_result_disabled (line 431) | def test_custom_result_disabled(self):
Condensed preview — 93 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,028K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 618,
    "preview": "Please [read these guidelines](http://ibm.biz/cdt-issue-guide) before opening an issue.\n\n<!-- Issues will be CLOSED IMME"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1826,
    "preview": "<!--\nThanks for your hard work, please ensure all items are complete before opening.\n-->\n## Checklist\n\n- [ ] Tick to sig"
  },
  {
    "path": ".gitignore",
    "chars": 591,
    "preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Emacs temp files\n*~\n\\#*\n\\.\\#*\n\n# "
  },
  {
    "path": ".travis.yml",
    "chars": 817,
    "preview": "sudo: required\n\nlanguage: python\n\npython:\n  - \"3.8\"\n\nenv:\n  - ADMIN_PARTY=true COUCHDB_VERSION=2.3.1\n  - ADMIN_PARTY=fal"
  },
  {
    "path": "CHANGES.md",
    "chars": 15874,
    "preview": "# UNRELEASED\n- [DEPRECATED] This library is end-of-life and no longer supported.\n\n# 2.15.0 (2021-08-26)\n- [NEW] Override"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3723,
    "preview": "# Contributing\n\n## Issues\n\nPlease [read these guidelines](http://ibm.biz/cdt-issue-guide) before opening an issue.\nIf yo"
  },
  {
    "path": "DCO1.1.txt",
    "chars": 1554,
    "preview": "Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Lette"
  },
  {
    "path": "Jenkinsfile",
    "chars": 2394,
    "preview": "def getEnvForSuite(suiteName) {\n  // Base environment variables\n  def envVars = [\n    \"DB_URL=${SDKS_TEST_SERVER_URL}\",\n"
  },
  {
    "path": "LICENSE",
    "chars": 11323,
    "preview": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licens"
  },
  {
    "path": "MANIFEST.in",
    "chars": 41,
    "preview": "include requirements.txt VERSION LICENSE\n"
  },
  {
    "path": "MIGRATION.md",
    "chars": 11426,
    "preview": "# Migrating to the `cloudant-python-sdk` library\nThis document is to assist in migrating from the `python-cloudant` (mod"
  },
  {
    "path": "README.md",
    "chars": 5046,
    "preview": "# :warning: NO LONGER MAINTAINED :warning:\n\n**This library is end-of-life and no longer supported.**\n\nThis repository wi"
  },
  {
    "path": "VERSION",
    "chars": 16,
    "preview": "2.15.1-SNAPSHOT\n"
  },
  {
    "path": "docs/Makefile",
    "chars": 7493,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/adapters.rst",
    "chars": 154,
    "preview": "adapters\n========\n\n.. automodule:: cloudant.adapters\n    :members:\n    :undoc-members:\n    :special-members: __getitem__"
  },
  {
    "path": "docs/client.rst",
    "chars": 164,
    "preview": "client\n======\n\n.. automodule:: cloudant.client\n    :members:\n    :undoc-members:\n    :special-members: __getitem__, __de"
  },
  {
    "path": "docs/cloudant.rst",
    "chars": 181,
    "preview": "Cloudant client library API\n===========================\n\n.. automodule:: cloudant\n    :members:\n    :undoc-members:\n    "
  },
  {
    "path": "docs/compatibility.rst",
    "chars": 523,
    "preview": "Compatibility\n=============\n\nThis library can be used with the following databases\n\n* `IBM Cloudant® Database-as-a-Servi"
  },
  {
    "path": "docs/conf.py",
    "chars": 9646,
    "preview": "# -*- coding: utf-8 -*-\n#\n# Cloudant Python client library documentation build configuration file, created by\n# sphinx-q"
  },
  {
    "path": "docs/database.rst",
    "chars": 154,
    "preview": "database\n========\n\n.. automodule:: cloudant.database\n    :members:\n    :undoc-members:\n    :special-members: __getitem__"
  },
  {
    "path": "docs/design_document.rst",
    "chars": 158,
    "preview": "design_document\n===============\n\n.. automodule:: cloudant.design_document\n    :members:\n    :exclude-members: info\n    :"
  },
  {
    "path": "docs/document.rst",
    "chars": 110,
    "preview": "document\n========\n\n.. automodule:: cloudant.document\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/error.rst",
    "chars": 101,
    "preview": "error\n=====\n\n.. automodule:: cloudant.error\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/feed.rst",
    "chars": 98,
    "preview": "feed\n====\n\n.. automodule:: cloudant.feed\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/getting_started.rst",
    "chars": 23602,
    "preview": "###############\nGetting started\n###############\n\nNow it's time to begin doing some work with Cloudant and Python.  For w"
  },
  {
    "path": "docs/index.rst",
    "chars": 53,
    "preview": "This library is end-of-life and no longer supported.\n"
  },
  {
    "path": "docs/make.bat",
    "chars": 7286,
    "preview": "@ECHO OFF\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sphinx-build\r\n)\r\n"
  },
  {
    "path": "docs/module_index.rst",
    "chars": 101,
    "preview": "index\n=====\n\n.. automodule:: cloudant.index\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/modules.rst",
    "chars": 207,
    "preview": "Modules\n=======\n\n.. toctree::\n   :maxdepth: 2\n\n   client\n   database\n   document\n   design_document\n   security_document"
  },
  {
    "path": "docs/query.rst",
    "chars": 132,
    "preview": "query\n=====\n\n.. automodule:: cloudant.query\n    :members:\n    :undoc-members:\n    :special-members: __call__\n    :show-i"
  },
  {
    "path": "docs/replicator.rst",
    "chars": 116,
    "preview": "replicator\n==========\n\n.. automodule:: cloudant.replicator\n    :members:\n    :undoc-members:\n    :show-inheritance:\n"
  },
  {
    "path": "docs/result.rst",
    "chars": 183,
    "preview": "result\n======\n\n.. automodule:: cloudant.result\n    :members:\n    :undoc-members:\n    :special-members: __getitem__, __it"
  },
  {
    "path": "docs/security_document.rst",
    "chars": 137,
    "preview": "security_document\n=================\n\n.. automodule:: cloudant.security_document\n    :members:\n    :undoc-members:\n    :s"
  },
  {
    "path": "docs/view.rst",
    "chars": 129,
    "preview": "view\n====\n\n.. automodule:: cloudant.view\n    :members:\n    :undoc-members:\n    :special-members: __call__\n    :show-inhe"
  },
  {
    "path": "pylintrc",
    "chars": 12221,
    "preview": "[MASTER]\n\n# Specify a configuration file.\nrcfile=pylintrc\n\n# Python code to execute, usually for sys.path manipulation s"
  },
  {
    "path": "requirements.txt",
    "chars": 25,
    "preview": "requests >=2.7.0, <3.0.0\n"
  },
  {
    "path": "setup.py",
    "chars": 2118,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "src/cloudant/_2to3.py",
    "chars": 3644,
    "preview": "# Copyright (c) 2016, 2017 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "src/cloudant/__init__.py",
    "chars": 8045,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015, 2018 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/_client_session.py",
    "chars": 9147,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015, 2019 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "src/cloudant/_common_util.py",
    "chars": 13587,
    "preview": "#!/usr/bin/env python\n# Copyright © 2015, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Ver"
  },
  {
    "path": "src/cloudant/_messages.py",
    "chars": 6353,
    "preview": "#!/usr/bin/env python\n# Copyright © 2016, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Ver"
  },
  {
    "path": "src/cloudant/adapters.py",
    "chars": 2066,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# Copyright © 2016 IBM Corp. All rights reserved.\n#\n# Licensed under the A"
  },
  {
    "path": "src/cloudant/client.py",
    "chars": 34876,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "src/cloudant/database.py",
    "chars": 67770,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "src/cloudant/design_document.py",
    "chars": 28354,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/document.py",
    "chars": 18595,
    "preview": "#!/usr/bin/env python\n# Copyright © 2015, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Ver"
  },
  {
    "path": "src/cloudant/error.py",
    "chars": 7385,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015, 2016 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/feed.py",
    "chars": 10327,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015, 2018 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/index.py",
    "chars": 9146,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/query.py",
    "chars": 9389,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/replicator.py",
    "chars": 8692,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "src/cloudant/result.py",
    "chars": 24315,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "src/cloudant/scheduler.py",
    "chars": 3228,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version"
  },
  {
    "path": "src/cloudant/security_document.py",
    "chars": 5013,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "src/cloudant/view.py",
    "chars": 14295,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "test-requirements.txt",
    "chars": 61,
    "preview": "mock==1.3.0\nnose\nsphinx\nsphinx_rtd_theme\npylint==2.5.2\nflaky\n"
  },
  {
    "path": "tests/__init__.py",
    "chars": 1113,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/credentials.py",
    "chars": 3198,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/__init__.py",
    "chars": 668,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/changes_test.py",
    "chars": 4075,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/document_test.py",
    "chars": 1701,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/end_to_end_example_test.py",
    "chars": 4989,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/iter_test.py",
    "chars": 3087,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/integration/replicator_test.py",
    "chars": 9897,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/unit/__init__.py",
    "chars": 648,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/unit/_test_util.py",
    "chars": 817,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2017 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version"
  },
  {
    "path": "tests/unit/adapter_tests.py",
    "chars": 2163,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n# Copyright © 2016 IBM Corp. All rights reserved.\n#\n# Licensed under the A"
  },
  {
    "path": "tests/unit/auth_renewal_tests.py",
    "chars": 5578,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/changes_tests.py",
    "chars": 20622,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/client_tests.py",
    "chars": 51476,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/cloud_foundry_tests.py",
    "chars": 11516,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/database_partition_tests.py",
    "chars": 5032,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2019 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version"
  },
  {
    "path": "tests/unit/database_tests.py",
    "chars": 68335,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2019 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/db_updates_tests.py",
    "chars": 20437,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/design_document_tests.py",
    "chars": 78104,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2020 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/document_tests.py",
    "chars": 34667,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/document_validation_tests.py",
    "chars": 42670,
    "preview": "#!/usr/bin/env python\n# Copyright © 2021 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version 2"
  },
  {
    "path": "tests/unit/fixtures/__init__.py",
    "chars": 692,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2015 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "tests/unit/iam_auth_tests.py",
    "chars": 15514,
    "preview": "#!/usr/bin/env python\n# Copyright (c) 2017, 2019 IBM. All rights reserved.\n#\n# Licensed under the Apache License, Versio"
  },
  {
    "path": "tests/unit/index_tests.py",
    "chars": 24510,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2020 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/infinite_feed_tests.py",
    "chars": 8916,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/param_translation_tests.py",
    "chars": 14374,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/query_result_tests.py",
    "chars": 21667,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/query_tests.py",
    "chars": 6037,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/replicator_mock_tests.py",
    "chars": 5926,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version"
  },
  {
    "path": "tests/unit/replicator_tests.py",
    "chars": 16410,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2020 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/result_tests.py",
    "chars": 28763,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/scheduler_tests.py",
    "chars": 11474,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, Version"
  },
  {
    "path": "tests/unit/security_document_tests.py",
    "chars": 3434,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/unit_t_db_base.py",
    "chars": 15071,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2020 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/view_execution_tests.py",
    "chars": 24111,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2016, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  },
  {
    "path": "tests/unit/view_tests.py",
    "chars": 15541,
    "preview": "#!/usr/bin/env python\n# Copyright (C) 2015, 2018 IBM Corp. All rights reserved.\n#\n# Licensed under the Apache License, V"
  }
]

About this extraction

This page contains the full source code of the cloudant/python-cloudant GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 93 files (964.7 KB), approximately 224.4k tokens, and a symbol index with 1203 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!