├── .gitignore ├── .hgignore ├── .hgtags ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── NOTICE ├── README.rst ├── THANKS ├── TODO.txt ├── couchdbkit ├── __init__.py ├── changes.py ├── client.py ├── consumer │ ├── __init__.py │ ├── base.py │ ├── ceventlet.py │ ├── cgevent.py │ └── sync.py ├── designer │ ├── __init__.py │ ├── fs.py │ └── macros.py ├── exceptions.py ├── ext │ ├── __init__.py │ ├── django │ │ ├── __init__.py │ │ ├── forms.py │ │ ├── loading.py │ │ ├── management │ │ │ ├── __init__.py │ │ │ └── commands │ │ │ │ ├── __init__.py │ │ │ │ ├── sync_couchdb.py │ │ │ │ ├── sync_finish_couchdb.py │ │ │ │ └── sync_prepare_couchdb.py │ │ ├── schema.py │ │ └── testrunner.py │ └── pylons │ │ ├── __init__.py │ │ ├── auth │ │ ├── __init__.py │ │ ├── adapters.py │ │ ├── basic.py │ │ └── model.py │ │ ├── commands.py │ │ ├── db.py │ │ └── test.py ├── external.py ├── loaders.py ├── resource.py ├── schema │ ├── __init__.py │ ├── base.py │ ├── properties.py │ ├── properties_proxy.py │ └── util.py ├── utils.py ├── version.py └── wsgi │ ├── __init__.py │ ├── handler.py │ └── proxy.py ├── debian ├── changelog ├── clean ├── compat ├── control ├── copyright ├── pyversions ├── rules ├── source │ └── format └── watch ├── distribute_setup.py ├── doc └── couchdbkit.org │ ├── buildweb.py │ ├── conf.py │ ├── htdocs │ ├── CNAME │ ├── blog │ │ ├── 1009-06-26-Couchdbkit-0.1.7.1.html │ │ ├── 2009-06-15-Couchdbkit-site-launched.html │ │ ├── 2009-06-16-Couchdbkit-site-launched.html │ │ ├── 2009-06-25-Couchdbkit-0.1.7-released.html │ │ ├── 2009-06-26-Couchdbkit-0.1.7.1.html │ │ ├── 2009-07-07-Couchdbkit-0.1.8.html │ │ ├── 2009-09-07-Couchdbkit-0.1.9.html │ │ ├── 2009-09-11-Couchdbkit-0.2.html │ │ ├── 2009-11-05-Couchdbkit-0.2.2.html │ │ ├── 2009-11-22-Couchdbkit-0.2.4.html │ │ ├── 2009-12-07-Couchdbkit-0.3.html │ │ ├── 2010-01-08-Couchdbkit-0.4.html │ │ ├── 2010-01-25-Couchdbkit-0.4.1.html │ │ ├── 2010-02-04-CouchdbKit-0.4..2.html │ │ ├── 2010-02-04-CouchdbKit-0.4.2.html │ │ ├── 2010-02-24-move-to-github.html │ │ ├── 2010-02-28-restkit-update.html │ │ ├── 2010-06-28-CouchdbKit-0.4.7.html │ │ ├── 2010-07-20-CouchdbKit-0.4.9.html │ │ ├── 2010-11-25-Couchdbkit-0.5.html │ │ ├── 2011-02-18-Couchdbkit-0.5.4.html │ │ ├── 2012-01-26-Couchdbkit-0.6.0.html │ │ ├── 2012-05-04-Couchdbkit-0.6.2.html │ │ ├── archives.html │ │ └── index.html │ ├── contact.html │ ├── css │ │ ├── couchdbkit.css │ │ └── print.css │ ├── docs │ │ ├── about.html │ │ ├── api │ │ │ ├── abc.ABCMeta-class.html │ │ │ ├── api-objects.txt │ │ │ ├── bool-class.html │ │ │ ├── class-tree.html │ │ │ ├── couchdbkit-module.html │ │ │ ├── couchdbkit-pysrc.html │ │ │ ├── couchdbkit.changes-module.html │ │ │ ├── couchdbkit.changes-pysrc.html │ │ │ ├── couchdbkit.changes.ChangesStream-class.html │ │ │ ├── couchdbkit.client-module.html │ │ │ ├── couchdbkit.client-pysrc.html │ │ │ ├── couchdbkit.client.Database-class.html │ │ │ ├── couchdbkit.client.Server-class.html │ │ │ ├── couchdbkit.client.ViewResults-class.html │ │ │ ├── couchdbkit.consumer-module.html │ │ │ ├── couchdbkit.consumer-pysrc.html │ │ │ ├── couchdbkit.consumer.Consumer-class.html │ │ │ ├── couchdbkit.consumer.base-module.html │ │ │ ├── couchdbkit.consumer.base-pysrc.html │ │ │ ├── couchdbkit.consumer.base.ConsumerBase-class.html │ │ │ ├── couchdbkit.consumer.ceventlet-module.html │ │ │ ├── couchdbkit.consumer.ceventlet-pysrc.html │ │ │ ├── couchdbkit.consumer.ceventlet.ChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.ceventlet.ContinuousChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.ceventlet.EventletConsumer-class.html │ │ │ ├── couchdbkit.consumer.ceventlet.LongPollChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.cgevent-module.html │ │ │ ├── couchdbkit.consumer.cgevent-pysrc.html │ │ │ ├── couchdbkit.consumer.cgevent.ChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.cgevent.ContinuousChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.cgevent.GeventConsumer-class.html │ │ │ ├── couchdbkit.consumer.cgevent.LongPollChangeConsumer-class.html │ │ │ ├── couchdbkit.consumer.sync-module.html │ │ │ ├── couchdbkit.consumer.sync-pysrc.html │ │ │ ├── couchdbkit.consumer.sync.SyncConsumer-class.html │ │ │ ├── couchdbkit.designer-module.html │ │ │ ├── couchdbkit.designer-pysrc.html │ │ │ ├── couchdbkit.designer.fs-module.html │ │ │ ├── couchdbkit.designer.fs-pysrc.html │ │ │ ├── couchdbkit.designer.fs.FSDoc-class.html │ │ │ ├── couchdbkit.designer.macros-module.html │ │ │ ├── couchdbkit.designer.macros-pysrc.html │ │ │ ├── couchdbkit.exceptions-module.html │ │ │ ├── couchdbkit.exceptions-pysrc.html │ │ │ ├── couchdbkit.exceptions.BadValueError-class.html │ │ │ ├── couchdbkit.exceptions.BulkSaveError-class.html │ │ │ ├── couchdbkit.exceptions.DesignerError-class.html │ │ │ ├── couchdbkit.exceptions.DocsPathNotFound-class.html │ │ │ ├── couchdbkit.exceptions.DuplicatePropertyError-class.html │ │ │ ├── couchdbkit.exceptions.InvalidAttachment-class.html │ │ │ ├── couchdbkit.exceptions.MacroError-class.html │ │ │ ├── couchdbkit.exceptions.MultipleResultsFound-class.html │ │ │ ├── couchdbkit.exceptions.NoResultFound-class.html │ │ │ ├── couchdbkit.exceptions.PreconditionFailed-class.html │ │ │ ├── couchdbkit.exceptions.ReservedWordError-class.html │ │ │ ├── couchdbkit.exceptions.ResourceConflict-class.html │ │ │ ├── couchdbkit.exceptions.ResourceNotFound-class.html │ │ │ ├── couchdbkit.exceptions.ViewServerError-class.html │ │ │ ├── couchdbkit.ext-module.html │ │ │ ├── couchdbkit.ext-pysrc.html │ │ │ ├── couchdbkit.ext.django-module.html │ │ │ ├── couchdbkit.ext.django-pysrc.html │ │ │ ├── couchdbkit.ext.django.forms-module.html │ │ │ ├── couchdbkit.ext.django.forms-pysrc.html │ │ │ ├── couchdbkit.ext.django.forms.BaseDocumentForm-class.html │ │ │ ├── couchdbkit.ext.django.forms.DocumentForm-class.html │ │ │ ├── couchdbkit.ext.django.forms.DocumentFormMetaClass-class.html │ │ │ ├── couchdbkit.ext.django.forms.DocumentFormOptions-class.html │ │ │ ├── couchdbkit.ext.django.loading-module.html │ │ │ ├── couchdbkit.ext.django.loading-pysrc.html │ │ │ ├── couchdbkit.ext.django.loading.CouchdbkitHandler-class.html │ │ │ ├── couchdbkit.ext.django.management-module.html │ │ │ ├── couchdbkit.ext.django.management-pysrc.html │ │ │ ├── couchdbkit.ext.django.management.commands-module.html │ │ │ ├── couchdbkit.ext.django.management.commands-pysrc.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_couchdb-module.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_couchdb-pysrc.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_couchdb.Command-class.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_finish_couchdb-module.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_finish_couchdb-pysrc.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_finish_couchdb.Command-class.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_prepare_couchdb-module.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_prepare_couchdb-pysrc.html │ │ │ ├── couchdbkit.ext.django.management.commands.sync_prepare_couchdb.Command-class.html │ │ │ ├── couchdbkit.ext.django.schema-module.html │ │ │ ├── couchdbkit.ext.django.schema-pysrc.html │ │ │ ├── couchdbkit.ext.django.schema.Document-class.html │ │ │ ├── couchdbkit.ext.django.schema.DocumentMeta-class.html │ │ │ ├── couchdbkit.ext.django.schema.Options-class.html │ │ │ ├── couchdbkit.ext.django.testrunner-module.html │ │ │ ├── couchdbkit.ext.django.testrunner-pysrc.html │ │ │ ├── couchdbkit.ext.django.testrunner.CouchDbKitTestSuiteRunner-class.html │ │ │ ├── couchdbkit.ext.pylons-module.html │ │ │ ├── couchdbkit.ext.pylons-pysrc.html │ │ │ ├── couchdbkit.ext.pylons.commands-module.html │ │ │ ├── couchdbkit.ext.pylons.commands-pysrc.html │ │ │ ├── couchdbkit.ext.pylons.commands.SyncDbCommand-class.html │ │ │ ├── couchdbkit.ext.pylons.db-module.html │ │ │ ├── couchdbkit.ext.pylons.db-pysrc.html │ │ │ ├── couchdbkit.ext.pylons.test-module.html │ │ │ ├── couchdbkit.ext.pylons.test-pysrc.html │ │ │ ├── couchdbkit.ext.pylons.test.FixtureLoader-class.html │ │ │ ├── couchdbkit.ext.pylons.test.TestCase-class.html │ │ │ ├── couchdbkit.external-module.html │ │ │ ├── couchdbkit.external-pysrc.html │ │ │ ├── couchdbkit.external.External-class.html │ │ │ ├── couchdbkit.loaders-module.html │ │ │ ├── couchdbkit.loaders-pysrc.html │ │ │ ├── couchdbkit.loaders.BaseDocsLoader-class.html │ │ │ ├── couchdbkit.loaders.FileSystemDocLoader-class.html │ │ │ ├── couchdbkit.loaders.FileSystemDocsLoader-class.html │ │ │ ├── couchdbkit.resource-module.html │ │ │ ├── couchdbkit.resource-pysrc.html │ │ │ ├── couchdbkit.resource.CouchDBResponse-class.html │ │ │ ├── couchdbkit.resource.CouchdbResource-class.html │ │ │ ├── couchdbkit.schema-module.html │ │ │ ├── couchdbkit.schema-pysrc.html │ │ │ ├── couchdbkit.schema.base-module.html │ │ │ ├── couchdbkit.schema.base-pysrc.html │ │ │ ├── couchdbkit.schema.base.AttachmentMixin-class.html │ │ │ ├── couchdbkit.schema.base.Document-class.html │ │ │ ├── couchdbkit.schema.base.DocumentBase-class.html │ │ │ ├── couchdbkit.schema.base.DocumentSchema-class.html │ │ │ ├── couchdbkit.schema.base.QueryMixin-class.html │ │ │ ├── couchdbkit.schema.base.SchemaProperties-class.html │ │ │ ├── couchdbkit.schema.base.StaticDocument-class.html │ │ │ ├── couchdbkit.schema.properties-module.html │ │ │ ├── couchdbkit.schema.properties-pysrc.html │ │ │ ├── couchdbkit.schema.properties.BooleanProperty-class.html │ │ │ ├── couchdbkit.schema.properties.DateProperty-class.html │ │ │ ├── couchdbkit.schema.properties.DateTimeProperty-class.html │ │ │ ├── couchdbkit.schema.properties.DecimalProperty-class.html │ │ │ ├── couchdbkit.schema.properties.DictProperty-class.html │ │ │ ├── couchdbkit.schema.properties.FloatProperty-class.html │ │ │ ├── couchdbkit.schema.properties.IntegerProperty-class.html │ │ │ ├── couchdbkit.schema.properties.LazyDict-class.html │ │ │ ├── couchdbkit.schema.properties.LazyList-class.html │ │ │ ├── couchdbkit.schema.properties.LazySet-class.html │ │ │ ├── couchdbkit.schema.properties.ListProperty-class.html │ │ │ ├── couchdbkit.schema.properties.Property-class.html │ │ │ ├── couchdbkit.schema.properties.SetProperty-class.html │ │ │ ├── couchdbkit.schema.properties.StringListProperty-class.html │ │ │ ├── couchdbkit.schema.properties.StringProperty-class.html │ │ │ ├── couchdbkit.schema.properties.TimeProperty-class.html │ │ │ ├── couchdbkit.schema.properties_proxy-module.html │ │ │ ├── couchdbkit.schema.properties_proxy-pysrc.html │ │ │ ├── couchdbkit.schema.properties_proxy.LazySchemaDict-class.html │ │ │ ├── couchdbkit.schema.properties_proxy.LazySchemaList-class.html │ │ │ ├── couchdbkit.schema.properties_proxy.SchemaDictProperty-class.html │ │ │ ├── couchdbkit.schema.properties_proxy.SchemaListProperty-class.html │ │ │ ├── couchdbkit.schema.properties_proxy.SchemaProperty-class.html │ │ │ ├── couchdbkit.schema.util-module.html │ │ │ ├── couchdbkit.schema.util-pysrc.html │ │ │ ├── couchdbkit.utils-module.html │ │ │ ├── couchdbkit.utils-pysrc.html │ │ │ ├── couchdbkit.version-module.html │ │ │ ├── couchdbkit.version-pysrc.html │ │ │ ├── couchdbkit.wsgi-module.html │ │ │ ├── couchdbkit.wsgi-pysrc.html │ │ │ ├── couchdbkit.wsgi.handler-module.html │ │ │ ├── couchdbkit.wsgi.handler-pysrc.html │ │ │ ├── couchdbkit.wsgi.handler.WSGIHandler-class.html │ │ │ ├── couchdbkit.wsgi.handler.WSGIRequest-class.html │ │ │ ├── couchdbkit.wsgi.proxy-module.html │ │ │ ├── couchdbkit.wsgi.proxy-pysrc.html │ │ │ ├── couchdbkit.wsgi.proxy.CouchdbProxy-class.html │ │ │ ├── crarr.png │ │ │ ├── datetime.date-class.html │ │ │ ├── datetime.datetime-class.html │ │ │ ├── datetime.time-class.html │ │ │ ├── decimal.Decimal-class.html │ │ │ ├── dict-class.html │ │ │ ├── epydoc.css │ │ │ ├── epydoc.js │ │ │ ├── exceptions.AssertionError-class.html │ │ │ ├── float-class.html │ │ │ ├── frames.html │ │ │ ├── greenlet.GreenletExit-class.html │ │ │ ├── greenlet.error-class.html │ │ │ ├── help.html │ │ │ ├── identifier-index.html │ │ │ ├── index.html │ │ │ ├── int-class.html │ │ │ ├── list-class.html │ │ │ ├── module-tree.html │ │ │ ├── paste.script.command.BadCommand-class.html │ │ │ ├── redirect.html │ │ │ ├── restkit.wrappers.Response-class.html │ │ │ ├── set-class.html │ │ │ ├── toc-couchdbkit-module.html │ │ │ ├── toc-couchdbkit.changes-module.html │ │ │ ├── toc-couchdbkit.client-module.html │ │ │ ├── toc-couchdbkit.consumer-module.html │ │ │ ├── toc-couchdbkit.consumer.base-module.html │ │ │ ├── toc-couchdbkit.consumer.ceventlet-module.html │ │ │ ├── toc-couchdbkit.consumer.cgevent-module.html │ │ │ ├── toc-couchdbkit.consumer.sync-module.html │ │ │ ├── toc-couchdbkit.designer-module.html │ │ │ ├── toc-couchdbkit.designer.fs-module.html │ │ │ ├── toc-couchdbkit.designer.macros-module.html │ │ │ ├── toc-couchdbkit.exceptions-module.html │ │ │ ├── toc-couchdbkit.ext-module.html │ │ │ ├── toc-couchdbkit.ext.django-module.html │ │ │ ├── toc-couchdbkit.ext.django.forms-module.html │ │ │ ├── toc-couchdbkit.ext.django.loading-module.html │ │ │ ├── toc-couchdbkit.ext.django.management-module.html │ │ │ ├── toc-couchdbkit.ext.django.management.commands-module.html │ │ │ ├── toc-couchdbkit.ext.django.management.commands.sync_couchdb-module.html │ │ │ ├── toc-couchdbkit.ext.django.management.commands.sync_finish_couchdb-module.html │ │ │ ├── toc-couchdbkit.ext.django.management.commands.sync_prepare_couchdb-module.html │ │ │ ├── toc-couchdbkit.ext.django.schema-module.html │ │ │ ├── toc-couchdbkit.ext.django.testrunner-module.html │ │ │ ├── toc-couchdbkit.ext.pylons-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.auth-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.auth.adapters-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.auth.basic-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.auth.model-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.commands-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.db-module.html │ │ │ ├── toc-couchdbkit.ext.pylons.test-module.html │ │ │ ├── toc-couchdbkit.external-module.html │ │ │ ├── toc-couchdbkit.loaders-module.html │ │ │ ├── toc-couchdbkit.resource-module.html │ │ │ ├── toc-couchdbkit.schema-module.html │ │ │ ├── toc-couchdbkit.schema.base-module.html │ │ │ ├── toc-couchdbkit.schema.properties-module.html │ │ │ ├── toc-couchdbkit.schema.properties_proxy-module.html │ │ │ ├── toc-couchdbkit.schema.util-module.html │ │ │ ├── toc-couchdbkit.utils-module.html │ │ │ ├── toc-couchdbkit.version-module.html │ │ │ ├── toc-couchdbkit.wsgi-module.html │ │ │ ├── toc-couchdbkit.wsgi.handler-module.html │ │ │ ├── toc-couchdbkit.wsgi.proxy-module.html │ │ │ ├── toc-everything.html │ │ │ ├── toc.html │ │ │ └── unicode-class.html │ │ ├── changes.html │ │ ├── changes_consumer.html │ │ ├── django-extension.html │ │ ├── external.html │ │ ├── faq.html │ │ ├── formalchemy.html │ │ ├── gettingstarted.html │ │ ├── index.html │ │ └── storing_docs_and_designdocs_on_filesystem.html │ ├── download.html │ ├── feed.xml │ ├── images │ │ ├── bg_header_new.png │ │ ├── gettingstarted.png │ │ └── logo.png │ ├── index.html │ ├── js │ │ └── prettify.js │ ├── robots.txt │ └── sitemaps.xml │ ├── index.html │ ├── site │ ├── blog │ │ ├── 2009-06-16-Couchdbkit-site-launched.txt │ │ ├── 2009-06-25-Couchdbkit-0.1.7-released.txt │ │ ├── 2009-06-26-Couchdbkit-0.1.7.1.txt │ │ ├── 2009-07-07-Couchdbkit-0.1.8.txt │ │ ├── 2009-09-07-Couchdbkit-0.1.9.txt │ │ ├── 2009-09-11-Couchdbkit-0.2.txt │ │ ├── 2009-11-05-Couchdbkit-0.2.2.txt │ │ ├── 2009-11-22-Couchdbkit-0.2.4.txt │ │ ├── 2009-12-07-Couchdbkit-0.3.txt │ │ ├── 2010-01-08-Couchdbkit-0.4.txt │ │ ├── 2010-01-25-Couchdbkit-0.4.1.txt │ │ ├── 2010-02-04-CouchdbKit-0.4.2.txt │ │ ├── 2010-02-24-move-to-github.txt │ │ ├── 2010-02-28-restkit-update.txt │ │ ├── 2010-06-28-CouchdbKit-0.4.7.txt │ │ ├── 2010-07-20-CouchdbKit-0.4.9.txt │ │ ├── 2010-11-25-Couchdbkit-0.5.txt │ │ ├── 2011-02-18-Couchdbkit-0.5.4.txt │ │ ├── 2012-01-26-Couchdbkit-0.6.0.txt │ │ ├── 2012-05-04-Couchdbkit-0.6.2.txt │ │ ├── archives.txt │ │ └── index.txt │ ├── contact.txt │ ├── docs │ │ ├── about.txt │ │ ├── changes.txt │ │ ├── changes_consumer.txt │ │ ├── django-extension.txt │ │ ├── external.txt │ │ ├── faq.txt │ │ ├── formalchemy.txt │ │ ├── gettingstarted.txt │ │ ├── index.txt │ │ └── storing_docs_and_designdocs_on_filesystem.txt │ ├── download.txt │ └── index.txt │ └── templates │ ├── base.html │ ├── blog │ ├── archives.html │ ├── index.html │ └── post.html │ ├── default.html │ ├── docs │ └── index.html │ └── index.html ├── examples ├── django_blogapp │ ├── REQUIREMENTS.txt │ ├── __init__.py │ ├── blog_app │ │ ├── __init__.py │ │ ├── _design │ │ │ └── views │ │ │ │ ├── all_posts │ │ │ │ └── map.js │ │ │ │ └── commets_by_post │ │ │ │ └── map.js │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── settings.py │ ├── templates │ │ ├── base.html │ │ ├── home.html │ │ ├── post_details.html │ │ └── post_edit.html │ ├── urls.py │ └── wsgi.py ├── djangoapp │ ├── __init__.py │ ├── greeting │ │ ├── __init__.py │ │ ├── _design │ │ │ └── views │ │ │ │ └── all │ │ │ │ └── map.js │ │ ├── models.py │ │ └── views.py │ ├── manage.py │ ├── requirements.txt │ ├── run.py │ ├── settings.py │ ├── templates │ │ ├── base.html │ │ └── home.html │ └── urls.py ├── pyramidapp │ ├── MANIFEST.in │ ├── README │ ├── development.ini │ ├── pyramid_couchdb_example │ │ ├── __init__.py │ │ ├── static │ │ │ ├── favicon.ico │ │ │ ├── footerbg.png │ │ │ ├── headerbg.png │ │ │ ├── ie6.css │ │ │ ├── middlebg.png │ │ │ ├── pylons.css │ │ │ ├── pyramid-small.png │ │ │ ├── pyramid.png │ │ │ └── transparent.gif │ │ ├── templates │ │ │ └── mytemplate.pt │ │ ├── tests.py │ │ └── views.py │ ├── setup.cfg │ └── setup.py └── wsgi │ └── test.py ├── requirements.txt ├── requirements_dev.txt ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── client_test.py ├── data └── app-template │ ├── _attachments │ ├── index.html │ └── style │ │ └── main.css │ ├── foo │ └── bar.txt │ ├── lib │ ├── helpers │ │ ├── math.js │ │ └── template.js │ └── templates │ │ └── example.html │ ├── lists │ └── feed.js │ ├── shows │ └── example-show.js │ └── views │ └── example │ ├── map.js │ └── reduce.js ├── test_changes.py ├── test_consumer.py ├── test_loaders.py ├── test_resource.py └── test_schema.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.swp 3 | *.pyc 4 | *#* 5 | build 6 | dist 7 | setuptools-* 8 | .svn/* 9 | .DS_Store 10 | *.so 11 | nohup.out 12 | *.orig 13 | *.rej 14 | *~ 15 | *.o 16 | *.pyc 17 | *.pyo 18 | tests/*.err 19 | *.swp 20 | store/* 21 | *.DS_Store 22 | *.beam 23 | *.log 24 | couchdbkit.egg-info 25 | dist/ 26 | doc/_build/ 27 | distribute-* 28 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.orig 3 | *.rej 4 | *~ 5 | *.o 6 | *.pyc 7 | *.pyo 8 | tests/*.err 9 | *.swp 10 | store/* 11 | *.DS_Store 12 | *.beam 13 | .coverage 14 | couchdbkit.egg-info 15 | dist 16 | examples/djangoapp/test.db 17 | 18 | syntax: regexp 19 | .*\#.*\#$ 20 | 21 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | 042d6587fe290b158f6779145a96651a894fc5f7 0.1.1 2 | 99a25564cc09004aca0c921c0a94e92c3972c033 0.1.2 3 | 69bc244110249a0b310dfde31b719dc7472bb3d7 0.1.3 4 | eb07f2cd97b65a5a3ff9ddaac0435effee589fe8 0.1.4 5 | 9d8a3b20aa4e41565513ce1593701e1658c44efc 0.1.6 6 | 7e5da2149fa5864a0390094d9c5dee88589233eb 0.1.6.1 7 | d9831b7c3d6d21a9827c171e92e84eb60889c481 0.1.7 8 | d8acae3e42268fd765e5b7c348435ba707d10636 0.1.7.1 9 | aedb19fb01cb8f4afc79027b20cdd6ebc275825f 0.1.7.2 10 | 9e169d80ffb1e1fdf9131c2824c1ebc5037c5d95 0.1.8 11 | f9fa696b672130cf15a2d16d97c0cc862507d1fc 0.1.9 12 | c28f80517104b7a4dc402974959449ccfa60ab08 0.1.9.1 13 | 67dddbdb8ae5d668662f2dcbcc7bf484adf50533 0.2 14 | ffa06885b498666efe9c069a53f640751a38d4e5 0.2.1 15 | e9316c36f8e73b3a016debcfd1d130f4c6df3a0d 0.2.2 16 | e9316c36f8e73b3a016debcfd1d130f4c6df3a0d 0.2.2 17 | d7e31f3829a8021d50b5f19f33f4a4ec5253a728 0.2.2 18 | 7214410b4514880b8f6b09e6d7cbb5f5e746efa2 0.2.3 19 | 7214410b4514880b8f6b09e6d7cbb5f5e746efa2 0.2.3 20 | be307befe36be7ff5b102f2fff36105db9a9f871 0.2.3 21 | 903cd60cec4b11d1171e88a045a9a16c2fb03024 0.2.4 22 | 903cd60cec4b11d1171e88a045a9a16c2fb03024 0.2.4 23 | 3dc59a843ce0bad21a16bca4b4a9ec3d8397fd75 0.2.4 24 | d5c211047a6d2d98daa403c7ba7ceaa24b5a0585 0.3 25 | d5c211047a6d2d98daa403c7ba7ceaa24b5a0585 0.3 26 | 65bb003bde529a1fc6669ccfbdef3abe5835e283 0.3 27 | 57879431a4e200318378327af6dfe04884822e3e 0.3.1 28 | 062d4b680c600c9cfbf2d96b90af80a291add1e3 0.4 29 | 062d4b680c600c9cfbf2d96b90af80a291add1e3 0.4 30 | f8ddd60879ef6ed24a69b76ac1927c3fa1bdbb54 0.4 31 | f8ddd60879ef6ed24a69b76ac1927c3fa1bdbb54 0.4 32 | 4eb125217ca6800e25deb185a6ced3f813f5727e 0.4 33 | 4eb125217ca6800e25deb185a6ced3f813f5727e 0.4 34 | a1907763e888440b17353208de0fb78740587735 0.4 35 | b157f94ff805b10f6ec4118b78d25b9695d10fbf 0.4.1 36 | b157f94ff805b10f6ec4118b78d25b9695d10fbf 0.4.1 37 | c43c2a19151952af90d3b26a6ba4f4f726123e27 0.4.1 38 | 631c681601e1be76a94dda6ffc7faa90e55ce9f1 0.4.2 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | services: 4 | - couchdb 5 | 6 | python: 7 | - 2.6 8 | - 2.7 9 | 10 | install: 11 | - pip install -r requirements_dev.txt --use-mirrors 12 | - python setup.py install 13 | 14 | script: python setup.py test 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2008-2012 (c) Benoît Chesneau 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include distribute_setup.py 4 | recursive-include docs * 5 | recursive-include tests/data * 6 | recursive-include tests * -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Couchdbkit 2 | --------- 3 | 4 | 2008-2012 (c) Benoît Chesneau 5 | 6 | couchdbkit is released under the MIT license. See the LICENSE file for 7 | the complete license. 8 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | Couchdbkit THANKS 2 | ================= 3 | 4 | A number of people have contributed to Couchdbkit by reporting problems, 5 | suggesting improvements or submitting changes. Some of these people are: 6 | 7 | Alfred Hall 8 | Doug Latornell 9 | Nicolas Clairon 10 | Stefan Kögl 11 | Jeff McGee 12 | Cory Zue 13 | Ivan Gromov 14 | Ronny Pfannschmidt 15 | Elisiano Petrini 16 | Daniel Roberts 17 | Rémy Hubscher 18 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | version 0.5 2 | - new versatile mapper + support of desktopcouch records format 3 | - full Desktop Couchdb apps support 4 | - add support for oauth 5 | - full featured python view server 6 | - more helper for views : key filter 7 | 8 | -------------------------------------------------------------------------------- /couchdbkit/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from .version import version_info, __version__ 7 | 8 | from .resource import RequestFailed, CouchdbResource 9 | from .exceptions import InvalidAttachment, DuplicatePropertyError,\ 10 | BadValueError, MultipleResultsFound, NoResultFound, ReservedWordError,\ 11 | DocsPathNotFound, BulkSaveError, ResourceNotFound, ResourceConflict, \ 12 | PreconditionFailed 13 | 14 | from .client import Server, Database, ViewResults 15 | from .changes import ChangesStream 16 | from .consumer import Consumer 17 | from .designer import document, push, pushdocs, pushapps, clone 18 | from .external import External 19 | from .loaders import BaseDocsLoader, FileSystemDocsLoader 20 | 21 | from .schema import ( 22 | Property, IntegerProperty, DecimalProperty, BooleanProperty, FloatProperty, StringProperty, 23 | DateTimeProperty, DateProperty, TimeProperty, 24 | dict_to_json, dict_to_json, dict_to_json, 25 | value_to_python, dict_to_python, 26 | DocumentSchema, DocumentBase, Document, StaticDocument, contain, 27 | QueryMixin, AttachmentMixin, 28 | SchemaProperty, SchemaListProperty, SchemaDictProperty, 29 | ListProperty, DictProperty, StringDictProperty, StringListProperty, SetProperty 30 | ) 31 | 32 | import logging 33 | 34 | LOG_LEVELS = { 35 | "critical": logging.CRITICAL, 36 | "error": logging.ERROR, 37 | "warning": logging.WARNING, 38 | "info": logging.INFO, 39 | "debug": logging.DEBUG 40 | } 41 | 42 | def set_logging(level, handler=None): 43 | """ 44 | Set level of logging, and choose where to display/save logs 45 | (file or standard output). 46 | """ 47 | if not handler: 48 | handler = logging.StreamHandler() 49 | 50 | loglevel = LOG_LEVELS.get(level, logging.INFO) 51 | logger = logging.getLogger('couchdbkit') 52 | logger.setLevel(loglevel) 53 | format = r"%(asctime)s [%(process)d] [%(levelname)s] %(message)s" 54 | datefmt = r"%Y-%m-%d %H:%M:%S" 55 | 56 | handler.setFormatter(logging.Formatter(format, datefmt)) 57 | logger.addHandler(handler) 58 | 59 | -------------------------------------------------------------------------------- /couchdbkit/changes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | """ 7 | module to fetch and stream changes from a database 8 | """ 9 | 10 | from .utils import json 11 | 12 | 13 | class ChangesStream(object): 14 | """\ 15 | Change stream object. 16 | 17 | .. code-block:: python 18 | 19 | from couchdbkit import Server from couchdbkit.changes import ChangesStream 20 | 21 | s = Server() 22 | db = s['testdb'] 23 | stream = ChangesStream(db) 24 | 25 | print "got change now" 26 | for c in stream: 27 | print c 28 | 29 | print "stream changes" 30 | with ChangesStream(db, feed="continuous", heartbeat=True) as stream: 31 | for c in stream: print c 32 | 33 | """ 34 | 35 | def __init__(self, db, **params): 36 | self.db = db 37 | self.params = params 38 | 39 | def __enter__(self): 40 | return self 41 | 42 | def __exit__(self, *args): 43 | return False 44 | 45 | def __iter__(self): 46 | r = self.db.res.get("_changes", **self.params) 47 | with r.body_stream() as body: 48 | while True: 49 | line = body.readline() 50 | if not line: 51 | break 52 | if line.endswith("\r\n"): 53 | line = line[:-2] 54 | else: 55 | line = line[:-1] 56 | if not line: 57 | #heartbeat 58 | continue 59 | 60 | if line.endswith(","): 61 | line = line[:-1] 62 | ret = self._parse_change(line) 63 | if not ret: 64 | continue 65 | yield ret 66 | 67 | def _parse_change(self, line): 68 | if line.startswith('{"results":') or line.startswith('"last_seq'): 69 | return None 70 | else: 71 | try: 72 | obj = json.loads(line) 73 | return obj 74 | except ValueError: 75 | return None 76 | 77 | def __next__(self): 78 | return self 79 | 80 | 81 | def fold(db, fun, acc, since=0): 82 | """Fold each changes and accuumulate result using a function 83 | 84 | Args: 85 | 86 | @param db: Database, a database object 87 | @param fun: function, a callable with arity 2 88 | @param since: int, sequence where to start the feed 89 | 90 | @return: list, last acc returned 91 | 92 | Ex of function: 93 | 94 | fun(change_object,acc): 95 | return acc 96 | 97 | If the function return "stop", the changes feed will stop. 98 | 99 | 100 | """ 101 | 102 | if not callable(fun): 103 | raise TypeError("fun isn't a callable") 104 | 105 | with ChangesStream(db, since=since) as st: 106 | for c in st: 107 | acc = fun(c, acc) 108 | return acc 109 | 110 | 111 | def foreach(db, fun, since=0): 112 | """Iter each changes and pass it to the callable""" 113 | 114 | if not callable(fun): 115 | raise TypeError("fun isn't a callable") 116 | 117 | with ChangesStream(db, since=since) as st: 118 | for c in st: 119 | fun(c) 120 | -------------------------------------------------------------------------------- /couchdbkit/consumer/base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | def check_callable(cb): 7 | if not callable(cb): 8 | raise TypeError("callback isn't a callable") 9 | 10 | class ConsumerBase(object): 11 | 12 | def __init__(self, db, **kwargs): 13 | self.db = db 14 | 15 | def fetch(self, cb=None, **params): 16 | resp = self.db.res.get("_changes", **params) 17 | if cb is not None: 18 | check_callable(cb) 19 | cb(resp.json_body) 20 | else: 21 | return resp.json_body 22 | 23 | def wait_once(self, cb=None, **params): 24 | raise NotImplementedError 25 | 26 | def wait(self, cb, **params): 27 | raise NotImplementedError 28 | 29 | def wait_once_async(self, cb, **params): 30 | raise NotImplementedError 31 | 32 | def wait_async(self, cb, **params): 33 | raise NotImplementedError 34 | -------------------------------------------------------------------------------- /couchdbkit/consumer/sync.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from __future__ import with_statement 7 | 8 | from .base import ConsumerBase, check_callable 9 | from ..utils import json 10 | 11 | __all__ = ['SyncConsumer'] 12 | 13 | class SyncConsumer(ConsumerBase): 14 | 15 | def wait_once(self, cb=None, **params): 16 | if cb is not None: 17 | check_callable(cb) 18 | 19 | params.update({"feed": "longpoll"}) 20 | resp = self.db.res.get("_changes", **params) 21 | buf = "" 22 | with resp.body_stream() as body: 23 | while True: 24 | data = body.read() 25 | if not data: 26 | break 27 | buf += data 28 | 29 | ret = json.loads(buf) 30 | if cb is not None: 31 | cb(ret) 32 | return 33 | 34 | return ret 35 | 36 | def wait(self, cb, **params): 37 | check_callable(cb) 38 | params.update({"feed": "continuous"}) 39 | resp = self.db.res.get("_changes", **params) 40 | 41 | with resp.body_stream() as body: 42 | while True: 43 | try: 44 | line = body.readline() 45 | if not line: 46 | break 47 | if line.endswith("\r\n"): 48 | line = line[:-2] 49 | else: 50 | line = line[:-1] 51 | if not line: 52 | continue 53 | 54 | cb(json.loads(line)) 55 | except (KeyboardInterrupt, SystemExit,): 56 | break 57 | -------------------------------------------------------------------------------- /couchdbkit/designer/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from .fs import FSDoc, document, push, pushdocs, pushapps, clone 7 | -------------------------------------------------------------------------------- /couchdbkit/exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | """ 7 | All exceptions used in couchdbkit. 8 | """ 9 | from restkit.errors import ResourceError, RequestFailed 10 | 11 | class InvalidAttachment(Exception): 12 | """ raised when an attachment is invalid """ 13 | 14 | class DuplicatePropertyError(Exception): 15 | """ exception raised when there is a duplicate 16 | property in a model """ 17 | 18 | class BadValueError(Exception): 19 | """ exception raised when a value can't be validated 20 | or is required """ 21 | 22 | class MultipleResultsFound(Exception): 23 | """ exception raised when more than one object is 24 | returned by the get_by method""" 25 | 26 | class NoResultFound(Exception): 27 | """ exception returned when no results are found """ 28 | 29 | class ReservedWordError(Exception): 30 | """ exception raised when a reserved word 31 | is used in Document schema """ 32 | 33 | class DocsPathNotFound(Exception): 34 | """ exception raised when path given for docs isn't found """ 35 | 36 | class BulkSaveError(Exception): 37 | """ exception raised when bulk save contain errors. 38 | error are saved in `errors` property. 39 | """ 40 | def __init__(self, errors, results, *args): 41 | self.errors = errors 42 | self.results = results 43 | 44 | class ViewServerError(Exception): 45 | """ exception raised by view server""" 46 | 47 | class MacroError(Exception): 48 | """ exception raised when macro parsiing error in functions """ 49 | 50 | class DesignerError(Exception): 51 | """ unkown exception raised by the designer """ 52 | 53 | class ResourceNotFound(ResourceError): 54 | """ Exception raised when resource is not found""" 55 | 56 | class ResourceConflict(ResourceError): 57 | """ Exception raised when there is conflict while updating""" 58 | 59 | class PreconditionFailed(ResourceError): 60 | """ Exception raised when 412 HTTP error is received in response 61 | to a request """ 62 | 63 | class DocTypeError(Exception): 64 | """ Exception raised when doc type of json to be wrapped 65 | does not match the doc type of the matching class 66 | """ 67 | -------------------------------------------------------------------------------- /couchdbkit/ext/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/couchdbkit/ext/__init__.py -------------------------------------------------------------------------------- /couchdbkit/ext/django/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright (c) 2008-2009 Benoit Chesneau 4 | # 5 | # Permission to use, copy, modify, and distribute this software for any 6 | # purpose with or without fee is hereby granted, provided that the above 7 | # copyright notice and this permission notice appear in all copies. 8 | # 9 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | """ 18 | Extension to use couchdbkit in Django 1.x. It allows you to use couchdbkit 19 | easily in your django projects. 20 | 21 | Just add to your settings the `COUCHDB_DATABASES` that defines 22 | 23 | COUCHDB_DATABASES = ( 24 | ('djangoapp.greeting', 'http://127.0.0.1:5984/greeting'), 25 | ) 26 | 27 | This one define the db greeting on url `http://127.0.0.1:5984/greeting` 28 | for the application `greeting`of djangoapp project. 29 | 30 | 31 | Then add extension to your INSTALLED_APPS before all applications using 32 | couchdbkit documents : 33 | 34 | INSTALLED_APPS = ( 35 | .... 36 | 'couchdbkit.ext.django', 37 | .... 38 | ) 39 | 40 | Add your documents objects in models.py : 41 | 42 | from couchdbkit.ext.django.schema import * 43 | class Greeting(Document): 44 | author = StringProperty() 45 | content = StringProperty(required=True) 46 | date = DateTimeProperty(default=datetimee.utcnow) 47 | 48 | and use it in your views.py : 49 | 50 | class GreetingForm(DocumentForm): 51 | 52 | class Meta: 53 | document = Greeting 54 | 55 | def home(request): 56 | 57 | greet = None 58 | 59 | if request.POST: 60 | form = GreetingForm(request.POST) 61 | if form.is_valid(): 62 | greet = form.save() 63 | else: 64 | form = GreetingForm() 65 | 66 | greetings = Greeting.view('greeting/all') 67 | 68 | return render("home.html", { 69 | "form": form, 70 | "greet": greet, 71 | "greetings": greetings 72 | }, context_instance=RequestContext(request) 73 | 74 | You could notice in this example the `DocumentForm` object. 75 | This object works like the ModelForm object but for couchdb 76 | documents. Very easy. 77 | 78 | Views/shows/lists are created in _design folder of your application. 79 | exemple : 80 | 81 | /yourapp 82 | /yourapp/_design 83 | /yourapp/_design/views 84 | /yourapp/_design/views/viewname 85 | /yourapp/_design/views/viewname/map.js 86 | .... 87 | 88 | To create databases and sync views, just run the usual `syncdb` command. 89 | It won't destroy your datas, just synchronize views. 90 | """ 91 | 92 | from django.db.models import signals 93 | 94 | def syncdb(app, created_models, verbosity=2, **kwargs): 95 | """ function used by syncdb signal """ 96 | from couchdbkit.ext.django.loading import couchdbkit_handler 97 | couchdbkit_handler.sync(app, verbosity=verbosity) 98 | 99 | signals.post_syncdb.connect(syncdb) 100 | -------------------------------------------------------------------------------- /couchdbkit/ext/django/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/couchdbkit/ext/django/management/__init__.py -------------------------------------------------------------------------------- /couchdbkit/ext/django/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/couchdbkit/ext/django/management/commands/__init__.py -------------------------------------------------------------------------------- /couchdbkit/ext/django/management/commands/sync_couchdb.py: -------------------------------------------------------------------------------- 1 | from django.db.models import get_apps 2 | from django.core.management.base import BaseCommand 3 | from couchdbkit.ext.django.loading import couchdbkit_handler 4 | 5 | class Command(BaseCommand): 6 | help = 'Sync couchdb views.' 7 | 8 | def handle(self, *args, **options): 9 | for app in get_apps(): 10 | couchdbkit_handler.sync(app, verbosity=2) 11 | -------------------------------------------------------------------------------- /couchdbkit/ext/django/management/commands/sync_finish_couchdb.py: -------------------------------------------------------------------------------- 1 | from django.db.models import get_apps 2 | from django.core.management.base import BaseCommand 3 | from couchdbkit.ext.django.loading import couchdbkit_handler 4 | 5 | class Command(BaseCommand): 6 | help = 'Copy temporary design docs over existing ones' 7 | 8 | def handle(self, *args, **options): 9 | for app in get_apps(): 10 | couchdbkit_handler.copy_designs(app, temp='tmp', verbosity=2) 11 | -------------------------------------------------------------------------------- /couchdbkit/ext/django/management/commands/sync_prepare_couchdb.py: -------------------------------------------------------------------------------- 1 | from django.db.models import get_apps 2 | from django.core.management.base import BaseCommand 3 | from couchdbkit.ext.django.loading import couchdbkit_handler 4 | 5 | class Command(BaseCommand): 6 | help = 'Sync design docs to temporary ids' 7 | 8 | def handle(self, *args, **options): 9 | for app in get_apps(): 10 | couchdbkit_handler.sync(app, verbosity=2, temp='tmp') 11 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | """Pylons extension to simplify using couchdbkit with pylons. This features the 7 | following: 8 | * Simple configuration 9 | * Authentication 10 | * View synchronization 11 | * Testing 12 | 13 | Configuration 14 | ------------- 15 | Add this to your ini file: 16 | 17 | couchdb.uri = http://localhost:5984 18 | couchdb.dbname = mydbname 19 | cookies.secret = randomuniquestringforauth 20 | 21 | And this into environment.py: 22 | 23 | from couchdbkit.ext.pylons import init_from_config 24 | init_from_config(config) 25 | 26 | Authentication 27 | -------------- 28 | You first need to define a User model, add this into model/user.py: 29 | 30 | from couchdbkit import StringProperty 31 | from couchdbkit.ext.pylons.auth.model import User as UserBase 32 | 33 | class User(UserBase): 34 | first_name = StringProperty() 35 | last_name = StringProperty() 36 | email = StringProperty() 37 | 38 | Then add this into middleware.py: 39 | from yourapp.model.user import User 40 | from couchdbkit.ext.pylons.auth.basic import AuthBasicMiddleware 41 | app = AuthBasicMiddleware(app, config, User) 42 | 43 | NOTE: This authentication by default uses sha-256 hashing with a salt, the behaviour 44 | can be changed by overriding methods. 45 | 46 | Now we need the views required for authentication: 47 | Create yourapp/_design/user/views/by_login/map.js and make it look like this: 48 | function(doc) { 49 | if(doc.doc_type == "User") { 50 | emit(doc.login, doc); 51 | } 52 | } 53 | 54 | And yourapp/_design/group/views/by_name/map.js: 55 | function(doc) { 56 | if(doc.doc_type == "Group") { 57 | emit(doc.name, doc); 58 | } 59 | } 60 | 61 | And yourapp/_design/group/views/show_permissions/map.js: 62 | function(doc) { 63 | if (doc.doc_type == "Group") { 64 | for (var i = 0; i < doc.permissions.length; i++) { 65 | emit(doc.name, doc.permissions[i].name); 66 | } 67 | } 68 | } 69 | 70 | View synchronization 71 | -------------------- 72 | This will sync yourapp/_design to the CouchDB database described in the config. 73 | couchdbkit has a built-in syncdb command that will automatically sync it. We 74 | need to open up setup.py and add the command there as an entry point: 75 | 76 | [paste.paster_command] 77 | syncdb = couchdbkit.ext.pylons.commands:SyncDbCommand 78 | 79 | And then add 'couchdbkit' to paster_plugins in the same file. 80 | 81 | Syncing the database is then as simple as: paster syncdb /path/to/config.ini 82 | 83 | Testing 84 | ------- 85 | This will make it easier to create unit and functional tests that use couchdb 86 | and load fixtures, this is not done yet and is TBC. 87 | 88 | """ 89 | 90 | from .db import init_from_config 91 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/auth/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/auth/adapters.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from repoze.what.adapters import BaseSourceAdapter 7 | from repoze.who.interfaces import IAuthenticator 8 | from repoze.who.interfaces import IMetadataProvider 9 | from zope.interface import implements 10 | 11 | class GroupAdapter(BaseSourceAdapter): 12 | """ group adapter """ 13 | 14 | def __init__(self, user_class): 15 | self.user_class = user_class 16 | 17 | def _get_all_sections(self): 18 | raise NotImplementedError() 19 | 20 | def _get_section_items(self, section): 21 | raise NotImplementedError() 22 | 23 | def _find_sections(self, hint): 24 | """Returns the group ids that the user is part of.""" 25 | user = self.user_class.get(hint['repoze.what.userid']) 26 | return user.groups 27 | 28 | def _include_items(self, section, items): 29 | raise NotImplementedError() 30 | 31 | def _item_is_included(self, section, item): 32 | raise NotImplementedError() 33 | 34 | def _section_exists(self, section): 35 | raise NotImplementedError() 36 | 37 | class PermissionAdapter(BaseSourceAdapter): 38 | def __init__(self, db): 39 | self.db = db 40 | 41 | def _get_all_sections(self): 42 | raise NotImplementedError() 43 | 44 | def _get_section_items(self, section): 45 | raise NotImplementedError() 46 | 47 | def _find_sections(self, hint): 48 | results = self.db.view('group/show_permissions', startkey=hint).all() 49 | return [x["value"] for x in results] 50 | 51 | def _include_items(self, section, items): 52 | raise NotImplementedError() 53 | 54 | def _item_is_included(self, section, item): 55 | raise NotImplementedError() 56 | 57 | def _section_exists(self, section): 58 | raise NotImplementedError() 59 | 60 | class Authenticator(object): 61 | implements(IAuthenticator) 62 | 63 | def __init__(self, user_class): 64 | self.user_class = user_class 65 | 66 | def authenticate(self, environ, identity): 67 | login = identity.get('login', '') 68 | password = identity.get('password', '') 69 | 70 | user = self.user_class.authenticate(login, password) 71 | if not user: 72 | return None 73 | identity['login'] = str(user.login) 74 | identity['user'] = user 75 | return user._id 76 | 77 | class MDPlugin(object): 78 | implements(IMetadataProvider) 79 | 80 | def __init__(self, user_class): 81 | self.user_class = user_class 82 | 83 | def add_metadata(self, environ, identity): 84 | if 'user' not in identity: 85 | uid = identity['repoze.who.userid'] 86 | if uid: 87 | user = self.user_class.get(uid) 88 | identity['user'] = user 89 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/auth/model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from hashlib import sha256 7 | import os 8 | 9 | 10 | from .... import Document, SchemaListProperty, StringProperty, \ 11 | StringListProperty 12 | 13 | class Permission(Document): 14 | name = StringProperty(required=True) 15 | 16 | class Group(Document): 17 | """ 18 | Group class, contains multiple permissions. 19 | """ 20 | name = StringProperty(required=True) 21 | permissions = SchemaListProperty(Permission) 22 | 23 | class User(Document): 24 | """The base User model. This should be extended by the user.""" 25 | login = StringProperty(required=True) 26 | password = StringProperty(required=True) 27 | groups = StringListProperty() 28 | 29 | @staticmethod 30 | def _hash_password(cleartext): 31 | if isinstance(cleartext, unicode): 32 | password_8bit = cleartext.encode('UTF-8') 33 | else: 34 | password_8bit = cleartext 35 | 36 | salt = sha256() 37 | salt.update(os.urandom(60)) 38 | hash = sha256() 39 | hash.update(password_8bit + salt.hexdigest()) 40 | hashed_password = salt.hexdigest() + hash.hexdigest() 41 | 42 | if not isinstance(hashed_password, unicode): 43 | hashed_password = hashed_password.decode('UTF-8') 44 | return hashed_password 45 | 46 | def set_password(self, password): 47 | self.password = self._hash_password(password) 48 | 49 | @staticmethod 50 | def authenticate(login, password): 51 | user = User.view("user/by_login", key=login).one() 52 | if not user: 53 | return None 54 | 55 | hashed_pass = sha256() 56 | hashed_pass.update(password + user.password[:64]) 57 | if user.password[64:] != hashed_pass.hexdigest(): 58 | return None 59 | return user 60 | 61 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/commands.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | import os 7 | from paste.deploy import loadapp 8 | from paste.script.command import Command 9 | 10 | from .db import sync_design, default_design_path 11 | 12 | class SyncDbCommand(Command): 13 | """Syncs the CouchDB views on disk with the database. 14 | 15 | Example:: 16 | 17 | $ paster syncdb my-development.ini 18 | 19 | This will also create the database if it does not exist 20 | """ 21 | summary = __doc__.splitlines()[0] 22 | usage = '\n' + __doc__ 23 | 24 | min_args = 1 25 | max_args = 1 26 | group_name = 'couchdbkit' 27 | default_verbosity = 3 28 | parser = Command.standard_parser(simulate=True) 29 | 30 | def command(self): 31 | """Main command to sync db""" 32 | config_file = self.args[0] 33 | 34 | config_name = 'config:%s' % config_file 35 | here_dir = os.getcwd() 36 | 37 | if not self.options.quiet: 38 | # Configure logging from the config file 39 | self.logging_file_config(config_file) 40 | 41 | # Load the wsgi app first so that everything is initialized right 42 | wsgiapp = loadapp(config_name, relative_to=here_dir) 43 | try: 44 | design_path = wsgiapp.config['couchdb.design'] 45 | except KeyError: 46 | design_path = default_design_path(wsgiapp.config) 47 | 48 | # This syncs the main database. 49 | sync_design(wsgiapp.config['couchdb.db'], design_path) 50 | 51 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/db.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | import os.path 7 | 8 | from ...client import Server 9 | from ...designer import pushapps 10 | from ...schema import Document 11 | 12 | def init_from_config(config): 13 | """Initialize the database given a pylons config. This assumes the 14 | configuration format layed out on the wiki. This will only initialize the 15 | primary database. 16 | 17 | This prefixes the database name with test_ if we're running unit tests. 18 | """ 19 | uri = config['couchdb.uri'] 20 | dbname = config['couchdb.dbname'] 21 | 22 | config['couchdb.db'] = init_db(uri, dbname) 23 | config['couchdb.fixtures'] = os.path.join(config['pylons.paths']['root'], "fixtures") 24 | 25 | def init_db(uri, dbname, main_db=True): 26 | """Returns a db object and syncs the design documents on demand. 27 | If main_db is set to true then all models will use that one by default. 28 | """ 29 | server = Server(uri) 30 | 31 | db = server.get_or_create_db(dbname) 32 | if main_db: 33 | Document.set_db(db) 34 | return db 35 | 36 | def sync_design(db, path): 37 | """Synchronizes the design documents with the database passed in.""" 38 | pushapps(path, db) 39 | 40 | def default_design_path(config): 41 | """Returns full path to the default design documents path, it's _design in 42 | the pylons root path 43 | """ 44 | return os.path.join(config['pylons.paths']['root'], "_design") 45 | 46 | -------------------------------------------------------------------------------- /couchdbkit/ext/pylons/test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from __future__ import with_statement 7 | 8 | import os 9 | import unittest 10 | 11 | from ... import BaseDocsLoader, ResourceNotFound 12 | from .db import init_db, sync_design, default_design_path 13 | from ...utils import json 14 | 15 | class FixtureLoader(BaseDocsLoader): 16 | def __init__(self, directory): 17 | self._directory = directory 18 | 19 | def get_docs(self): 20 | docs = [] 21 | for fixture in os.listdir(self._directory): 22 | fixture_path = os.path.join(self._directory, fixture) 23 | if not os.path.isfile(fixture_path): 24 | raise Exception("Fixture path %s not found" % fixture_path) 25 | with open(fixture_path, "r") as fp: 26 | for doc in json.load(fp): 27 | docs.append(doc) 28 | return docs 29 | 30 | class TestCase(unittest.TestCase): 31 | """ 32 | Basic test class that will be default load all fixtures specified in the 33 | fixtures attribute. 34 | """ 35 | def __init__(self, *args, **kwargs): 36 | self._config = kwargs['config'] 37 | del kwargs['config'] 38 | unittest.TestCase.__init__(self, *args, **kwargs) 39 | 40 | def setUp(self): 41 | dbname = self._config['couchdb.db'].dbname 42 | 43 | # Set the directory to the fixtures. 44 | try: 45 | self._config['couchdb.db'].server.delete_db(dbname) 46 | except ResourceNotFound: 47 | pass 48 | 49 | self._config['couchdb.db'] = init_db(self._config['couchdb.uri'], dbname) 50 | sync_design(self._config['couchdb.db'], default_design_path(self._config)) 51 | 52 | if hasattr(self, 'fixtures'): 53 | fixtures_dir = self._config['couchdb.fixtures'] 54 | if not os.path.isdir(fixtures_dir): 55 | raise Exception("Fixtures dir %s not found" % fixtures_dir) 56 | FixtureLoader(fixtures_dir).sync(self._config['couchdb.db']) 57 | 58 | -------------------------------------------------------------------------------- /couchdbkit/external.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | import sys 7 | 8 | from .utils import json 9 | 10 | class External(object): 11 | """ simple class to handle an external 12 | ans send the response. 13 | 14 | example: 15 | 16 | from couchdbkit.external import External 17 | from couchdbkit.utils import json 18 | 19 | class Test(External): 20 | 21 | def handle_line(self, line): 22 | self.send_response(200, 23 | "got message external object %s" % json.dumps(line), 24 | {"Content-type": "text/plain"}) 25 | 26 | if __name__ == "__main__": 27 | Test().run() 28 | 29 | """ 30 | 31 | def __init__(self, stdin=sys.stdin, stdout=sys.stdout): 32 | self.stdin = stdin 33 | self.stdout = stdout 34 | 35 | def handle_line(self, line): 36 | raise NotImplementedError 37 | 38 | def write(self, line): 39 | self.stdout.write("%s\n" % line) 40 | self.stdout.flush() 41 | 42 | def lines(self): 43 | line = self.stdin.readline() 44 | while line: 45 | yield json.loads(line) 46 | line = self.stdin.readline() 47 | 48 | def run(self): 49 | for line in self.lines(): 50 | self.handle_line(line) 51 | 52 | def send_response(self, code=200, body="", headers={}): 53 | resp = { 54 | 'code': code, 55 | 'body': body, 56 | 'headers': headers 57 | } 58 | self.write(json.dumps(resp)) 59 | -------------------------------------------------------------------------------- /couchdbkit/schema/util.py: -------------------------------------------------------------------------------- 1 | from couchdbkit.exceptions import DocTypeError 2 | 3 | 4 | def schema_map(schema, dynamic_properties): 5 | if hasattr(schema, "wrap") and hasattr(schema, '_doc_type'): 6 | schema = {schema._doc_type: schema} 7 | elif isinstance(schema, list): 8 | schema = dict((s._doc_type, s) for s in schema) 9 | 10 | if dynamic_properties is not None: 11 | for name, cls in schema.items(): 12 | if cls._allow_dynamic_properties != dynamic_properties: 13 | schema[name] = type(cls.__name__, (cls,), { 14 | '_allow_dynamic_properties': dynamic_properties, 15 | }) 16 | return schema 17 | 18 | 19 | def doctype_attr_of(classes): 20 | doc_type_attrs = set(cls._doc_type_attr for cls in classes) 21 | assert len(doc_type_attrs) == 1, "inconsistent doctype attr" 22 | return doc_type_attrs.pop() 23 | 24 | 25 | def get_multi_wrapper(classes): 26 | doctype_attr = doctype_attr_of(classes.values()) 27 | 28 | def wrap(doc): 29 | doc_type = doc.get(doctype_attr) 30 | try: 31 | cls = classes[doc_type] 32 | except KeyError: 33 | raise DocTypeError( 34 | "the document being wrapped has doc type {0!r}. " 35 | "To wrap it anyway, you must explicitly pass in " 36 | "classes={{{0!r}: }} to your view. " 37 | "This behavior is new starting in 0.6.2.".format(doc_type) 38 | ) 39 | return cls.wrap(doc) 40 | 41 | return wrap 42 | 43 | 44 | def schema_wrapper(schema, dynamic_properties=None): 45 | if hasattr(schema, "wrap") and hasattr(schema, '_doc_type') and not dynamic_properties: 46 | return schema.wrap 47 | mapping = schema_map(schema, dynamic_properties) 48 | return get_multi_wrapper(mapping) 49 | 50 | 51 | def maybe_schema_wrapper(schema, params): 52 | dynamic_properties = params.pop('dynamic_properties', None) 53 | return schema_wrapper(schema, dynamic_properties) 54 | -------------------------------------------------------------------------------- /couchdbkit/version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | version_info = (0, 6, 5) 7 | __version__ = ".".join(map(str, version_info)) 8 | -------------------------------------------------------------------------------- /couchdbkit/wsgi/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | 7 | -------------------------------------------------------------------------------- /couchdbkit/wsgi/proxy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | import urlparse 7 | 8 | from restkit.contrib.wsgi_proxy import HostProxy, ALLOWED_METHODS 9 | from webob import Request 10 | 11 | class CouchdbProxy(object): 12 | """\ 13 | WSGI application to proxy a couchdb server. 14 | 15 | Simple usage to proxy a CouchDB server on default url:: 16 | 17 | from couchdbkit.wsgi import CouchdbProxy 18 | application = CouchdbProxy() 19 | """ 20 | 21 | def __init__(self, uri="http://127.0.0.1:5984", 22 | allowed_method=ALLOWED_METHODS, **kwargs): 23 | self.proxy = HostProxy(uri, allowed_methods=allowed_method, 24 | **kwargs) 25 | 26 | def do_proxy(self, req, environ, start_response): 27 | """\ 28 | return proxy response. Can be overrided to add authentification and 29 | such. It's better to override do_proxy method than the __call__ 30 | """ 31 | return req.get_response(self.proxy) 32 | 33 | def __call__(self, environ, start_response): 34 | req = Request(environ) 35 | if 'RAW_URI' in req.environ: 36 | # gunicorn so we can use real path non encoded 37 | u = urlparse.urlparse(req.environ['RAW_URI']) 38 | req.environ['PATH_INFO'] = u.path 39 | 40 | resp = self.do_proy(req, environ, start_response) 41 | return resp(environ, start_response) 42 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | couchdbkit (0.5.4-1) karmic; urgency=low 2 | 3 | * new release 4 | 5 | -- Benoit Chesneau Fri, 18 Feb 2011 19:19:00 +0100 6 | 7 | couchdbkit (0.5.3-1) karmic; urgency=low 8 | 9 | * new release 10 | 11 | -- Benoit Chesneau Fri, 11 Feb 2011 00:00:00 +0100 12 | 13 | couchdbkit (0.5.2-1) karmic; urgency=low 14 | 15 | * new release 16 | 17 | -- Benoit Chesneau Wed, 2 Feb 2011 17:30:00 +0100 18 | 19 | couchdbkit (0.5.1-1) karmic; urgency=low 20 | 21 | * new release 22 | 23 | -- Benoit Chesneau Thu, 25 Nov 2010 17:30:00 +0100 24 | 25 | couchdbkit (0.5.0-1) karmic; urgency=low 26 | 27 | * new release 28 | 29 | -- Benoit Chesneau Thu, 25 Nov 2010 17:31:00 +0100 30 | 31 | couchdbkit (0.4.11-1) karmic; urgency=low 32 | 33 | * new release 34 | 35 | -- Benoit Chesneau Thu, 05 Aug 2010 19:22:05 +0100 36 | 37 | couchdbkit (0.4.2-1) karmic; urgency=low 38 | 39 | * Initial release 40 | 41 | -- Benoit Chesneau Mon, 22 Feb 2010 08:22:05 +0100 42 | -------------------------------------------------------------------------------- /debian/clean: -------------------------------------------------------------------------------- 1 | couchdbkit.egg-info/* 2 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: couchdbkit 2 | Section: python 3 | Priority: optional 4 | Maintainer: Benoit Chesneau 5 | Build-Depends: debhelper (>= 7), python-support, python-setuptools 6 | Standards-Version: 3.9.0.0 7 | Homepage: http://couchdbkit.org/ 8 | 9 | Package: python-couchdbkit 10 | Architecture: all 11 | Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, 12 | python-restkit(>=3.2.0) 13 | Provides: ${python:Provides} 14 | Description: Trying to improve couchdb experience in Python 15 | Couchdbkit provides you a full featured and easy client to access and 16 | manage CouchDB. It allows you to manage a CouchDB server, databases, 17 | doc managements and view access. All objects mostly reflect Python 18 | objects for convenience. 19 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008-2011 Benoit Chesneau 2 | 3 | Permission to use, copy, modify, and distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /debian/pyversions: -------------------------------------------------------------------------------- 1 | 2.5- 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | # export DH_VERBOSE=1 11 | 12 | %: 13 | dh $@ 14 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | # Example watch control file for uscan 2 | # Rename this file to "watch" and then you can run the "uscan" command 3 | # to check for upstream updates and more. 4 | # See uscan(1) for format 5 | 6 | # Compulsory line, this is a version 3 file 7 | version=3 8 | 9 | # Uncomment to examine a Webpage 10 | # 11 | #http://www.example.com/downloads.php python-couchdbkit-(.*)\.tar\.gz 12 | opts=dversionmangle=s/\+dfsg$// \ 13 | http://pypi.python.org/packages/source/c/couchdbkit/couchdbkit-(.*).tar.gz 14 | # http://github.com/benoitc/couchdbkit/downloads/ /benoitc/couchdbkit/tarball/([0-9].*) 15 | 16 | # Uncomment to examine a Webserver directory 17 | #http://www.example.com/pub/python-couchdbkit-(.*)\.tar\.gz 18 | 19 | # Uncommment to examine a FTP server 20 | #ftp://ftp.example.com/pub/python-couchdbkit-(.*)\.tar\.gz debian uupdate 21 | 22 | # Uncomment to find new files on sourceforge, for devscripts >= 2.9 23 | # http://sf.net/python-couchdbkit/python-couchdbkit-(.*)\.tar\.gz 24 | 25 | # Uncomment to find new files on GooglePages 26 | # http://example.googlepages.com/foo.html python-couchdbkit-(.*)\.tar\.gz 27 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import os, platform 3 | 4 | # options 5 | SITE_NAME = "Couchdbkit" 6 | SITE_URL = "http://www.couchdbkit.org" 7 | SITE_DESCRIPTION = "CouchdDB python framework" 8 | 9 | 10 | EXTENSIONS = ['.txt', '.md', '.markdown'] 11 | DEFAULT_TEMPLATE = "default.html" 12 | CONTENT_TYPE = "textile" 13 | 14 | 15 | # paths 16 | DOC_PATH = os.path.dirname(os.path.abspath(__file__)) 17 | TEMPLATES_PATH = os.path.join(DOC_PATH, "templates") 18 | INPUT_PATH = os.path.join(DOC_PATH, "site") 19 | OUTPUT_PATH = os.path.join(DOC_PATH, "htdocs") -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/CNAME: -------------------------------------------------------------------------------- 1 | couchdbkit.org 2 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/css/print.css: -------------------------------------------------------------------------------- 1 | * { 2 | color: #000 !important; 3 | } 4 | 5 | body { 6 | background: #fff !important; 7 | } 8 | 9 | header#site_header, #sidebar, #site_header * { 10 | display: none; 11 | } 12 | 13 | .noprint { 14 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/crarr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/doc/couchdbkit.org/htdocs/docs/api/crarr.png -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/frames.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | API Documentation 7 | 8 | 9 | 10 | 12 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | couchdbkit 7 | 8 | 9 | 10 | 11 | 13 |

