# 3. Basic CouchDB API: couchdb.client

Python client API for CouchDB.

    >>> server = Server()
    >>> db = server.create('python-tests')
    >>> doc_id, doc_rev = db.save({'type': 'Person', 'name': 'John Doe'})
    >>> doc = db[doc_id]
    >>> doc['type']
    u'Person'
    >>> doc['name']
    u'John Doe'
    >>> del db[doc.id]
    >>> doc.id in db
    False

    >>> del server['python-tests']

## 3.1. Server

class `couchdb.client.``Server`(url='http://localhost:5984/', full_commit=True, session=None)

  Representation of a CouchDB server.

      >>> server = Server()

  This class behaves like a dictionary of databases. For example, to get a list of database names on the server, you can simply iterate over the server object.

  New databases can be created using the create method:

      >>> db = server.create('python-tests')
      >>> db
      <Database 'python-tests'>

  You can access existing databases using item access, specifying the database name as the key:

      >>> db = server['python-tests']
      >>> db.name
      'python-tests'

  Databases can be deleted using a `del` statement:

      >>> del server['python-tests']

  `config`()

    The configuration of the CouchDB server.

    The configuration is represented as a nested dictionary of sections and options from the configuration files of the server, or the default values for options that are not explicitly configured.

    Return type: | dict

  `create`(name)

    Create a new database with the given name.

    Parameters: | name – the name of the database
    Returns: | a Database object representing the created database
    Return type: | Database
    Raises PreconditionFailed:
    | if a database with that name already exists

  `delete`(name)

    Delete the database with the specified name.

    Parameters: | name – the name of the database
    Raises ResourceNotFound:
    | if a database with that name does not exist
    Since: | 0.6

  `replicate`(source, target, **options)

    Replicate changes from the source database to the target database.

    Parameters:

    - source – URL of the source database
    - target – URL of the target database
    - options – optional replication args, e.g. continuous=True

  `stats`(name=None)

    Server statistics.

    Parameters: | name – name of single statistic, e.g. httpd/requests (None – return all statistics)

  `tasks`()

    A list of tasks currently active on the server.

  `uuids`(count=None)

    Retrieve a batch of uuids

    Parameters: | count – a number of uuids to fetch (None – get as many as the server sends)
    Returns: | a list of uuids

  `version`()

    The version string of the CouchDB server.

    Note that this results in a request being made, and can also be used to check for the availability of the server.

    Return type: | unicode

## 3.2. Database

