Cloudant Python Client Library
The `cloudant` Python client library provides a convenient interface for interacting with IBM Cloudant and Apache CouchDB databases. It allows developers to perform common database operations such as creating/deleting databases, managing documents, querying views, and using Cloudant-specific features. The library's last major release was 2.15.0 in August 2021, and it is currently in maintenance mode with no active development.
Common errors
-
NameError: name 'Cloudant' is not defined
cause The main Cloudant client class has not been imported.fixAdd `from cloudant.client import Cloudant` at the top of your script. -
cloudant.error.CloudantException: forbidden (reason='_reader access is required for this request')
cause The provided credentials (username/password or API key) do not have sufficient permissions to perform the requested operation on the database or instance.fixVerify that your Cloudant service credentials have the necessary read/write/admin permissions for the database or account you are trying to access. Check the IAM access policies in your IBM Cloud account. -
cloudant.error.CloudantException: not_found (reason='Database does not exist.')
cause The specified database name either does not exist or is misspelled. This can also occur if the user lacks permissions to list databases.fixDouble-check the database name for typos. Ensure the database exists or create it using `client.create_database('my_db_name')` if appropriate and your credentials have permission. -
TypeError: 'builtin_function_or_method' object is not subscriptable (when accessing document fields like `doc['field']`)
cause You might be trying to access document fields on a `Document` object that has not been properly initialized or fetched, or you're confusing it with a dict-like object.fixEnsure `doc` is a valid `Document` object, usually obtained by `my_database.create_document()` or `my_database[doc_id]`. If `doc` is a fresh `Document` object created without data or a fetch, it might not behave as expected until `save()` or `fetch()` is called.
Warnings
- deprecated The `cloudant` Python library is no longer under active development. As of October 2021, customers are encouraged to use the `python-couchdb` library instead, as it is actively maintained and provides a similar interface for CouchDB (and by extension, Cloudant).
- gotcha When updating an existing document, you must first fetch the document to obtain its `_rev` field. Cloudant/CouchDB requires this revision ID for all update and delete operations to prevent conflicts.
- gotcha The `Document` context manager (e.g., `with my_database['doc_id'] as doc:`) in versions prior to 2.12.0 could perform a remote save even if an uncaught exception occurred within the `with` block, leading to unintended data writes.
- breaking IAM (Identity and Access Management) authentication for IBM Cloudant was introduced in version 2.11.0. Older versions of the `cloudant` library will not support connecting to Cloudant instances that require IAM tokens.
Install
-
pip install cloudant
Imports
- Cloudant
from cloudant.client import Cloudant
- CloudantException
from cloudant.exceptions import CloudantException
from cloudant.error import CloudantException
- Result
from cloudant.result import Result
Quickstart
from cloudant.client import Cloudant
from cloudant.error import CloudantException
import os
# Configure credentials using environment variables
CLOUDANT_USERNAME = os.environ.get('CLOUDANT_USERNAME', 'testuser_example')
CLOUDANT_PASSWORD = os.environ.get('CLOUDANT_PASSWORD', 'testpass_example')
CLOUDANT_URL = os.environ.get('CLOUDANT_URL', 'http://localhost:5984') # Default for local CouchDB
client = None
try:
# Connect to the Cloudant service
client = Cloudant(CLOUDANT_USERNAME,
CLOUDANT_PASSWORD,
url=CLOUDANT_URL,
connect=True)
print(f"Connected to Cloudant/CouchDB at {CLOUDANT_URL}")
session = client.session()
print(f"User: {session['userCtx']['name']}")
db_name = 'my_sample_database'
# Attempt to create a database
my_database = client.create_database(db_name)
if my_database.exists():
print(f"Database '{db_name}' created or already exists.")
# Create a document
doc_data = {'name': 'Alice', 'city': 'New York', 'age': 30}
new_document = my_database.create_document(doc_data)
if new_document.exists():
print(f"Document created with ID: {new_document['_id']}")
print(f"Current document content: {new_document}")
# Fetch the document by ID
fetched_document = my_database[new_document['_id']]
print(f"Fetched document content: {fetched_document}")
# Update the document (requires fetching it first to get the _rev)
fetched_document['age'] = 31
fetched_document['status'] = 'active'
fetched_document.save()
print(f"Updated document content: {my_database[new_document['_id']]}")
# Delete the document
fetched_document.delete()
print(f"Document '{new_document['_id']}' deleted.")
# Delete the database
if client.get_database(db_name).exists():
client.delete_database(db_name)
print(f"Database '{db_name}' deleted.")
except CloudantException as ce:
print(f"Cloudant Error: {ce}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
if client:
client.disconnect()
print("Disconnected from Cloudant service.")