Module couchdbkit

14 |
15 |

Functions

16 | set_logging

Variables

18 | LOG_LEVELS
__package__

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.changes-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | changes 7 | 8 | 9 | 10 | 11 | 13 |

Module changes

14 |
15 |

Classes

16 | ChangesStream

Functions

18 | fold
foreach

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.client-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | client 7 | 8 | 9 | 10 | 11 | 13 |

Module client

14 |
15 |

Classes

16 | Database
Server
ViewResults

Functions

20 | 23 |

Variables

24 | DEFAULT_UUID_BATCH_COUNT
UNKOWN_INFO
__package__

28 | [hide private] 30 | 31 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.consumer-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | consumer 7 | 8 | 9 | 10 | 11 | 13 |

Module consumer

14 |
15 |

Classes

16 | Consumer

Functions

18 | load_consumer_class

Variables

20 | OLD_CONSUMER_URIS
__package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.consumer.base-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base 7 | 8 | 9 | 10 | 11 | 13 |

Module base

14 |
15 |

Classes

16 | ConsumerBase

Functions

18 | check_callable

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.consumer.ceventlet-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ceventlet 7 | 8 | 9 | 10 | 11 | 13 |

Module ceventlet

14 |
15 |

Classes

16 | ChangeConsumer
ContinuousChangeConsumer
EventletConsumer
LongPollChangeConsumer

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.consumer.cgevent-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | cgevent 7 | 8 | 9 | 10 | 11 | 13 |