class `couchdb.client.``Database`(url, name=None, session=None)

  Representation of a database on a CouchDB server.

      >>> server = Server()
      >>> db = server.create('python-tests')

  New documents can be added to the database using the save() method:

      >>> doc_id, doc_rev = db.save({'type': 'Person', 'name': 'John Doe'})

  This class provides a dictionary-like interface to databases: documents are retrieved by their ID using item access

      >>> doc = db[doc_id]
      >>> doc
      <Document u'...'@... {...}>

  Documents are represented as instances of the Row class, which is basically just a normal dictionary with the additional attributes `id` and `rev`:

      >>> doc.id, doc.rev
      (u'...', ...)
      >>> doc['type']
      u'Person'
      >>> doc['name']
      u'John Doe'

  To update an existing document, you use item access, too:

      >>> doc['name'] = 'Mary Jane'
      >>> db[doc.id] = doc

  The save() method creates a document with a random ID generated by CouchDB (which is not recommended). If you want to explicitly specify the ID, you’d use item access just as with updating:

      >>> db['JohnDoe'] = {'type': 'person', 'name': 'John Doe'}

      >>> 'JohnDoe' in db
      True
      >>> len(db)
      2

      >>> del server['python-tests']

  `changes`(**opts)

    Retrieve a changes feed from the database.

    Parameters: | opts – optional query string parameters
    Returns: | an iterable over change notification dicts

  `cleanup`()

    Clean up old design document indexes.

    Remove all unused index files from the database storage area.

    Returns: | a boolean to indicate successful cleanup initiation
    Return type: | bool

  `commit`()

    If the server is configured to delay commits, or previous requests used the special `X-Couch-Full-Commit: false` header to disable immediate commits, this method can be used to ensure that any non-committed changes are committed to physical storage.

  `compact`(ddoc=None)

    Compact the database or a design document’s index.

    Without an argument, this will try to prune all old revisions from the database. With an argument, it will compact the index cache for all views in the design document specified.

    Returns: | a boolean to indicate whether the compaction was initiated successfully
    Return type: | bool

  `copy`(src, dest)

    Copy the given document to create a new document.

    Parameters:

    - src – the ID of the document to copy, or a dictionary or Document object representing the source document.
    - dest – either the destination document ID as string, or a dictionary or Document instance of the document that should be overwritten.

    Returns: | the new revision of the destination document
    Return type: | str
    Since: | 0.6

  `create`(data)

    Create a new document in the database with a random ID that is generated by the server.

    Note that it is generally better to avoid the create() method and instead generate document IDs on the client side. This is due to the fact that the underlying HTTP `POST` method is not idempotent, and an automatic retry due to a problem somewhere on the networking stack may cause multiple documents being created in the database.

    To avoid such problems you can generate a UUID on the client side. Python (since version 2.5) comes with a `uuid` module that can be used for this:

        from uuid import uuid4
        doc_id = uuid4().hex
        db[doc_id] = {'type': 'person', 'name': 'John Doe'}

    Parameters: | data – the data to store in the document
    Returns: | the ID of the created document
    Return type: | unicode

  `delete`(doc)

    Delete the given document from the database.

    Use this method in preference over `__del__` to ensure you’re deleting the revision that you had previously retrieved. In the case the document has been updated since it was retrieved, this method will raise a ResourceConflict exception.

        >>> server = Server()
        >>> db = server.create('python-tests')

        >>> doc = dict(type='Person', name='John Doe')
        >>> db['johndoe'] = doc
        >>> doc2 = db['johndoe']
        >>> doc2['age'] = 42
        >>> db['johndoe'] = doc2
        >>> db.delete(doc)
        Traceback (most recent call last):
          ...
        ResourceConflict: (u'conflict', u'Document update conflict.')
        Traceback (most recent call last):
          ...
        ResourceConflict: (u'conflict', u'Document update conflict.')

        >>> del server['python-tests']

    Parameters: | doc – a dictionary or Document object holding the document data
    Raises ResourceConflict:
    | if the document was updated in the database
    Since: | 0.4.1

  `delete_attachment`(doc, filename)

    Delete the specified attachment.

    Note that the provided doc is required to have a `_rev` field. Thus, if the doc is based on a view row, the view row would need to include the `_rev` field.

    Parameters:

    - doc – the dictionary or Document object representing the document that the attachment belongs to
    - filename – the name of the attachment file

    Since: | 0.4.1

  `get`(id, default=None, **options)

    Return the document with the specified ID.

    Parameters:

    - id – the document ID
    - default – the default value to return when the document is not found

    Returns: | a Row object representing the requested document, or None if no document with the ID was found
    Return type: | Document

  `get_attachment`(id_or_doc, filename, default=None)

    Return an attachment from the specified doc id and filename.

    Parameters:

    - id_or_doc – either a document ID or a dictionary or Document object representing the document that the attachment belongs to
    - filename – the name of the attachment file
    - default – default value to return when the document or attachment is not found

    Returns: | a file-like object with read and close methods, or the value of the default argument if the attachment is not found
    Since: | 0.4.1

  `info`(ddoc=None)

    Return information about the database or design document as a dictionary.

    Without an argument, returns database information. With an argument, return information for the given design document.

    The returned dictionary exactly corresponds to the JSON response to a `GET` request on the database or design document’s info URI.

    Returns: | a dictionary of database properties
    Return type: | `dict`
    Since: | 0.4

  `iterview`(name, batch, wrapper=None, **options)

    Iterate the rows in a view, fetching rows in batches and yielding one row at a time.

    Since the view’s rows are fetched in batches any rows emitted for documents added, changed or deleted between requests may be missed or repeated.

    Parameters:

    - name – the name of the view; for custom views, use the format `design_docid/viewname`, that is, the document ID of the design document and the name of the view, separated by a slash.
    - batch – number of rows to fetch per HTTP request.
    - wrapper – an optional callable that should be used to wrap the result rows
    - options – optional query string parameters

    Returns: | row generator

  `list`(name, view, **options)

    Format a view using a ‘list’ function.

    Parameters:

    - name – the name of the list function in the format `designdoc/listname`
    - view – the name of the view in the format `designdoc/viewname`
    - options – optional query string parameters

    Returns: | (headers, body) tuple, where headers is a dict of headers returned from the list function and body is a readable file-like instance

  `name`

    The name of the database.

    Note that this may require a request to the server unless the name has already been cached by the info() method.

    Return type: | basestring

  `purge`(docs)

    Perform purging (complete removing) of the given documents.

    Uses a single HTTP request to purge all given documents. Purged documents do not leave any meta-data in the storage and are not replicated.

  `put_attachment`(doc, content, filename=None, content_type=None)

    Create or replace an attachment.

    Note that the provided doc is required to have a `_rev` field. Thus, if the doc is based on a view row, the view row would need to include the `_rev` field.

    Parameters:

    - doc – the dictionary or Document object representing the document that the attachment should be added to
    - content – the content to upload, either a file-like object or a string
    - filename – the name of the attachment file; if omitted, this function tries to get the filename from the file-like object passed as the content argument value
    - content_type – content type of the attachment; if omitted, the MIME type is guessed based on the file name extension

    Since: | 0.4.1

  `query`(map_fun, reduce_fun=None, language='javascript', wrapper=None, **options)

    Execute an ad-hoc query (a “temp view”) against the database.

        >>> server = Server()
        >>> db = server.create('python-tests')
        >>> db['johndoe'] = dict(type='Person', name='John Doe')
        >>> db['maryjane'] = dict(type='Person', name='Mary Jane')
        >>> db['gotham'] = dict(type='City', name='Gotham City')
        >>> map_fun = '''function(doc) {
        ...     if (doc.type == 'Person')
        ...         emit(doc.name, null);
        ... }'''
        >>> for row in db.query(map_fun):
        ...     print(row.key)
        John Doe
        Mary Jane

        >>> for row in db.query(map_fun, descending=True):
        ...     print(row.key)
        Mary Jane
        John Doe

        >>> for row in db.query(map_fun, key='John Doe'):
        ...     print(row.key)
        John Doe

        >>> del server['python-tests']

    Parameters:

    - map_fun – the code of the map function
    - reduce_fun – the code of the reduce function (optional)
    - language – the language of the functions, to determine which view server to use
    - wrapper – an optional callable that should be used to wrap the result rows
    - options – optional query string parameters

    Returns: | the view reults
    Return type: | ViewResults

  `revisions`(id, **options)

    Return all available revisions of the given document.

    Parameters: | id – the document ID
    Returns: | an iterator over Document objects, each a different revision, in reverse chronological order, if any were found

  `save`(doc, **options)

    Create a new document or update an existing document.

    If doc has no _id then the server will allocate a random ID and a new document will be created. Otherwise the doc’s _id will be used to identity the document to create or update. Trying to update an existing document with an incorrect _rev will raise a ResourceConflict exception.

    Note that it is generally better to avoid saving documents with no _id and instead generate document IDs on the client side. This is due to the fact that the underlying HTTP `POST` method is not idempotent, and an automatic retry due to a problem somewhere on the networking stack may cause multiple documents being created in the database.

    To avoid such problems you can generate a UUID on the client side. Python (since version 2.5) comes with a `uuid` module that can be used for this:

        from uuid import uuid4
        doc = {'_id': uuid4().hex, 'type': 'person', 'name': 'John Doe'}
        db.save(doc)

    Parameters:

    - doc – the document to store
    - options – optional args, e.g. batch=’ok’

    Returns: | (id, rev) tuple of the save document
    Return type: | tuple

  `show`(name, docid=None, **options)

    Call a ‘show’ function.

    Parameters:

    - name – the name of the show function in the format `designdoc/showname`
    - docid – optional ID of a document to pass to the show function.
    - options – optional query string parameters

    Returns: | (headers, body) tuple, where headers is a dict of headers returned from the show function and body is a readable file-like instance

  `update`(documents, **options)

    Perform a bulk update or insertion of the given documents using a single HTTP request.

        >>> server = Server()
        >>> db = server.create('python-tests')
        >>> for doc in db.update([
        ...     Document(type='Person', name='John Doe'),
        ...     Document(type='Person', name='Mary Jane'),
        ...     Document(type='City', name='Gotham City')
        ... ]):
        ...     print(repr(doc))
        (True, u'...', u'...')
        (True, u'...', u'...')
        (True, u'...', u'...')

        >>> del server['python-tests']

    The return value of this method is a list containing a tuple for every element in the documents sequence. Each tuple is of the form `(success, docid, rev_or_exc)`, where `success` is a boolean indicating whether the update succeeded, `docid` is the ID of the document, and `rev_or_exc` is either the new document revision, or an exception instance (e.g. ResourceConflict) if the update failed.

    If an object in the documents list is not a dictionary, this method looks for an `items()` method that can be used to convert the object to a dictionary. Effectively this means you can also use this method with mapping.Document objects.

    Parameters: | documents – a sequence of dictionaries or Document objects, or objects providing a `items()` method that can be used to convert them to a dictionary
    Returns: | an iterable over the resulting documents
    Return type: | `list`
    Since: | version 0.2

  `update_doc`(name, docid=None, **options)

    Calls server side update handler.

    Parameters:

    - name – the name of the update handler function in the format `designdoc/updatename`.
    - docid – optional ID of a document to pass to the update handler.
    - options – optional query string parameters.

    Returns: | (headers, body) tuple, where headers is a dict of headers returned from the list function and body is a readable file-like instance

  `view`(name, wrapper=None, **options)

    Execute a predefined view.

        >>> server = Server()
        >>> db = server.create('python-tests')
        >>> db['gotham'] = dict(type='City', name='Gotham City')

        >>> for row in db.view('_all_docs'):
        ...     print(row.id)
        gotham

        >>> del server['python-tests']

    Parameters:

    - name – the name of the view; for custom views, use the format `design_docid/viewname`, that is, the document ID of the design document and the name of the view, separated by a slash
    - wrapper – an optional callable that should be used to wrap the result rows
    - options – optional query string parameters

    Returns: | the view results
    Return type: | ViewResults