Module cgevent

14 |
15 |

Classes

16 | ChangeConsumer
ContinuousChangeConsumer
GeventConsumer
LongPollChangeConsumer

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.consumer.sync-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sync 7 | 8 | 9 | 10 | 11 | 13 |

Module sync

14 |
15 |

Classes

16 | SyncConsumer

Variables

18 | 21 |
22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.designer-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | designer 7 | 8 | 9 | 10 | 11 | 13 |

Module designer

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.designer.fs-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | fs 7 | 8 | 9 | 10 | 11 | 13 |

Module fs

14 |
15 |

Classes

16 | FSDoc

Functions

18 | 21 | 24 | clone
clone_design_doc
document
push
pushapps
pushdocs

Variables

31 | __package__
logger

34 | [hide private] 36 | 37 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.designer.macros-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | macros 7 | 8 | 9 | 10 | 11 | 13 |

Module macros

14 |
15 |

Functions

16 | apply_lib
package_shows
package_views
run_code_macros
run_json_macros

Variables

22 | __package__
logger

25 | [hide private] 27 | 28 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.exceptions-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | exceptions 7 | 8 | 9 | 10 | 11 | 13 |

Module exceptions

14 |
15 |

Classes

16 | BadValueError
BulkSaveError
DesignerError
DocsPathNotFound
DuplicatePropertyError
InvalidAttachment
MacroError
MultipleResultsFound
NoResultFound
PreconditionFailed
ReservedWordError
ResourceConflict
ResourceNotFound
ViewServerError

Variables

31 | __package__

33 | [hide private] 35 | 36 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ext 7 | 8 | 9 | 10 | 11 | 13 |

Module ext

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | django 7 | 8 | 9 | 10 | 11 | 13 |

Module django

14 |
15 |

Functions

16 | syncdb

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.forms-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | forms 7 | 8 | 9 | 10 | 11 | 13 |

Module forms

14 |
15 |

Classes

16 | BaseDocumentForm
DocumentForm
DocumentFormMetaClass
DocumentFormOptions

Functions

21 | document_to_dict
fields_for_document

Variables

24 | FIELDS_PROPERTES_MAPPING
__package__

27 | [hide private] 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.loading-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | loading 7 | 8 | 9 | 10 | 11 | 13 |

Module loading

14 |
15 |

Classes

16 | CouchdbkitHandler

Functions

18 | get_db
get_schema
register_schema

Variables

22 | COUCHDB_DATABASES
COUCHDB_TIMEOUT
__package__
couchdbkit_handler

27 | [hide private] 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.management-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | management 7 | 8 | 9 | 10 | 11 | 13 |

Module management

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.management.commands-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | commands 7 | 8 | 9 | 10 | 11 | 13 |

Module commands

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.management.commands.sync_couchdb-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sync_couchdb 7 | 8 | 9 | 10 | 11 | 13 |

Module sync_couchdb

14 |
15 |

Classes

16 | Command

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.management.commands.sync_finish_couchdb-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sync_finish_couchdb 7 | 8 | 9 | 10 | 11 | 13 |

Module sync_finish_couchdb

14 |
15 |

Classes

16 | Command

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.management.commands.sync_prepare_couchdb-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | sync_prepare_couchdb 7 | 8 | 9 | 10 | 11 | 13 |

Module sync_prepare_couchdb

14 |
15 |

Classes

16 | Command

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.django.testrunner-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | testrunner 7 | 8 | 9 | 10 | 11 | 13 |

Module testrunner

14 |
15 |

Classes

16 | CouchDbKitTestSuiteRunner

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | pylons 7 | 8 | 9 | 10 | 11 | 13 |

Module pylons

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.auth-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | auth 7 | 8 | 9 | 10 | 11 | 13 |

Module auth

14 |
15 |
16 | [hide private] 18 | 19 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.auth.adapters-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | adapters 7 | 8 | 9 | 10 | 11 | 13 |

Module adapters

14 |
15 |

Classes

16 | Authenticator
GroupAdapter
MDPlugin
PermissionAdapter

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.auth.basic-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | basic 7 | 8 | 9 | 10 | 11 | 13 |

Module basic

14 |
15 |

Classes

16 | BasicAuth

Functions

18 | AuthBasicMiddleware

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.auth.model-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | model 7 | 8 | 9 | 10 | 11 | 13 |

Module model

14 |
15 |

Classes

16 | Group
Permission
User

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.commands-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | commands 7 | 8 | 9 | 10 | 11 | 13 |

Module commands

14 |
15 |

Classes

16 | SyncDbCommand

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.db-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | db 7 | 8 | 9 | 10 | 11 | 13 |

Module db

14 |
15 |

Functions

16 | default_design_path
init_db
init_from_config
sync_design

Variables

21 | __package__

23 | [hide private] 25 | 26 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.ext.pylons.test-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | test 7 | 8 | 9 | 10 | 11 | 13 |

Module test

14 |
15 |

Classes

16 | FixtureLoader
TestCase

Variables

19 | __package__

21 | [hide private] 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.external-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | external 7 | 8 | 9 | 10 | 11 | 13 |

Module external

14 |
15 |

Classes

16 | External

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.loaders-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | loaders 7 | 8 | 9 | 10 | 11 | 13 |

Module loaders

14 |
15 |

Classes

16 | BaseDocsLoader
FileSystemDocLoader
FileSystemDocsLoader

Variables

20 | __package__

22 | [hide private] 24 | 25 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.resource-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | resource 7 | 8 | 9 | 10 | 11 | 13 |

Module resource

14 |
15 |

Classes

16 | CouchDBResponse
CouchdbResource

Functions

19 | encode_attachments
encode_params
escape_docid

Variables

23 | USER_AGENT
__package__
re_sp

27 | [hide private] 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.schema-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | schema 7 | 8 | 9 | 10 | 11 | 13 |

Module schema

14 |
15 |

Functions

16 | contain

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.schema.base-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | base 7 | 8 | 9 | 10 | 11 | 13 |

Module base

14 |
15 |

Classes

16 | AttachmentMixin
Document
DocumentBase
DocumentSchema
QueryMixin
ReservedWordError
SchemaProperties
StaticDocument

Functions

25 | 28 | valid_id

Variables

30 | ALLOWED_PROPERTY_TYPES
34 | 37 | 40 |
41 | [hide private] 43 | 44 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.schema.properties_proxy-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | properties_proxy 7 | 8 | 9 | 10 | 11 | 13 |

Module properties_proxy

14 |
15 |

Classes

16 | 19 | 22 | SchemaDictProperty
SchemaListProperty
SchemaProperty

Functions

26 | 29 |

Variables

30 | 33 |
34 | [hide private] 36 | 37 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.schema.util-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | util 7 | 8 | 9 | 10 | 11 | 13 |

Module util

14 |
15 |

Functions

16 | doctype_attr_of
get_multi_wrapper
maybe_schema_wrapper
schema_map
schema_wrapper

Variables

22 | __package__

24 | [hide private] 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.utils-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | utils 7 | 8 | 9 | 10 | 11 | 13 |

Module utils

14 |
15 |

Functions

16 | read_file
read_json
sign_file
split_path
splitunc
to_bytestring
validate_dbname
write_content
write_json

Variables

26 | SPECIAL_DBS
VALID_DB_NAME
__package__