## 3.3. Document

class `couchdb.client.``Document`

  Representation of a document in the database.

  This is basically just a dictionary with the two additional properties id and rev, which contain the document ID and revision, respectively.

  `id`

    The document ID.

    Return type: | basestring

  `rev`

    The document revision.

    Return type: | basestring

## 3.4. ViewResults

class `couchdb.client.``ViewResults`(view, options)

  Representation of a parameterized view (either permanent or temporary) and the results it produces.

  This class allows the specification of `key`, `startkey`, and `endkey` options using Python slice notation.

      >>> server = Server()
      >>> db = server.create('python-tests')
      >>> db['johndoe'] = dict(type='Person', name='John Doe')
      >>> db['maryjane'] = dict(type='Person', name='Mary Jane')
      >>> db['gotham'] = dict(type='City', name='Gotham City')
      >>> map_fun = '''function(doc) {
      ...     emit([doc.type, doc.name], doc.name);
      ... }'''
      >>> results = db.query(map_fun)

  At this point, the view has not actually been accessed yet. It is accessed as soon as it is iterated over, its length is requested, or one of its rows, total_rows, or offset properties are accessed:

      >>> len(results)
      3

  You can use slices to apply `startkey` and/or `endkey` options to the view:

      >>> people = results[['Person']:['Person','ZZZZ']]
      >>> for person in people:
      ...     print(person.value)
      John Doe
      Mary Jane
      >>> people.total_rows, people.offset
      (3, 1)

  Use plain indexed notation (without a slice) to apply the `key` option. Note that as CouchDB makes no claim that keys are unique in a view, this can still return multiple rows:

      >>> list(results[['City', 'Gotham City']])
      [<Row id=u'gotham', key=[u'City', u'Gotham City'], value=u'Gotham City'>]

      >>> del server['python-tests']

  `offset`

    The offset of the results from the first row in the view.

    This value is 0 for reduce views.

    Return type: | int

  `rows`

    The list of rows returned by the view.

    Return type: | list

  `total_rows`

    The total number of rows in this view.

    This value is None for reduce views.

    Return type: | int or `NoneType` for reduce views

  `update_seq`

    The database update sequence that the view reflects.

    The update sequence is included in the view result only when it is explicitly requested using the update_seq=true query option. Otherwise, the value is None.

    Return type: | int or NoneType depending on the query options

## 3.5. Row

class `couchdb.client.``Row`

  Representation of a row as returned by database views.

  `doc`

    The associated document for the row. This is only present when the view was accessed with `include_docs=True` as a query parameter, otherwise this property will be None.

  `id`

    The associated Document ID if it exists. Returns None when it doesn’t (reduce results).