30 | [hide private] 32 | 33 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.version-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | version 7 | 8 | 9 | 10 | 11 | 13 |

Module version

14 |
15 |

Variables

16 | __package__
version_info

19 | [hide private] 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.wsgi-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | wsgi 7 | 8 | 9 | 10 | 11 | 13 |

Module wsgi

14 |
15 |

Variables

16 | __package__

18 | [hide private] 20 | 21 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.wsgi.handler-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | handler 7 | 8 | 9 | 10 | 11 | 13 |

Module handler

14 |
15 |

Classes

16 | WSGIHandler
WSGIRequest

Functions

19 | 22 |

Variables

23 | __package__

25 | [hide private] 27 | 28 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/docs/api/toc-couchdbkit.wsgi.proxy-module.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | proxy 7 | 8 | 9 | 10 | 11 | 13 |

Module proxy

14 |
15 |

Classes

16 | CouchdbProxy

Variables

18 | __package__

20 | [hide private] 22 | 23 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/images/bg_header_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/doc/couchdbkit.org/htdocs/images/bg_header_new.png -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/images/gettingstarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/doc/couchdbkit.org/htdocs/images/gettingstarted.png -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/doc/couchdbkit.org/htdocs/images/logo.png -------------------------------------------------------------------------------- /doc/couchdbkit.org/htdocs/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-06-16-Couchdbkit-site-launched.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit website launched 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | Just launched **Couchdbkit** site at "couchdbkit.org":http://www.couchdbkit.org. 7 | 8 | All this website is static. For this purpose I wrote a script to generate doc and news from differents text files. The "Lamson project":http://lamsonproject.org/ used this idee for its own site, and I found it very usefull. I preferred to write mine script to allow use of jinja and some other changes (it will be possible for example to generate a cloud). 9 | 10 | I started to write documentation and more will come soon. You can follow changes via the "RSS feed":/feed.xml . -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-06-25-Couchdbkit-0.1.7-released.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.1.7 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | Just released Couchdbkit 0.1.7. 7 | 8 | Next version will be 0.2 and will have some new features : 9 | 10 | * Dump/Loads utilities 11 | * New view iterator system that would allow us to use less CPU 12 | * Aggregation : A way to combine multiple views in one 13 | * ReferenceProperty: Link documents between themselves 14 | * ... 15 | 16 | Changes for this version are following: 17 | 18 | h2. Fixes 19 | 20 | 21 | * documentation typos 22 | * database name encoding. 23 | * list are correctly handled in DictProperty 24 | 25 | h2. Breaking changes 26 | 27 | I introduced a *breaking change* in latest version of couchdbkit. Now id and rev members of `schema.Document` aren't alias to _id and _rev. It allows you to use id and rev like you want in CouchDB. It also means that you need to set yourdoc._id to set the id of a document. I made this change since it seems that a lot of you need it. So here it is. 28 | 29 | Please test it and let me know if anything is wrong. 30 | 31 | A little example : 32 | 33 |
34 |  In [1]: from couchdbkit import *
35 | 
36 |  In [2]: class A(Document):
37 |    ...:     pass
38 |    ...:
39 | 
40 |  In [3]: a = A()
41 | 
42 |  In [4]: a._id = "myid"
43 | 
44 |  In [5]: a.id = "idofapplication"
45 | 
46 |  In [6]: a._doc
47 |  Out[6]: {'_id': 'myid', 'doc_type': 'A', 'id': u'idofapplication'}
48 | 
49 |  In [7]: a._id
50 |  Out[7]: 'myid'
51 | 
52 |  In [8]: a.id
53 |  Out[8]: 'idofapplication'
54 | 
55 |  In [9]: s = Server()
56 | 
57 |  In [10]: db = s['couchdbkit_test3']
58 | 
59 |  In [11]: A._db = db
60 | 
61 |  In [12]: a.save()
62 | 
63 |  In [13]: a._doc
64 |  Out[13]:
65 |  {'_id': u'myid',
66 |  '_rev': u'1-676990679',
67 |  'doc_type': 'A',
68 |  'id': u'idofapplication'}
69 | 
70 |  In [14]: b = A.get('myid')
71 | 
72 |  In [15]: b.id
73 |  Out[15]: u'idofapplication'
74 | 
75 |  In [16]: b._id
76 |  Out[16]: u'myid'
77 | 
78 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-06-26-Couchdbkit-0.1.7.1.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.1.7.1 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | Quick fix release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.1.7.1 or check "download page":../download.html for other ways. 9 | 10 | h2. Fixes : 11 | 12 | * Compatibility of Loaders with windows 13 | * Fix DocumentForm.save in django extension 14 | * Fix "/" in database name 15 | * Fix total_rows in views -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-07-07-Couchdbkit-0.1.8.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.1.8 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.1.8 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * add ensure_full_commit method to client and allow options in save. 13 | * add `delete` method to `Document` object 14 | * add possibility to pass options to `save`, `get_or_create Document methods 15 | * add missing options to `Document.bulk_save()` 16 | 17 | h2. Fixes : 18 | 19 | * compatibility with python 2.5 20 | * iteritems is back in `DocumentSchema` 21 | * Fix LazyDict 22 | * docids with slashes are now properly encoded in all functions 23 | * Fix DocumentForm: make sure instance is passed in form. 24 | 25 | h2. Breaking changes 26 | 27 | * Accessing to document id in `Document`object is now done by using `_id` member. The same for revision (now `_rev`). It allows id and rev members. Since Django don't like get_id() and get_rev() methods have been created to allow access to these properties in templates. 28 | * Accept `unicode` instead str in `StringListProperty` -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-09-07-Couchdbkit-0.1.9.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.1.9 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.1.9 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * Replacing py-restclient with restkit. It removes dependancy on httplib2 & pycurl and add streaming possibilities. 13 | * **Streaming**: POST and PUT requests are streamed, streaming attachments from CouchDB is possible (use stream argument in fetch_attachment function) 14 | * **Use the best available json serialize/deserializer installed**. If you don't use python 2.6x or want to use a faster solution, you will need to install a json serializer. Supported json serializers are : cjson, jsonlib2, jsonlib, simplejson, and django.utils.json. To do that couchdbkit use anyjson module from the "Carrot":http://ask.github.com/carrot/ project. 15 | 16 | h2. Fixes : 17 | 18 | * removed httplib2 dependancy 19 | * Add support for custom keys in views results. Usefull for example with couchdb-lucene to get search time or other metadata. 20 | * Fix LazyList, make sure that if content_type is fixed in ListProperty we don't convert types 21 | * Django extension : support of dynamic initial values 22 | * Django extension : Fields in form are now ordered -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-09-11-Couchdbkit-0.2.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.2 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.2 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * Update to support latest features of restkit : new threadsafe support and now handle a pool of connections. 13 | * It's now possible to fetch raw json from the clients. Some methods have _raw_json params. raw view results could be retrieved with `fetch_raw` method. 14 | 15 | 16 | h2. Fixes : 17 | 18 | * Fix issues with dynamic properties 19 | * Fix db.documents iterator 20 | * Fix ext.django.forms 21 | 22 | h2. Breaking Changes 23 | 24 | The module `couchdbkit.session` don't exist anymore. Couchdbkit is now threadsafe by default due to last change in "restkit":http://bitbucket.org/benoitc/restkit/ . You don't need now to use `create_session`to make the db object threadsafe or to apply it to your 'couchdbkit.schema.Document` object. `Session.contain` has been replaced by `couchdbkit.schema.contain` function. 25 | 26 | The "tutorial":../docs/gettingstarted.html has been updated to reflect this. -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-11-05-Couchdbkit-0.2.2.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.2.2 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. This release fix a lot of oddities from previous version. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.2.2 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * Depends on new restkit 0.8.4 witch improve error handling and performances. 13 | * Create a Database object from full url without passing dbname in `Database.from_uri` function Database.from_uri("http://127.0.0.1:5984/couchdbkit_test") 14 | * Use of anyjson for serializing. It allows you to choose the json serializer you need. It also means that if you don't use python 2.6 or above you will need to install one. 15 | * add support for update and filters functions in loader. (backport from couchapp) 16 | * Add simple replication handler in server object 17 | 18 | 19 | h2. Fixes : 20 | 21 | * Updated doc 22 | * Don't reserver `type` property 23 | * Fix view results params 24 | * Remove malformed views when uploading with loaders 25 | * Make sure rev is updated afetr we delete an attachment 26 | * Make sure we don't reencode urls 27 | * Some fixes in django extension 28 | * Make ListProperty & DictProperty lazy -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-11-22-Couchdbkit-0.2.4.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.2.4 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. This release fix a lot of oddities from previous version. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.2.4 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * Depends on new restkit 0.8.8 - support timeout, latest webbob exceptions, handle connection reset 13 | * new property: ListSchemaProperty. Allow you to savec and validate a list of DocumentSchema object 14 | * db.compact function has now a dname argyment - allow you to compact views handled by the design doc named `dname` 15 | * db.view_cleanup function - Old view output remains on disk until you explicitly run cleanup 16 | * if conflicts or any other error in bulk_save, BulkSaveError is now raised. You can get list of documents in errors by using `error` property of this exception. 17 | * allow django extension to set timeout in settings -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2009-12-07-Couchdbkit-0.3.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.3 released - pre-awesome 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. This release fix a lot of oddities from previous version and prepare for next version. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.3 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * Updated Resource and client objects to handle restkit 0.9. It means that now you can stream all response from CouchDB in raw mode. Also errors returned are better. This is a big change. It will allow next features to come. 13 | * new property Server.uuids 14 | * Fix: don't spot `_all_dbs` each time we want to test if a db exists. 15 | * Fix: doc with revisions 16 | * Fix: macros -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-01-08-Couchdbkit-0.4.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. More fixes and new `External` and *_changes* `Consumer`. The 0.4 branch is the last branch with suport for 0.9x / 0.10x versions of CouchDB. Next releases will support only 0.11/trunk and 1.0 versions and will support python3. The "TODO":http://bitbucket.org/benoitc/couchdbkit/src/tip/TODO.txt has been updated. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4 or check "download page":../download.html for other ways. 9 | 10 | h2. New features : 11 | 12 | * `External` module. This module allows you to create easily "external handler":http://wiki.apache.org/couchdb/ExternalProcesses for couchdb. There is a little "tutorial":../docs/external.html about it. There is also in contrib an external allowing you to use "wsgi":http://www.python.org/dev/peps/pep-0333/ applications as external handler. See "example":http://bitbucket.org/benoitc/couchdbkit/src/tip/examples/wsgi/test.py . 13 | * *_changes* Consumer. With this modules you can listen on "db changes":http://wiki.apache.org/couchdb/HTTP_database_API#Changes, simple changes call, longpolling and continuous changes are supported. See the "doc":../docs/changes_consumer.html about it. 14 | 15 | h2. Fixes : 16 | 17 | * "__iter__":http://bitbucket.org/benoitc/couchdbkit/changeset/c455068b5c59/ in `Document schema` object has been fixed 18 | * `save_doc` method of a db instance can "return full result":http://bitbucket.org/benoitc/couchdbkit/changeset/891c76027721/ . Useful to manage conflicts. 19 | * some typos fixed in doc 20 | * installation with distribute 21 | * db.flush refactored 22 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-01-25-Couchdbkit-0.4.1.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4 1 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. More fixes 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4 or check "download page":../download.html for other ways. 9 | 10 | h2. Fixes : 11 | 12 | * use "doc" in view result for default wrapper used by `schema.Document.view` until "wrap_doc" argument is set to False. 13 | * Add sleep for db.flush which remove CouchDB traces on some systems. 14 | * some typos fixed in doc 15 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-02-04-CouchdbKit-0.4.2.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4.2 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. More fixes 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4 or check "download page":../download.html for other ways. 9 | 10 | 11 | h2. New features : 12 | 13 | * Database.from_uri is deprecated. Insteade use `Database.__init__`: 14 | 15 | db = Database("http://127.0.0.1:5984/somedb") 16 | 17 | * Add `Database.get_rev` method allowing you to get last revision of a document. 18 | * Add add force_update option to `Database.save_doc`, if a conflict is raised and force_update 19 | is True, it will get latest rev and place it inyour doc object and will try to save. 20 | 21 | 22 | h2. Fixes : 23 | 24 | * Fix None value in `Schema` properties 25 | * Validate against basestring in `Schema.StringListProperty` 26 | * Fix packages install. Remove tests from installed packages. -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-02-24-move-to-github.txt: -------------------------------------------------------------------------------- 1 | title: Sources and Tracker have been moved to github 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | Since I worked more and more with git and "github":http://github.com/benoitc, I decided to move Couchdbkit and Restkit to it: 7 | 8 | * "couchdbkit":http://github.com/benoitc/couchdbkit 9 | * "restkit":http://github.com/benoitc/restkit 10 | 11 | All the history have been imported and new development will take place there. 12 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-02-28-restkit-update.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4.2 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. CouchDBKit have been updated to support "restkit":http://benoitc.github.com/restkit 1.0. 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4.3 or check "download page":../download.html for other ways. 9 | 10 | 11 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-06-28-CouchdbKit-0.4.7.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4.7 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. More fixes 7 | 8 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4.7 or check "download page":../download.html for other ways. 9 | 10 | Couchdbkit 0.4.7 has lot of fixes since last reported version and is compatible with CouchDB 0.10.2, 0.11.0 and trunk. 11 | 12 | In particularly, *Server.replication* method has now all new parameters. Couchdbkit 0.4.7 also rely on "restkit 2.0":http://benoitc.github.com/restkit which give you a lot of performance improvements. 13 | 14 | You can find a summary of changes on "github":http://github.com/benoitc/couchdbkit/compare/0.4.2...0.4.7 . -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-07-20-CouchdbKit-0.4.9.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.4.9 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | * Added Server.close() and Database.close() method. clear the connections pool 9 | * Allows any parameters to be used in replication 10 | * Fix consumer 11 | * Fix loader 12 | 13 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.4.9 or check "download page":../download.html for other ways. 14 | 15 | You can find a summary of changes on "github":http://github.com/benoitc/couchdbkit/comp -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2010-11-25-Couchdbkit-0.5.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.5 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. Lot of change in this release. It's now based on latest "restkit":http://benoitc.github.com/restkit 2.3.0 so make sure to upgrade it before upgrading. 7 | 8 | h2. What's new ? 9 | 10 | * new `couchdbkit.designer` module. the `couchdbkit.loaders` module is now deprecated. Instead use push, pushapps, pushdocs & clone functions. They are all compatible with couchapp. 11 | * Use the Database instances to save Documents objects. 12 | 13 |
14 |  import datetime
15 |  
16 |  from couchdbkit import *
17 | 
18 |  s = Server()
19 |  db = s["mydb"]
20 | 
21 |  class Greeting(Document):
22 |       author = StringProperty()
23 |       content = StringProperty()
24 |       date = DateTimeProperty()
25 | 
26 |  greet = Greeting(
27 |      author="Benoit",
28 |      content="Welcome to couchdbkit world",
29 |      date=datetime.datetime.utcnow()
30 |  )
31 |  db.save_doc(greet)
32 | 
33 | 34 | * new pylons extension, thanks to Alfred Hall. Like django extension it will help you to use couchdbkit in pylons 35 | * Added gevent & eventlet consumers. The "doc":http://couchdbkit.org/docs/changes_consumer.html has been updated. 36 | * New **SchemaDict** property 37 | * Added oauth support via restkit 38 | * Lazy db loading in django extension 39 | * No more _raw_json function. For proxying use the CouchdbResource object. 40 | * breaking changes. We are now using simplejson instead of anyjson. 41 | * Simplejson give us better JSON serialization. 42 | * Fixed BooleanProperty 43 | * support for ISO-8601 DateTime format with a timezone offset 44 | 45 | You can download latest release on "Pypi":http://pypi.python.org/pypi/couchdbkit/0.5 or check "download page":../download.html for other ways. 46 | 47 | You can find a summary of changes on "github":http://github.com/benoitc/couchdbkit/comp 48 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2011-02-18-Couchdbkit-0.5.4.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.5.5 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | 9 | It's now based on latest "restkit":http://benoitc.github.com/restkit 3.2.0 so make sure to upgrade it before 10 | upgrading. I will try to resume main changes since 0.5.0. I've failed to 11 | update this blog since, sorry for that. 12 | 13 | Full changelog is also "here":https://github.com/benoitc/couchdbkit/compare/0.5.0...0.5.4 14 | 15 | h2. What's new ? 16 | 17 | * New SchemaDict property, store dict of things. 18 | 19 | Usage: 20 | "restkit":http://benoitc.github.com/restkit 3.2.0 21 |
22 |  class A(DocumentSchema):
23 |      # some properties
24 |      pass
25 | 
26 |  class B(Document):
27 |      p = SchemaDictProperty(A)
28 | 
29 |  a1 = A()
30 |  a2 = A()
31 |  b = B()
32 |  b.p['str'] = a1
33 |  b.p[12345] = a2
34 | 
35 | 36 | * support ISO-8601 DateTime format with a timezone offset in 37 | DateTimeProperty 38 | * TestRunner in django extension 39 | * Query views can return different Document instance based on doc_type 40 | * Many fixes. 41 | 42 | 43 | You can download latest release on 44 | "Pypi":http://pypi.python.org/pypi/couchdbkit/0.5.4 or check "download page":../download.html for other ways. 45 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2012-01-26-Couchdbkit-0.6.0.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.6.0 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | 9 | It's now based on latest "restkit":http://benoitc.github.com/restkit 10 | 4.0x so make sure to upgrade it before upgrading. I 11 | Full changelog is also 12 | "here":https://github.com/benoitc/couchdbkit/compare/0.5.4...0.6.0 13 | 14 | h2. What's new ? 15 | 16 | * new changes API 17 | * based on unitests2 18 | * Fix django support 19 | * Lot of fixes 20 | 21 | 22 | You can download latest release on 23 | "Pypi":http://pypi.python.org/pypi/couchdbkit/0.6.0 or check "download page":../download.html for other ways. 24 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/2012-05-04-Couchdbkit-0.6.2.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit version 0.6.2 released 2 | content_type: textile 3 | page_type: blog 4 | template: blog/post.html 5 | 6 | New release for "Couchdbkit":http://couchdbkit.org. 7 | 8 | 9 | Compare changes from 0.6.1 to 0.6.2 on 10 | "github":https://github.com/benoitc/couchdbkit/compare/0.6.1...0.6.2 . 11 | 12 | 13 | 14 | 15 | You can download latest release on 16 | "Pypi":http://pypi.python.org/pypi/couchdbkit/0.6.0 or check "download page":../download.html for other ways. 17 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/archives.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit news 2 | content_type: textile 3 | page_type: blog 4 | template: blog/archives.html 5 | 6 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/blog/index.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit news 2 | content_type: textile 3 | page_type: blog 4 | template: blog/index.html 5 | 6 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/contact.txt: -------------------------------------------------------------------------------- 1 | title: Getting help with Couchdbkit 2 | 3 | There is a mailing-list for now on "Google 4 | groups":http://groups.google.com/group/couchdbkit where you can follow changes 5 | and ask questions about Couchdbkit. You can also chat with users and 6 | developers on "#couchdbkit irc channel":irc://irc.freenode.net/couchdbkit or 7 | send a ticket on "bitbucket":http://github.com/benoitc/couchdbkit/. 8 | 9 | The best way to get help with Couchdbkit is to email me directly at 10 | "benoitc@e-engura.org":mailto:benoitc@apache.org . 11 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/about.txt: -------------------------------------------------------------------------------- 1 | title: About CouchdbKit 2 | 3 | **CouchDBKit** is a framework to allow your python application to use "Apache CouchDB":http://couchdb.apache.org. 4 | 5 | I started it for a project in my own company, **"Enki Multimedia":http://e-engura.org** but it since evolved in a completely new library though some code is still based on it. I decided to make it public. -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/changes.txt: -------------------------------------------------------------------------------- 1 | title: Listen to database changes 2 | page_type: blog 3 | 4 | couchdbkit 0.6.0 introduced a new API to listen for CouchDB changes. 5 | 6 | 7 | The `couchdbkit.changes` modules allows you to listen for changes with a 8 | streaming API. 9 | 10 | h2. Stream changes in your application: 11 | 12 | To listen for change, instantiate the `couchdbkit.changes.ChangesStream` 13 | object and iterrate it: 14 | 15 |
 16 |     from couchdbkit import Server
 17 |     from couchdbkit.changes import ChangesStream, fold, foreach
 18 | 
 19 | 
 20 |     s = Server()
 21 |     db = s['testdb']
 22 |     stream = ChangesStream(db, feed="continuous", heartbeat=True)
 23 | 
 24 |     print "got change now"
 25 |     for change in stream:
 26 |         print change
 27 | 
28 | 29 | 30 | You can also use it as a context: 31 | 32 |
 33 |     from couchdbkit import Server
 34 |     from couchdbkit.changes import ChangesStream, fold, foreach
 35 | 
 36 | 
 37 |     s = Server()
 38 |     db = s['testdb']
 39 |     with ChangesStream(db, feed="continuous", heartbeat=True) as stream:
 40 |         for change in stream:
 41 |             print change
 42 | 
43 | 44 | Note: if you want to use it with gevent, you can just setup a gevent 45 | pool: 46 | 47 | 48 |
 49 |     from couchdbkit import Server
 50 |     from couchdbkit.changes import ChangesStream, fold, foreach
 51 | 
 52 |     from restkit.conn import Connection
 53 |     from socketpool.pool import ConnectionPool
 54 | 
 55 |     pool = ConnectionPool(factory=Connection, backend="gevent")
 56 | 
 57 |     s = Server(pool=pool)
 58 |     db = s['testdb']
 59 |     with ChangesStream(db, feed="continuous", heartbeat=True) as stream:
 60 |         for change in stream:
 61 |             print change
 62 | 
63 | 64 | For more information about creating a greened pool, read the restkit 66 | documentation. 67 | 68 | 69 | You can of course spawn or do anything you want with the gevent or 70 | eventlet libraries. 71 | 72 | h2. fold changes: 73 | 74 | `couchdbkit.changes.fold` allows you to fold all changes and pass 75 | the change to a function, while collecting results to an accumularor. 76 | The accumulator is returned at the end of the changes. 77 | 78 | Exemple to fetch all changes in a streaming fashion: 79 | 80 |
 81 |     def fold_fun(c, acc):
 82 |         acc.append(c)
 83 |         return acc
 84 | 
 85 |     acc = fold(db, fold_fun, [])
 86 | 
87 | 88 | 89 | Note: The function take an optionnal `since` parameter. 90 | 91 | h2. Iterrate all changes 92 | 93 | `couchdbkit.changes.foreach` allows you to itterate all changes and pass 94 | the change to a function: 95 | 96 |
 97 |     def print_change(c):
 98 |         print c
 99 | 
100 |     foreach(db, print_change)
101 | 
102 | 103 | Note: The function take an optionnal `since` parameter. 104 | 105 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/changes_consumer.txt: -------------------------------------------------------------------------------- 1 | title: Listen to database changes 2 | page_type: blog 3 | 4 | Since the "0.10 release":http://couchdb.apache.org/downloads.html of CouchDB, it's possible to listen on "db changes":http://wiki.apache.org/couchdb/HTTP_database_API#Changes via the REST api. 5 | 6 | The `couchdbkit.Consumer` object provides you a way to listen on these changes asynchronously (continuous changes) or just wait for one change (longpolling). You can of course just fetch changes since the last update sequence. 7 | 8 | h1. DEPRECATED 9 | 10 | This api is now deprecated. Since the changes API instead. 11 | 12 | h2. Create a consumer 13 | 14 | To create a consumer, instantiate the `couchdbkit.Consumer` object like this. 15 | 16 |
17 | 	>>> from couchdbkit import Server, Consumer
18 | 	>>> s = Server()
19 | 	>>> db = s.create_db("mydb")
20 | 	>>> c = Consumer(db)
21 | 
22 | 23 | A consumer object is initialized with the db instance on which you want 24 | to listen changes. The default backend use standard library asyncore, 25 | but you can also use gevent and eventlet backend: 26 | 27 |
28 |     >>>  c = Consumer(db, backend='gevent')
29 | 
30 | 31 | 32 | h2. Fetch changes 33 | 34 |
35 | 	>>> db.save_doc({})
36 | 	{'rev': '1-967a00dff5e02add41819138abb3284d',
37 | 	 'ok': True, 'id': 'e3453543865212eede756809f71436c5'}
38 | 	>>> db.save_doc({})
39 | 	{'rev': '1-967a00dff5e02add41819138abb3284d', 
40 | 	'ok': True, 'id': 'b0ec8a9287cc53b00c1d621720e8144d'}
41 | 	>>> c.fetch(since=0)
42 | 	{'last_seq': 2, 'results': [{'changes': 
43 | 	[{'rev': '1-967a00dff5e02add41819138abb3284d'}], 
44 | 	'id': 'e3453543865212eede756809f71436c5', 'seq': 1}, 
45 | 	{'changes': [{'rev': '1-967a00dff5e02add41819138abb3284d'}], 
46 | 	'id': 'b0ec8a9287cc53b00c1d621720e8144d', 'seq': 2}]}
47 | 
48 | 49 | 50 | Here we get all changes since the db has been created via `fetch` method of `Consumer` instance. 51 | 52 | h3. Listen for changes 53 | 54 | There are 2 possibilities in CouchDB to listen for changes. You can wait until a change happen in the db (longpolling) and close connection or you can just listen on each changes events and handle them in one function. 55 | 56 | To wait for a change you may want to use the `wait_once` function. To wait a change since the last sequence: 57 | 58 |
59 |  >>> c.wait_once(since=2)
60 |  {'last_seq': 3, 'results': [{'changes': 
61 |  [{'rev': '1-967a00dff5e02add41819138abb3284d'}], 
62 |  'id': '70958b546d1f214d221c6a16648d3a2b', 'seq': 3}]}
63 | 
64 | 65 | `wait_once` will wait until a change happen or until connection timeout. Using `timeout` args or `heartbeat` you can set timeout or keep connection open. 66 | 67 | To listen on changes asynchronously and react on them, you have to use the `wait` method. This method using Python `asyncore` module, will wait on new changes lines and send these lines to the functions you registered as callaback : 68 | 69 |
70 |  >>> def print_line(line):
71 |  ...     print "got %s" % line
72 |  ... 
73 |  >>> c.register_callback(print_line)
74 |  >>> c.wait() # Go into receive loop
75 | 
76 | 77 | 78 | By default it will wait infinitely, connection is kept alive. 79 | 80 | h2. Filter changes 81 | 82 | `wait_once` and `wait` method allow you to use design docs filter's functions to filter changes. Ex: 83 | 84 |
85 |  >>> c.wait(filter_name="mydesign/filtername")
86 | 
87 | 88 | `filter_name` argument take the design doc name and filter function name as string. 89 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/external.txt: -------------------------------------------------------------------------------- 1 | title: Build an external handler 2 | page_type: blog 3 | 4 | Building an "external handler":http://wiki.apache.org/couchdb/ExternalProcesse with couchdbkit is easy. The only thing you have to do is to create an object inheriting from `couchdbkit.external` module. 5 | 6 | Here is a little snippet that shows you how to handle the "example external process from CouchDB wiki":http://wiki.apache.org/couchdb/ExternalProcesse#Example_External_Process with couchdbkit. 7 | 8 |
 9 |  from couchdbkit.external import External
10 |  import anyjson
11 | 
12 |  class Test(External):
13 | 
14 |      def handle_line(self, line):
15 |          self.send_response(200, 
16 |              "got message external object %s" % anyjson.serialize(line),
17 |              {"Content-type": "text/plain"})
18 | 
19 |  if __name__ == "__main__":
20 |      Test().run()
21 | 
22 | 23 | 24 | All lines received by the external handler are handled in `handle_line` method of External instance. Then the `send_response` method can be used to send the response. It takes the http status code, body and headers as arguments. `This method is a wrapper around `write` method of your instance. 25 | 26 | `couchdbkit.External` interface has been used to build the wsgi external handler. Its "code":http://bitbucket.org/benoitc/couchdbkit/src/5d7bb0ebf3f4/couchdbkit/contrib/wsgi_handler.py is also a good example of use. 27 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/faq.txt: -------------------------------------------------------------------------------- 1 | title: Frequently Asked questions 2 | 3 | h2. What is CouchdbKit? 4 | 5 | Couchdbkit's goal is to provide a framework for your Python application to access and manage Couchdb. It provides you a full featured and easy client to access and manage CouchDB. It allow you to manage a CouchDB server, databases, doc managements and view access. All objects mostly reflect python objects for convenience. Server and Databases objects could be used for example as easy as using a dict. 6 | 7 | h2. What about other libraries? 8 | 9 | I'm not trying to compare them to mine. Couchdbkit follows its own way. 10 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/formalchemy.txt: -------------------------------------------------------------------------------- 1 | title: Formalchemy extension 2 | page_type: blog 3 | 4 | In the "Django extension":/docs/django-extension.html, I wrote the object `DocumentForm` that allows you to create a Django Form class based on a Document class or instance of a Document. 5 | 6 | But you don't need to use Django to have this facility in your web application. If you use "Pylons":http://pylonshq.com/ you may already know "FormAlchemy":http://code.google.com/p/formalchemy/. FormAlchemy was originaly developped to map "SQLAlchemy":http://www.sqlalchemy.org/ object in a form but it now contains an extension for Couchdbkit too. 7 | 8 | h2. How to use it? 9 | 10 | Once again we have our Document `Greeting` 11 | 12 |
13 |  from couchdbkit import *
14 |  
15 |  class Greeting(Document):
16 |      author = StringProperty()
17 |      content = StringProperty(required=True)
18 |      date = DateTimeProperty(default=datetime.utcnow)
19 | 
20 | 21 | The couchdbkit extension of FormAlchemy is in module `formalchemy.ext.couchdb`. To map our document to a FormAlchemy do : 22 | 23 |
24 |  from formalchemy.ext.couchdb import FieldSet
25 |  
26 |  fs = FieldSet(Greeting)
27 |  greet = Greeting(
28 |      author="Benoit",
29 |      content="Welcome to simplecouchdb world",
30 |      date=datetime.datetime.utcnow()
31 |  )
32 |  fs = fs.bind(greet)
33 | 
34 | 35 | And that's it. 36 | 37 | For more information about FormAlchemy, please check its "documentation":http://docs.formalchemy.org/ . 38 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/index.txt: -------------------------------------------------------------------------------- 1 | title: Couchdbkit Documentation 2 | page_type: blog 3 | template: docs/index.html 4 | 5 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/docs/storing_docs_and_designdocs_on_filesystem.txt: -------------------------------------------------------------------------------- 1 | title: Storing design documents and views on the filesystem 2 | page_type: blog 3 | 4 | Couchdbkit allows you to manage you design docs and docs on the file system. 5 | 6 | A system will be provided to manage view creation and other things. As some noticed, this system works like "couchapp":http://github.com/couchapp/couchapp/tree/. 7 | 8 | !/images/gettingstarted.png(couchdbkit textmate screen)! 9 | 10 | 11 | h2. Create a design document 12 | 13 | Let's create a folder that contains the design doc, and then the folder for the view. On unix : 14 | 15 |
16 |  mkdir -p ~/Work/couchdbkit/example/_design/greeting/views/all
17 | 
18 | 19 | In this folder we edit a file `map.js`: 20 | 21 |
22 |  function(doc) { 
23 |    if (doc.doc_type == "Greeting") 
24 |     emit(doc._id, doc); 
25 |  }
26 | 
27 | 28 | h2. Synchronize design documents on the database 29 | 30 | Then we use `FileSystemDocsLoader` object to send the design document to CouchDB: 31 | 32 |
33 |  from couchdbkit.loaders import FileSystemDocsLoader
34 |  
35 |  loader = FileSystemDocsLoader('/path/to/example/_design')
36 |  loader.sync(db, verbose=True)
37 | 
38 | 39 | The design doc is now in the `greetings` database and you can get all greets : 40 | 41 |
42 |  greets = Greeting.view('greeting/all')
43 | 
44 | 45 | 46 | You can automate this when you start your application. This what "Friendpaste":http://friendpaste.com do by running python manage.py setup on first bootstrap. -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/download.txt: -------------------------------------------------------------------------------- 1 | title: Downloading Couchdbkit 2 | 3 | This is a manual for installing Couchdbkit and its dependencies. 4 | 5 | h2. 1. Installing CouchDB 6 | 7 | Couchdbkit requires couchdb 0.11 or later to use it. 8 | 9 | To install Couchdb follow the documentation on "CouchDB wiki":http://wiki.apache.org/couchdb/Installation . 10 | 11 | h2. 2. Installing Couchdbkit 12 | 13 | Couchdbkit requires python2.x >= 2.6.0 to work. python 3.x will be supported soon. 14 | 15 | To install couchdbkit using pip you must make sure you have a 16 | recent version of distribute installed: 17 | 18 |
19 |     $ curl -O http://python-distribute.org/distribute_setup.py
20 |     $ sudo python distribute_setup.py
21 |     $ easy_install pip
22 | 
23 | 24 | To install or upgrade to the latest released version of couchdbkit: 25 | 26 |
27 |     $ pip install couchdbkit
28 | 
29 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/site/index.txt: -------------------------------------------------------------------------------- 1 | title: Welcome to the Couchdbkit project 2 | content_type: html 3 | template: index.html 4 | 5 | 6 |
7 |
8 | 9 |

CouchDB framework in Python

10 | 11 |

Couchdbkit provides you a full featured and easy client to access and manage CouchDB. It allows you to manage a CouchDB server, databases, doc managements and view access. All objects mostly reflect python objects for convenience. Server and Databases objects could be used for example as easy as using a dict.

12 | 13 |
14 | from couchdbkit import Server
15 | 
16 | s = Server()
17 | 
18 | db = s.create_db("couchbdkit_test")
19 | db['someid'] = { 'test': 'essai' }
20 | doc = db['someid']
21 | 
22 | 23 |

Map couchdb object to python object easily with dynamic schema. It's similar to ORMs but with all the couchdb awesomeness.

24 | 25 |
26 | from couchdbkit import Document
27 | 
28 | class Greeting(Document):
29 |     author = StringProperty()
30 |     content = StringProperty()
31 |     date = DateTimeProperty()
32 |     
33 | greet = Greeting()
34 | greet.author = "Me"
35 | greet.homepage = "http://couchdbkit.org"
36 | 
37 |

Manage easily design docs in your Python application with loaders.

38 |
39 | from couchdbkit.designer import pushapps
40 | 
41 | pushapps('/path/to/designs', db)
42 | 
43 | 
44 | 45 |
46 |
47 |

Next steps

48 |

Grab the code and you can read through the getting started tutorial. After you've gone through that, best thing to do is read the documentation on this site.

49 |

If you need help, don't hesitate to contact me.

50 |
51 | 52 |
53 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/blog/archives.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | {{ title }} 5 | {% endblock %} 6 | 7 | {% block content %} 8 | 9 |
10 | 15 |
16 | {% endblock %} -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/blog/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}{{ title }}{% endblock %} 3 | 4 | 5 | 6 | {% block content %} 7 |
8 |

couchdbkit project blog

9 | {% for item in entries %} 10 | 20 | {% endfor %} 21 | 22 | 23 | 24 |
25 | {% endblock %} 26 | 27 | {% block script %} 28 | 43 | 44 | {% endblock %} -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/blog/post.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | {{ title }} 5 | {% endblock %} 6 | 7 | {% block content %} 8 | 9 |
10 |
11 |
12 |

{{ title }}

13 |
14 | {{ body }} 15 | 18 |
19 |
blog comments powered by Disqus 20 |
21 | {% endblock %} 22 | 23 | {% block script %} 24 | 39 | 40 | {% endblock %} -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/default.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %}{{ title }}{% endblock %} 4 | 5 | {% block content %} 6 |
7 |
8 |

{{ title }}

9 | {{ body }} 10 |
11 |
12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/docs/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block title %}{{ title }}{% endblock %} 3 | 4 | {% block content %} 5 |
6 |

{{ title }}

7 | {% for item in entries %} 8 | 17 | {% endfor %} 18 |
19 | {% endblock %} -------------------------------------------------------------------------------- /doc/couchdbkit.org/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block title %} 4 | {{ title }} 5 | {% endblock %} 6 | 7 | {% block head %} 8 | 9 | {% endblock %} 10 | 11 | {% block top %} 12 | 13 |
14 |
15 |
16 | 17 |

CouchDB framework in Python

18 | 19 |

Apache CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API. Among other features, it provides robust, incremental replication with bi-directional conflict detection and resolution, and is queryable and indexable using a table-oriented view engine with JavaScript acting as the default view definition language.

20 | 21 |

Couchdbkit goal is to provide a framework for your Python application to access and manage Couchdb.

22 |
23 | 24 |
25 | 26 |

Features

27 |
    28 |
  • a full client always in sync with latest couchdb releases or trunk. Currently you can use full features of couchdb 0.9 and latest trunk
  • 29 |
  • a client allowing you to use the http backend you want via py-restclient. Currently curl or httplib. You could also write your own, see transports documentation of py-restclient.
  • 30 |
  • threadsafe
  • 31 |
  • A system to attach design docs to your application and send them to CouchDB.
  • 32 |
  • Manage documents with dynamic schema. Documents are completely dynamic
  • 33 |
34 |

Getting started

35 |
36 |
37 |
38 | {% endblock %} 39 | 40 | {% block content %} 41 | 42 | 43 | {{ body }} 44 | {% endblock %} -------------------------------------------------------------------------------- /examples/django_blogapp/REQUIREMENTS.txt: -------------------------------------------------------------------------------- 1 | Django==1.5.4 2 | argparse==1.2.1 3 | couchdbkit==0.6.5 4 | http-parser==0.8.3 5 | restkit==4.2.2 6 | socketpool==0.5.3 7 | wsgiref==0.1.2 8 | -------------------------------------------------------------------------------- /examples/django_blogapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/django_blogapp/__init__.py -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/django_blogapp/blog_app/__init__.py -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/_design/views/all_posts/map.js: -------------------------------------------------------------------------------- 1 | function(doc) { 2 | if (doc.doc_type == "Post") 3 | emit(doc._id, doc); 4 | } 5 | -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/_design/views/commets_by_post/map.js: -------------------------------------------------------------------------------- 1 | function(doc) { 2 | if (doc.doc_type == "Comment") { 3 | emit(doc.post, doc); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/models.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | from couchdbkit.ext.django.schema import Document, StringProperty, \ 4 | DateTimeProperty 5 | 6 | 7 | class Post(Document): 8 | author = StringProperty() 9 | title = StringProperty() 10 | content = StringProperty() 11 | date = DateTimeProperty(default=datetime.utcnow) 12 | 13 | class Comment(Document): 14 | author = StringProperty() 15 | content = StringProperty() 16 | date = DateTimeProperty(default=datetime.utcnow) 17 | post = StringProperty() 18 | -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates writing tests using the unittest module. These will pass 3 | when you run "manage.py test". 4 | 5 | Replace this with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | 11 | class SimpleTest(TestCase): 12 | def test_basic_addition(self): 13 | """ 14 | Tests that 1 + 1 always equals 2. 15 | """ 16 | self.assertEqual(1 + 1, 2) 17 | -------------------------------------------------------------------------------- /examples/django_blogapp/blog_app/views.py: -------------------------------------------------------------------------------- 1 | from couchdbkit.ext.django.forms import DocumentForm 2 | from django.forms.fields import CharField 3 | from django.forms.widgets import HiddenInput 4 | from django.shortcuts import render_to_response 5 | from django.template import RequestContext 6 | 7 | from models import Post, Comment 8 | 9 | 10 | class PostForm(DocumentForm): 11 | 12 | class Meta: 13 | document = Post 14 | 15 | class CommentForm(DocumentForm): 16 | 17 | post = CharField(widget=HiddenInput(), required=False) 18 | 19 | class Meta: 20 | document = Comment 21 | 22 | def home(request): 23 | post = None 24 | form = PostForm(request.POST or None) 25 | 26 | if request.POST: 27 | if form.is_valid(): 28 | post = form.save() 29 | 30 | posts = Post.view('blog_app/all_posts', descending=True) 31 | 32 | return render_to_response("home.html", { 33 | "form": form, 34 | "post": post, 35 | "posts": posts 36 | }, context_instance=RequestContext(request)) 37 | 38 | def view_post(request, post_id): 39 | post = Post.get(post_id) 40 | form = CommentForm(request.POST or None) 41 | 42 | if request.POST: 43 | if form.is_valid(): 44 | form.cleaned_data['post'] = post_id 45 | form.save() 46 | 47 | comments = Comment.view('blog_app/commets_by_post', key=post_id) 48 | 49 | return render_to_response("post_details.html", { 50 | "form": form, 51 | "post": post, 52 | "comments": comments 53 | }, context_instance=RequestContext(request)) 54 | 55 | def edit_post(request, post_id): 56 | post = Post.get(post_id) 57 | form = PostForm(request.POST or None, instance=post) 58 | 59 | if form.is_valid(): 60 | post = form.save() 61 | 62 | return render_to_response("post_edit.html", { 63 | "form": form, 64 | "post": post 65 | }, context_instance=RequestContext(request)) -------------------------------------------------------------------------------- /examples/django_blogapp/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Super Blog Application 6 | 7 | 8 |
9 |

Blog app

10 |
11 | 12 | {% block content %}{% endblock %} 13 | 14 |
15 | 16 | -------------------------------------------------------------------------------- /examples/django_blogapp/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |

Create new Post

6 |
7 | 8 | {{ form.as_table }} 9 |
10 | {% csrf_token %} 11 | 12 |
13 | 14 | {% if post %} 15 | {{ post.get_id }} was added 16 | {% endif %} 17 |
18 |

Posts

19 | 20 | {% for p in posts %} 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 |
{{ p.date|timesince }} ago. by {{ p.author }} {{ p.title }}
28 | {% endblock content %} -------------------------------------------------------------------------------- /examples/django_blogapp/templates/post_details.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |

{{ post.title }}

6 |

by {{ post.author }}

7 |

{{ post.content }}

8 |
9 |

Posted {{ post.date|timesince }} ago.

10 | 11 |
12 | 13 |

Edit Post

14 | 15 |
16 | 17 |

Comments

18 | 19 | 20 | {% for c in comments %} 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 |
{{ c.author }}: {{ c.content }} {{ c.date|timesince }} ago.
28 | 29 |

Leave a comment!

30 |
31 | 32 | {{ form.as_table }} 33 |
34 | {% csrf_token %} 35 | 36 |
37 | 38 | {% endblock content %} -------------------------------------------------------------------------------- /examples/django_blogapp/templates/post_edit.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |

Editing Post {{ post.title }}

6 |
7 | 8 | {{ form.as_table }} 9 |
10 | {% csrf_token %} 11 | 12 |
13 | {% endblock content %} -------------------------------------------------------------------------------- /examples/django_blogapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, url 2 | 3 | 4 | urlpatterns = patterns('', 5 | url(r'^$', 'django_blogapp.blog_app.views.home'), 6 | url(r'^post/(?P\w*)/$', 'django_blogapp.blog_app.views.view_post'), 7 | url(r'^post/edit/(?P\w*)/$', 'django_blogapp.blog_app.views.edit_post'), 8 | ) 9 | -------------------------------------------------------------------------------- /examples/django_blogapp/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for django_blogapp project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | # We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks 19 | # if running multiple sites in the same mod_wsgi process. To fix this, use 20 | # mod_wsgi daemon mode with each site in its own daemon process, or use 21 | # os.environ["DJANGO_SETTINGS_MODULE"] = "django_blogapp.settings" 22 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_blogapp.settings") 23 | 24 | # This application object is used by any WSGI server configured to use this 25 | # file. This includes Django's development server, if the WSGI_APPLICATION 26 | # setting points here. 27 | from django.core.wsgi import get_wsgi_application 28 | application = get_wsgi_application() 29 | 30 | # Apply WSGI middleware here. 31 | # from helloworld.wsgi import HelloWorldApplication 32 | # application = HelloWorldApplication(application) 33 | -------------------------------------------------------------------------------- /examples/djangoapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/djangoapp/__init__.py -------------------------------------------------------------------------------- /examples/djangoapp/greeting/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/djangoapp/greeting/__init__.py -------------------------------------------------------------------------------- /examples/djangoapp/greeting/_design/views/all/map.js: -------------------------------------------------------------------------------- 1 | function(doc) { 2 | if (doc.doc_type == "Greeting") 3 | emit(doc._id, doc); 4 | } -------------------------------------------------------------------------------- /examples/djangoapp/greeting/models.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from django.db import models 3 | 4 | from couchdbkit.ext.django.schema import * 5 | 6 | class Greeting(Document): 7 | author = StringProperty() 8 | content = StringProperty(required=True) 9 | date = DateTimeProperty(default=datetime.utcnow) 10 | 11 | class Meta: 12 | app_label = "greeting" 13 | -------------------------------------------------------------------------------- /examples/djangoapp/greeting/views.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from datetime import datetime 4 | from django.shortcuts import render_to_response as render 5 | from django.template import RequestContext, loader, Context 6 | 7 | from couchdbkit.ext.django.forms import DocumentForm 8 | 9 | from djangoapp.greeting.models import Greeting 10 | 11 | 12 | class GreetingForm(DocumentForm): 13 | 14 | class Meta: 15 | document = Greeting 16 | 17 | 18 | def home(request): 19 | 20 | greet = None 21 | 22 | if request.POST: 23 | form = GreetingForm(request.POST) 24 | if form.is_valid(): 25 | greet = form.save() 26 | else: 27 | form = GreetingForm() 28 | 29 | greetings = Greeting.view('greeting/all', descending=True) 30 | 31 | return render("home.html", { 32 | "form": form, 33 | "greet": greet, 34 | "greetings": greetings 35 | }, context_instance=RequestContext(request)) -------------------------------------------------------------------------------- /examples/djangoapp/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from django.core.management import execute_manager 3 | try: 4 | import settings # Assumed to be in the same directory. 5 | except ImportError: 6 | import sys 7 | sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) 8 | sys.exit(1) 9 | 10 | if __name__ == "__main__": 11 | execute_manager(settings) 12 | -------------------------------------------------------------------------------- /examples/djangoapp/requirements.txt: -------------------------------------------------------------------------------- 1 | CouchDB==0.8 2 | Django==1.4 3 | WebOb==1.2 4 | couchdbkit==0.6.3 5 | gunicorn==0.14.3 6 | http-parser==0.7.5 7 | nose==1.1.2 8 | restkit==4.1.3 9 | socketpool==0.4.1 10 | wsgiref==0.1.2 11 | yolk==0.4.3 12 | -------------------------------------------------------------------------------- /examples/djangoapp/run.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2008,2009 Benoit Chesneau 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at# 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | from couchdbkit.wsgi.handler import WSGIHandler 19 | import os 20 | import sys 21 | 22 | PROJECT_PATH = os.path.join(os.path.dirname(__file__), '..') 23 | sys.path.append(PROJECT_PATH) 24 | 25 | os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoapp.settings' 26 | 27 | import django.core.handlers.wsgi 28 | app = django.core.handlers.wsgi.WSGIHandler() 29 | 30 | def main(): 31 | handler = WSGIHandler(app) 32 | handler.run() 33 | 34 | if __name__ == "__main__": 35 | main() 36 | -------------------------------------------------------------------------------- /examples/djangoapp/settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for testapp project. 2 | 3 | import os, platform 4 | 5 | PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) 6 | 7 | DEBUG = True 8 | TEMPLATE_DEBUG = DEBUG 9 | 10 | ADMINS = ( 11 | ('Benoit Chesneau', 'bchesneau@gmail.com'), 12 | ) 13 | 14 | MANAGERS = ADMINS 15 | 16 | DATABASES = { 17 | 'default': { 18 | 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 19 | 'NAME': 'test.db', # Or path to database file if using sqlite3. 20 | 'USER': '', # Not used with sqlite3. 21 | 'PASSWORD': '', # Not used with sqlite3. 22 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 23 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 24 | } 25 | } 26 | 27 | COUCHDB_DATABASES = ( 28 | ('djangoapp.greeting', 'http://127.0.0.1:5984/greeting'), 29 | ) 30 | 31 | # Local time zone for this installation. Choices can be found here: 32 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 33 | # although not all choices may be available on all operating systems. 34 | # If running in a Windows environment this must be set to the same as your 35 | # system time zone. 36 | TIME_ZONE = 'Europe/Paris' 37 | 38 | # Language code for this installation. All choices can be found here: 39 | # http://www.i18nguy.com/unicode/language-identifiers.html 40 | LANGUAGE_CODE = 'en-us' 41 | 42 | SITE_ID = 1 43 | 44 | # If you set this to False, Django will make some optimizations so as not 45 | # to load the internationalization machinery. 46 | USE_I18N = True 47 | 48 | # Absolute path to the directory that holds media. 49 | # Example: "/home/media/media.lawrence.com/" 50 | MEDIA_ROOT = os.path.join(PROJECT_PATH, 'static') 51 | 52 | MEDIA_URL = '/media' 53 | 54 | ADMIN_MEDIA_PREFIX = '/admin/media/' 55 | 56 | # Make this unique, and don't share it with anybody. 57 | SECRET_KEY = '3c7!ofj2o@7vglv+dj(pm_2_m*n)4qnfi7cw+7#8c3ng6sxcml' 58 | 59 | MIDDLEWARE_CLASSES = ( 60 | 'django.middleware.common.CommonMiddleware', 61 | 'django.contrib.sessions.middleware.SessionMiddleware', 62 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 63 | ) 64 | 65 | ROOT_URLCONF = 'djangoapp.urls' 66 | 67 | TEMPLATE_DIRS = ( 68 | os.path.join(PROJECT_PATH, 'templates'), 69 | ) 70 | 71 | INSTALLED_APPS = ( 72 | 'django.contrib.auth', 73 | 'django.contrib.contenttypes', 74 | 'django.contrib.sessions', 75 | 'django.contrib.sites', 76 | 'couchdbkit.ext.django', 77 | 'djangoapp.greeting' 78 | ) 79 | -------------------------------------------------------------------------------- /examples/djangoapp/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | couchdbkit example app 6 | 20 | 21 | 22 | 23 |
24 |

Greeting app

25 |
26 | 27 | {% block content %}{% endblock %} 28 | 29 | 30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/djangoapp/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% load i18n %} 3 | 4 | {% block content %} 5 |
6 | 7 | {{ form.as_table }} 8 |
9 | 10 |
11 | 12 | {% if greet %} 13 | {{ greet.get_id }} was added 14 | {% endif %} 15 | 16 |

Greetings

17 | 18 | {% for g in greetings %} 19 | 20 | 21 | 22 | 23 | 24 | {% endfor %} 25 |
{{ g.date|timesince }} {{ g.author }} {{ g.content }}
26 | {% endblock content %} -------------------------------------------------------------------------------- /examples/djangoapp/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls.defaults import * 2 | 3 | urlpatterns = patterns('', 4 | url(r'^$', 'djangoapp.greeting.views.home'), 5 | ) 6 | 7 | -------------------------------------------------------------------------------- /examples/pyramidapp/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt *.ini *.cfg *.rst 2 | recursive-include pyramid_couchdb_example *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml 3 | -------------------------------------------------------------------------------- /examples/pyramidapp/README: -------------------------------------------------------------------------------- 1 | Example implementation for http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/database/couchdb.html 2 | 3 | $ python setup.py develop 4 | $ pserve --reload development.ini 5 | -------------------------------------------------------------------------------- /examples/pyramidapp/development.ini: -------------------------------------------------------------------------------- 1 | [app:main] 2 | use = egg:pyramid_couchdb_example 3 | 4 | pyramid.reload_templates = true 5 | pyramid.debug_authorization = false 6 | pyramid.debug_notfound = false 7 | pyramid.debug_routematch = false 8 | pyramid.debug_templates = true 9 | pyramid.default_locale_name = en 10 | pyramid.includes = pyramid_debugtoolbar 11 | 12 | couchdb.uri = http://localhost:5984/ 13 | couchdb.db = mydb 14 | 15 | [server:main] 16 | use = egg:waitress#main 17 | host = 0.0.0.0 18 | port = 6543 19 | 20 | # Begin logging configuration 21 | 22 | [loggers] 23 | keys = root, pyramid_couchdb_example 24 | 25 | [handlers] 26 | keys = console 27 | 28 | [formatters] 29 | keys = generic 30 | 31 | [logger_root] 32 | level = INFO 33 | handlers = console 34 | 35 | [logger_pyramid_couchdb_example] 36 | level = DEBUG 37 | handlers = 38 | qualname = pyramid_couchdb_example 39 | 40 | [handler_console] 41 | class = StreamHandler 42 | args = (sys.stderr,) 43 | level = NOTSET 44 | formatter = generic 45 | 46 | [formatter_generic] 47 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s 48 | 49 | # End logging configuration 50 | -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/__init__.py: -------------------------------------------------------------------------------- 1 | from pyramid.config import Configurator 2 | from pyramid.events import subscriber, ApplicationCreated 3 | from couchdbkit import * 4 | 5 | import logging 6 | log = logging.getLogger(__name__) 7 | 8 | @subscriber(ApplicationCreated) 9 | def application_created_subscriber(event): 10 | registry = event.app.registry 11 | db = registry.db.get_or_create_db(registry.settings['couchdb.db']) 12 | 13 | pages_view_exists = db.doc_exist('lists/pages') 14 | if pages_view_exists == False: 15 | design_doc = { 16 | '_id': '_design/lists', 17 | 'language': 'javascript', 18 | 'views': { 19 | 'pages': { 20 | 'map': ''' 21 | function(doc) { 22 | if (doc.doc_type === 'Page') { 23 | emit([doc.page, doc._id], null) 24 | } 25 | } 26 | ''' 27 | } 28 | } 29 | } 30 | db.save_doc(design_doc) 31 | 32 | def main(global_config, **settings): 33 | """ This function returns a Pyramid WSGI application. 34 | """ 35 | config = Configurator(settings=settings) 36 | config.registry.db = Server(uri=settings['couchdb.uri']) 37 | 38 | def add_couchdb(request): 39 | db = config.registry.db.get_db(settings['couchdb.db']) 40 | return db 41 | 42 | config.add_request_method(add_couchdb, 'db', reify=True) 43 | 44 | config.add_static_view('static', 'static', cache_max_age=3600) 45 | config.add_route('home', '/') 46 | config.scan() 47 | return config.make_wsgi_app() 48 | -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/favicon.ico -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/footerbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/footerbg.png -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/headerbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/headerbg.png -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/ie6.css: -------------------------------------------------------------------------------- 1 | * html img, 2 | * html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", 3 | this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", 4 | this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), 5 | this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", 6 | this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) 7 | );} 8 | #wrap{display:table;height:100%} 9 | -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/middlebg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/middlebg.png -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/pyramid-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/pyramid-small.png -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/pyramid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/pyramid.png -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/static/transparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/examples/pyramidapp/pyramid_couchdb_example/static/transparent.gif -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/tests.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from pyramid import testing 4 | 5 | class ViewTests(unittest.TestCase): 6 | def setUp(self): 7 | self.config = testing.setUp() 8 | 9 | def tearDown(self): 10 | testing.tearDown() 11 | 12 | def test_my_view(self): 13 | from .views import my_view 14 | #Don't actually test anything right now 15 | #request = testing.DummyRequest() 16 | #info = my_view(request) 17 | #self.assertEqual(info['project'], 'pyramid_couchdb_example') 18 | self.assertEqual(True, True) 19 | -------------------------------------------------------------------------------- /examples/pyramidapp/pyramid_couchdb_example/views.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | from pyramid.view import view_config 4 | 5 | from couchdbkit import * 6 | 7 | import logging 8 | log = logging.getLogger(__name__) 9 | 10 | class Page(Document): 11 | author = StringProperty() 12 | page = StringProperty() 13 | content = StringProperty() 14 | date = DateTimeProperty() 15 | 16 | @view_config(route_name='home', renderer='templates/mytemplate.pt') 17 | def my_view(request): 18 | 19 | def get_data(): 20 | return list(request.db.view('lists/pages', startkey=['home'], \ 21 | endkey=['home', {}], include_docs=True)) 22 | 23 | page_data = get_data() 24 | 25 | if not page_data: 26 | Page.set_db(request.db) 27 | home = Page( 28 | author='Wendall', 29 | content='Using CouchDB via couchdbkit!', 30 | page='home', 31 | date=datetime.datetime.utcnow() 32 | ) 33 | # save page data 34 | home.save() 35 | 36 | page_data = get_data() 37 | 38 | doc = page_data[0].get('doc') 39 | 40 | return { 41 | 'project': 'pyramid_couchdb_example', 42 | 'info': request.db.info(), 43 | 'author': doc.get('author'), 44 | 'content': doc.get('content'), 45 | 'date': doc.get('date') 46 | } 47 | -------------------------------------------------------------------------------- /examples/pyramidapp/setup.cfg: -------------------------------------------------------------------------------- 1 | [nosetests] 2 | match = ^test 3 | nocapture = 1 4 | cover-package = pyramid_couchdb_example 5 | with-coverage = 1 6 | cover-erase = 1 7 | 8 | [compile_catalog] 9 | directory = pyramid_couchdb_example/locale 10 | domain = pyramid_couchdb_example 11 | statistics = true 12 | 13 | [extract_messages] 14 | add_comments = TRANSLATORS: 15 | output_file = pyramid_couchdb_example/locale/pyramid_couchdb_example.pot 16 | width = 80 17 | 18 | [init_catalog] 19 | domain = pyramid_couchdb_example 20 | input_file = pyramid_couchdb_example/locale/pyramid_couchdb_example.pot 21 | output_dir = pyramid_couchdb_example/locale 22 | 23 | [update_catalog] 24 | domain = pyramid_couchdb_example 25 | input_file = pyramid_couchdb_example/locale/pyramid_couchdb_example.pot 26 | output_dir = pyramid_couchdb_example/locale 27 | previous = true 28 | -------------------------------------------------------------------------------- /examples/pyramidapp/setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import setup, find_packages 4 | 5 | here = os.path.abspath(os.path.dirname(__file__)) 6 | README = open(os.path.join(here, 'README')).read() 7 | 8 | requires = [ 9 | 'pyramid', 10 | 'pyramid_debugtoolbar', 11 | 'waitress', 12 | 'couchdbkit', 13 | ] 14 | 15 | setup(name='pyramid_couchdb_example', 16 | version='0.0', 17 | description='pyramid_couchdb_example', 18 | long_description=README, 19 | classifiers=[ 20 | "Programming Language :: Python", 21 | "Framework :: Pyramid", 22 | "Topic :: Internet :: WWW/HTTP", 23 | "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", 24 | ], 25 | author='', 26 | author_email='', 27 | url='', 28 | keywords='web pyramid pylons', 29 | packages=find_packages(), 30 | include_package_data=True, 31 | zip_safe=False, 32 | install_requires=requires, 33 | tests_require=requires, 34 | test_suite="pyramid_couchdb_example", 35 | entry_points = """\ 36 | [paste.app_factory] 37 | main = pyramid_couchdb_example:main 38 | """, 39 | ) 40 | 41 | -------------------------------------------------------------------------------- /examples/wsgi/test.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2008,2009 Benoit Chesneau 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at# 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | import couchdbkit 19 | from couchdbkit.contrib import WSGIHandler 20 | import json 21 | 22 | def app(environ, start_response): 23 | """Simplest possible application object""" 24 | data = 'Hello, World!\n DB Infos : %s\n' % json.dumps(environ["COUCHDB_INFO"]) 25 | status = '200 OK' 26 | response_headers = [ 27 | ('Content-type','text/plain'), 28 | ('Content-Length', len(data)) 29 | ] 30 | start_response(status, response_headers) 31 | return [data] 32 | 33 | def main(): 34 | handler = WSGIHandler(app) 35 | handler.run() 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | restkit>=4.2.2 2 | -------------------------------------------------------------------------------- /requirements_dev.txt: -------------------------------------------------------------------------------- 1 | unittest2 2 | nose 3 | restkit>=4.2.2 4 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [nosetests] 2 | exclude=(django) 3 | with-coverage=1 4 | cover-package=couchdbkit 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | 6 | from imp import load_source 7 | import os 8 | import sys 9 | 10 | if not hasattr(sys, 'version_info') or sys.version_info < (2, 6, 0, 'final'): 11 | raise SystemExit("couchdbkit requires Python 2.6 or later.") 12 | 13 | from setuptools import setup, find_packages 14 | 15 | # open version module 16 | version = load_source("version", os.path.join("couchdbkit", 17 | "version.py")) 18 | 19 | 20 | setup( 21 | name = 'couchdbkit', 22 | version = version.__version__, 23 | 24 | description = 'Python couchdb kit', 25 | long_description = file( 26 | os.path.join( 27 | os.path.dirname(__file__), 28 | 'README.rst' 29 | ) 30 | ).read(), 31 | author = 'Benoit Chesneau', 32 | author_email = 'benoitc@e-engura.com', 33 | license = 'Apache License 2', 34 | url = 'http://couchdbkit.org', 35 | 36 | classifiers = [ 37 | 'Development Status :: 4 - Beta', 38 | 'Environment :: Other Environment', 39 | 'Intended Audience :: Developers', 40 | 'License :: OSI Approved :: Apache Software License', 41 | 'Operating System :: OS Independent', 42 | 'Programming Language :: Python :: 2', 43 | 'Programming Language :: Python :: 2.5', 44 | 'Programming Language :: Python :: 2.6', 45 | 'Programming Language :: Python :: 2.7', 46 | 'Topic :: Database', 47 | 'Topic :: Utilities', 48 | 'Topic :: Software Development :: Libraries :: Python Modules', 49 | ], 50 | packages = find_packages(exclude=['tests']), 51 | 52 | zip_safe = False, 53 | 54 | install_requires = [ 'restkit>=4.2.2' ], 55 | 56 | entry_points=""" 57 | [couchdbkit.consumers] 58 | sync=couchdbkit.consumer.sync:SyncConsumer 59 | eventlet=couchdbkit.consumer.ceventlet:EventletConsumer 60 | gevent=couchdbkit.consumer.cgevent:GeventConsumer 61 | """, 62 | 63 | test_suite='nose.collector', 64 | ) 65 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benoitc/couchdbkit/6be148640c00b54ee87a2f2d502e9d67fa5b45a8/tests/__init__.py -------------------------------------------------------------------------------- /tests/data/app-template/_attachments/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated CouchApp 5 | 6 | 7 | 8 |

Generated CouchApp

9 |
    10 | 11 | 12 | 13 | 14 | 26 | 27 | -------------------------------------------------------------------------------- /tests/data/app-template/_attachments/style/main.css: -------------------------------------------------------------------------------- 1 | /* add styles here */ -------------------------------------------------------------------------------- /tests/data/app-template/foo/bar.txt: -------------------------------------------------------------------------------- 1 | Couchapp will create a field on your document corresponding to any directories you make within the application directory, with the text of any files found as key/value pairs. 2 | 3 | Also, any files that end in .json will be treated as json rather than text, and put in the corresponding field. Also note that file.json, file.js, or file.txt will be stored under the "file" key, so don't make collisions in the filesystem unless you want unpredictable results. 4 | 5 | Of course you know that the views, shows, and lists directories will be treated specially, as those files are processed with the !code and !json macros. 6 | 7 | ps: each design document only has one language key: CouchDB defaults to Javascript, so that's what you'll get if you don't express otherwise. The way to switch to a different langauge is to edit the file in the approot called "language", changing "javascript" for instance into "python". 8 | 9 | Oh yeah it's recommended that you delete this file. -------------------------------------------------------------------------------- /tests/data/app-template/lib/helpers/math.js: -------------------------------------------------------------------------------- 1 | // this is just a placeholder for example purposes 2 | function stddev() {}; -------------------------------------------------------------------------------- /tests/data/app-template/lib/helpers/template.js: -------------------------------------------------------------------------------- 1 | // Simple JavaScript Templating 2 | // John Resig - http://ejohn.org/ - MIT Licensed 3 | var cache = {}; 4 | 5 | function template(str, data){ 6 | // Figure out if we're getting a template, or if we need to 7 | // load the template - and be sure to cache the result. 8 | var fn = cache[str] || 9 | 10 | // Generate a reusable function that will serve as a template 11 | // generator (and which will be cached). 12 | new Function("obj", 13 | "var p=[],print=function(){p.push.apply(p,arguments);};" + 14 | 15 | // Introduce the data as local variables using with(){} 16 | "with(obj){p.push('" + 17 | 18 | // Convert the template into pure JavaScript 19 | str 20 | .replace(/[\r\t\n]/g, " ") 21 | .replace(/'(?=[^%]*%>)/g,"\t") 22 | .split("'").join("\\'") 23 | .split("\t").join("'") 24 | .replace(/<%=(.+?)%>/g, "',$1,'") 25 | .split("<%").join("');") 26 | .split("%>").join("p.push('") 27 | + "');}return p.join('');"); 28 | cache[str] = fn; 29 | 30 | // Provide some basic currying to the user 31 | return data ? fn( data ) : fn; 32 | }; -------------------------------------------------------------------------------- /tests/data/app-template/lib/templates/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated CouchApp Form Template 5 | 6 | 7 | 10 |
    11 |

    <% doc.title %>

    12 |
    13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | -------------------------------------------------------------------------------- /tests/data/app-template/lists/feed.js: -------------------------------------------------------------------------------- 1 | function(head, row, req) { 2 | respondWith(req, { 3 | html : function() { 4 | if (head) { 5 | return '

    Listing

    total rows: '+head.row_count+'
      '; 6 | } else if (row) { 7 | return '\n
    • Id:' + row.id + '
    • '; 8 | } else { 9 | return '
    '; 10 | } 11 | }, 12 | xml : function() { 13 | if (head) { 14 | return {body:'' 15 | +'Test XML Feed'}; 16 | } else if (row) { 17 | // Becase Safari can't stand to see that dastardly 18 | // E4X outside of a string. Outside of tests you 19 | // can just use E4X literals. 20 | var entry = new XML(''); 21 | entry.id = row.id; 22 | entry.title = row.key; 23 | entry.content = row.value; 24 | return {body:entry}; 25 | } else { 26 | return {body : ""}; 27 | } 28 | } 29 | }) 30 | }; -------------------------------------------------------------------------------- /tests/data/app-template/shows/example-show.js: -------------------------------------------------------------------------------- 1 | function(doc, req) { 2 | // !code lib/helpers/template.js 3 | // !json lib.templates 4 | 5 | respondWith(req, { 6 | html : function() { 7 | var html = template(lib.templates.example, doc); 8 | return {body:html} 9 | }, 10 | xml : function() { 11 | return { 12 | body : 13 | } 14 | } 15 | }) 16 | }; -------------------------------------------------------------------------------- /tests/data/app-template/views/example/map.js: -------------------------------------------------------------------------------- 1 | // an example map function, emits the doc id 2 | // and the list of keys it contains 3 | // !code lib/helpers/math.js 4 | 5 | function(doc) { 6 | var k, keys = [] 7 | for (k in doc) keys.push(k); 8 | emit(doc._id, keys); 9 | }; 10 | -------------------------------------------------------------------------------- /tests/data/app-template/views/example/reduce.js: -------------------------------------------------------------------------------- 1 | // example reduce function to count the 2 | // number of rows in a given key range. 3 | 4 | function(keys, values, rereduce) { 5 | if (rereduce) { 6 | return sum(values); 7 | } else { 8 | return values.length; 9 | } 10 | }; -------------------------------------------------------------------------------- /tests/test_changes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | # 6 | __author__ = 'benoitc@e-engura.com (Benoît Chesneau)' 7 | 8 | import threading 9 | import time 10 | try: 11 | import unittest2 as unittest 12 | except ImportError: 13 | import unittest 14 | 15 | from couchdbkit import * 16 | from couchdbkit.changes import ChangesStream, fold, foreach 17 | 18 | class ClientServerTestCase(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.server = Server() 22 | self._delete_db() 23 | self.db = self.server.create_db("couchdbkit_test") 24 | self.consumer = Consumer(self.db) 25 | 26 | def tearDown(self): 27 | self._delete_db() 28 | 29 | def _delete_db(self): 30 | try: 31 | del self.server['couchdbkit_test'] 32 | except: 33 | pass 34 | 35 | 36 | def test_fetch(self): 37 | # save a doc 38 | doc = {} 39 | self.db.save_doc(doc) 40 | 41 | def fold_fun(c, acc): 42 | acc.append(c) 43 | return acc 44 | 45 | changes = fold(self.db, fold_fun, []) 46 | 47 | self.assert_(len(changes) == 1) 48 | change = changes[0] 49 | self.assert_(change["id"] == doc['_id']) 50 | 51 | 52 | def test_lonpoll(self): 53 | def test_change(): 54 | with ChangesStream(self.db, feed="longpoll") as stream: 55 | for change in stream: 56 | self.assert_(change["seq"] == 1) 57 | 58 | t = threading.Thread(target=test_change) 59 | t.daemon = True 60 | t.start() 61 | 62 | doc = {} 63 | self.db.save_doc(doc) 64 | 65 | 66 | def test_continuous(self): 67 | lines = [] 68 | def test_change(): 69 | with ChangesStream(self.db, feed="continuous") as stream: 70 | for change in stream: 71 | lines.append(change) 72 | 73 | 74 | t = threading.Thread(target=test_change) 75 | t.daemon = True 76 | t.start() 77 | 78 | for i in range(5): 79 | doc = {"_id": "test%s" % str(i)} 80 | self.db.save_doc(doc) 81 | 82 | self.db.ensure_full_commit() 83 | time.sleep(0.3) 84 | self.assert_(len(lines) == 5) 85 | self.assert_(lines[4]["id"] == "test4") 86 | doc = {"_id": "test5"} 87 | self.db.save_doc(doc) 88 | time.sleep(0.3) 89 | self.assert_(len(lines) == 6) 90 | self.assert_(lines[5]["id"] == "test5") 91 | 92 | -------------------------------------------------------------------------------- /tests/test_consumer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | # 6 | __author__ = 'benoitc@e-engura.com (Benoît Chesneau)' 7 | 8 | import threading 9 | import time 10 | try: 11 | import unittest2 as unittest 12 | except ImportError: 13 | import unittest 14 | 15 | from couchdbkit import * 16 | 17 | class ClientServerTestCase(unittest.TestCase): 18 | 19 | def setUp(self): 20 | self.server = Server() 21 | self._delete_db() 22 | self.db = self.server.create_db("couchdbkit_test") 23 | self.consumer = Consumer(self.db) 24 | 25 | def tearDown(self): 26 | self._delete_db() 27 | 28 | def _delete_db(self): 29 | try: 30 | del self.server['couchdbkit_test'] 31 | except: 32 | pass 33 | 34 | 35 | def test_fetch(self): 36 | res1 = self.consumer.fetch() 37 | self.assert_("last_seq" in res1) 38 | self.assert_(res1["last_seq"] == 0) 39 | self.assert_(res1["results"] == []) 40 | doc = {} 41 | self.db.save_doc(doc) 42 | res2 = self.consumer.fetch() 43 | self.assert_(res2["last_seq"] == 1) 44 | self.assert_(len(res2["results"]) == 1) 45 | line = res2["results"][0] 46 | self.assert_(line["id"] == doc["_id"]) 47 | 48 | def test_longpoll(self): 49 | 50 | def test_line(line): 51 | self.assert_(line["last_seq"] == 1) 52 | self.assert_(len(line["results"]) == 1) 53 | return 54 | 55 | t = threading.Thread(target=self.consumer.wait_once, 56 | kwargs=dict(cb=test_line)) 57 | t.daemon = True 58 | t.start() 59 | doc = {} 60 | self.db.save_doc(doc) 61 | 62 | def test_continuous(self): 63 | self.lines = [] 64 | def test_line(line): 65 | self.lines.append(line) 66 | 67 | t = threading.Thread(target=self.consumer.wait, 68 | kwargs=dict(cb=test_line)) 69 | t.daemon = True 70 | t.start() 71 | 72 | for i in range(5): 73 | doc = {"_id": "test%s" % str(i)} 74 | self.db.save_doc(doc) 75 | self.db.ensure_full_commit() 76 | time.sleep(0.3) 77 | self.assert_(len(self.lines) == 5) 78 | self.assert_(self.lines[4]["id"] == "test4") 79 | doc = {"_id": "test5"} 80 | self.db.save_doc(doc) 81 | time.sleep(0.3) 82 | self.assert_(len(self.lines) == 6) 83 | self.assert_(self.lines[5]["id"] == "test5") 84 | 85 | 86 | if __name__ == '__main__': 87 | unittest.main() 88 | -------------------------------------------------------------------------------- /tests/test_resource.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 - 2 | # 3 | # This file is part of couchdbkit released under the MIT license. 4 | # See the NOTICE for more information. 5 | # 6 | __author__ = 'benoitc@e-engura.com (Benoît Chesneau)' 7 | 8 | try: 9 | import unittest2 as unittest 10 | except ImportError: 11 | import unittest 12 | 13 | from restkit.errors import RequestFailed, RequestError 14 | from couchdbkit.resource import CouchdbResource 15 | 16 | 17 | class ServerTestCase(unittest.TestCase): 18 | def setUp(self): 19 | self.couchdb = CouchdbResource() 20 | try: 21 | self.couchdb.delete('/couchdkbit_test') 22 | except: 23 | pass 24 | 25 | def tearDown(self): 26 | self.couchdb = None 27 | try: 28 | self.couchdb.delete('/couchdkbit_test') 29 | except: 30 | pass 31 | 32 | def testGetInfo(self): 33 | info = self.couchdb.get().json_body 34 | self.assert_(info.has_key('version')) 35 | 36 | def testCreateDb(self): 37 | res = self.couchdb.put('/couchdkbit_test').json_body 38 | self.assert_(res['ok'] == True) 39 | all_dbs = self.couchdb.get('/_all_dbs').json_body 40 | self.assert_('couchdkbit_test' in all_dbs) 41 | self.couchdb.delete('/couchdkbit_test') 42 | 43 | def testCreateEmptyDoc(self): 44 | res = self.couchdb.put('/couchdkbit_test/').json_body 45 | self.assert_(res['ok'] == True) 46 | res = self.couchdb.post('/couchdkbit_test/', payload={}).json_body 47 | self.couchdb.delete('/couchdkbit_test') 48 | self.assert_(len(res) > 0) 49 | 50 | def testRequestFailed(self): 51 | bad = CouchdbResource('http://localhost:10000') 52 | self.assertRaises(RequestError, bad.get) 53 | 54 | if __name__ == '__main__': 55 | unittest.main() 56 | 57 | 58 | --------------------------------------------------------------------------------