{ "info": { "author": "David Eyk", "author_email": "deyk@crossway.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3.5", "Topic :: Database", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries" ], "description": "Duo: A powerful, dynamic, pythonic interface to AWS DynamoDB\n============================================================\n\n\n.. image:: https://travis-ci.org/eykd/duo.svg?branch=master\n :target: https://travis-ci.org/eykd/duo#\n\n.. image:: https://coveralls.io/repos/github/eykd/duo/badge.svg?branch=master\n :target: https://coveralls.io/github/eykd/duo?branch=master\n\n\n\n\n\nDuo provides a few straightforward, Pythonic abstractions for working\nwith Amazon Web Services' DynamoDB. It's a very light wrapper around\n`boto.dynamodb.layer2`, so you have full access to that excellent\nlibrary when you need it, but you don't have to sweat the details when\nyou don't.\n\nStern warning:\n--------------\n\nNo seriously, it's a very light wrapper around\n`boto.dynamodb.layer2`. If you stray much beyond the usage examples\nbelow, you'd do best to be familiar with Boto's DynamoDB API. `The\ndocs`_ are excellent. Reading `duo's source`_ may also be helpful. It's\nkept short for that reason.\n\n.. _The docs: http://boto.readthedocs.org/en/latest/ref/dynamodb.html\n.. _duo's source: https://github.com/eykd/duo/blob/master/duo.py\n\n\nUsage:\n------\n\n`duo` is made up of one module::\n\n >>> import duo\n\nThe module isn't very big (at the time of this writing, ~700\nlines). If you want to know how something works, `you should read it`_.\n\n.. _you should read it: https://github.com/eykd/duo/blob/master/duo.py\n\nPre-create your tables in the AWS console, then write simple classes\nto access them. `duo.Table` Sub-classes are automatically registered\nwith the db::\n\n >>> class MyHashKeyTable(duo.Table):\n ... table_name = 'my_hashkey_table'\n ... hash_key_name = 'slug'\n ... range_key_name = None # Implicit default\n\n\n`duo.Item` is a thin wrapper around `boto.dynamodb.items.Item`, with\nlots of syntactic sugar. `duo.Item` sub-classs are automatically\nregistered with the db::\n\n >>> import datetime\n\n >>> class MyHashKeyItem(duo.Item):\n ... table_name = 'my_hashkey_table'\n ... hash_key_name = 'slug'\n ...\n ... slug = duo.UnicodeField()\n ... my_field = duo.UnicodeField(default='foo')\n ... on_this_date = duo.DateField(default=lambda o: datetime.date.today())\n\n\nDatabases and Tables use dict-like access syntax::\n\n >>> db = duo.DynamoDB(key='access_key', secret='secret_key')\n\n >>> # The correct Table sub-class is matched by table name:\n >>> table = duo.DynamoDB['my_hashkey_table']\n\n >>> # The correct Item sub-class is matched by table name:\n >>> item = table['new-item']\n\n >>> # Items are actually dict subclasses, but that's not where the\n >>> # fun is. They can only store unicode strings and integers:\n >>> item['slug']\n 'new-item'\n\n\nSpecify a field on an Item sub-class to get useful data types::\n\n >>> item.is_new\n True\n\n >>> # A field doesn't exist initially...\n >>> item['my_field']\n Traceback (most recent call last):\n File \"...\", line 1, in \n item['my_field']\n KeyError: 'my_field'\n\n >>> # But we specified a default.\n >>> item.my_field\n 'foo'\n\n >>> # The default, once accessed, gets populated:\n >>> item['my_field']\n 'foo'\n\n >>> # Or we can set our own value...\n >>> item.my_field = 'bar'\n\n >>> item['my_field']\n 'bar'\n\n >>> # Finally, we save it to DynamoDB.\n >>> item.put()\n\n >>> item.is_new\n False\n\n\nCaching:\n--------\n\nDuo integrates with any cache that implements a `python-memcached`\\\n-compatible interface, namely, the following::\n\n import pylibmc\n cache = pylibmc.Client(['127.0.0.1'])\n cache.get()\n cache.set(, )\n cache.delete()\n\nIntegrate caching by passing the cache to the db constructor::\n\n >>> import duo\n >>> db = duo.DynamoDB(key='access_key', secret='secret_key', cache=cache)\n\nYou can also specify a cache object on a per-table or per-item basis::\n\n >>> class MyHashKeyTable(duo.Table):\n ... cache = pylibmc.Client(['127.0.0.1'])\n ...\n ... table_name = 'my_hashkey_table'\n ... hash_key_name = 'slug'\n ... range_key_name = None # Implicit default\n\n\nCaching is turned off by default, but you can turn it on by specifying\na `cache_duration` as an integer (0 is forever)::\n\n >>> class MyHashKeyItem(duo.Item):\n ... cache_duration = 30 # 30 seconds\n ...\n ... table_name = 'my_hashkey_table'\n ... hash_key_name = 'slug'\n ...\n ... slug = duo.UnicodeField()\n ... my_field = duo.UnicodeField(default='foo')\n ... on_this_date = duo.DateField(default=lambda o: datetime.date.today())\n\n\nCache keys are determined by hash key, range key, and a cache prefix\n(set on the Table). By default, the cache prefix is the table name::\n\n >>> table = duo.DynamoDB['my_hashkey_table']\n >>> item = table['new-item']\n >>> item.cache_prefix is None\n True\n >>>item._cache_key\n 'my_hashkey_table_new-item'\n >>> MyHashKeyTable.cache_prefix = 'hello_world'\n >>> item._get_cache_key()\n 'hello_world_new-item'\n\n\nCHANGELOG\n---------\n\n0.3.1\n^^^^^\n\nFixed bug whereby EnumMeta and subclasses were not comparing properly (re: at all) in Python 3.\n\n0.3.0\n^^^^^\n\nAdd Python 3 compatibility.\n\n0.2.5\n^^^^^\n\nget_item() now writes to the cache, even though it doesn't read from the cache.\n\n0.2.4\n^^^^^\n\nAdded a custom get_item to Table, for specifying consistent reads,\netc. Used by __getitem__, for simpler code!\n\n0.2.3\n^^^^^\n\nOne more packaging fix, so pip won't explode. Thanks, cbrinker!\n\n\n0.2.2\n^^^^^\n\nTable.scan() and .query() should return extended Items.\n\n\n0.2.1\n^^^^^\n\nCorrections/improvements to setup.py. Packaging is HARD.\n\n\n0.2\n^^^\n\nInitial public release.\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/eykd/duo", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "duo", "package_url": "https://pypi.org/project/duo/", "platform": "", "project_url": "https://pypi.org/project/duo/", "project_urls": { "Homepage": "http://github.com/eykd/duo" }, "release_url": "https://pypi.org/project/duo/0.3.2/", "requires_dist": null, "requires_python": "", "summary": "A powerful, dynamic, pythonic interface to AWS DynamoDB.", "version": "0.3.2" }, "last_serial": 2875695, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "ab0fdb33c1bd8aff38df4ed484157ede", "sha256": "aa8bc9efcb1c8ccf5ff31a7b43e979f68bd4c0c08348d652da86fe1c10621392" }, "downloads": -1, "filename": "duo-0.2.tar.gz", "has_sig": false, "md5_digest": "ab0fdb33c1bd8aff38df4ed484157ede", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9548, "upload_time": "2012-08-17T05:02:15", "url": "https://files.pythonhosted.org/packages/5a/55/2867850065752b4dea2984ab994b8be5e71d98df290b9656f902aad21188/duo-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "ccc2f64cd448406cd1331b99a3d36057", "sha256": "001b771bb5110a0e42d873944bcb86eed94951b7bc7eeb7311f4f71fea7bd2e4" }, "downloads": -1, "filename": "duo-0.2.1.tar.gz", "has_sig": false, "md5_digest": "ccc2f64cd448406cd1331b99a3d36057", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11307, "upload_time": "2012-08-17T05:15:36", "url": "https://files.pythonhosted.org/packages/99/55/452933a2af49fa46eea41325b55d076de2e2027ab9a3e89ad46f289aef28/duo-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "85d70566036800bd12d72cef5207ef19", "sha256": "3f5e4f4427321ae26aecc39a15616c0973d79fd3a60bec803cc309a17cd8aab4" }, "downloads": -1, "filename": "duo-0.2.2.tar.gz", "has_sig": false, "md5_digest": "85d70566036800bd12d72cef5207ef19", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11378, "upload_time": "2012-09-27T23:43:19", "url": "https://files.pythonhosted.org/packages/9b/5b/b29d09a9f50725088d60b2263323a0ee8a09fd4aac5879f6ada5d38853f0/duo-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "13e638a2341422ecbf8f5fb3ccc80ce5", "sha256": "3eb77a9c07cc9d13c94f0a3b66d0359db8b7cd9cb02052582fa534e234714235" }, "downloads": -1, "filename": "duo-0.2.3.tar.gz", "has_sig": false, "md5_digest": "13e638a2341422ecbf8f5fb3ccc80ce5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11467, "upload_time": "2012-10-11T17:21:22", "url": "https://files.pythonhosted.org/packages/bd/5c/09d895743b7354949b77152e4430515ec98c9208a3cf7210d0e539f2e2f5/duo-0.2.3.tar.gz" } ], "0.2.4": [ { "comment_text": "", "digests": { "md5": "21ed53f36a9958f7997fea45ae988a73", "sha256": "2fde0605d8ce71688317b7657370c32229e2a8d2df459f0129b9628975bd6cd6" }, "downloads": -1, "filename": "duo-0.2.4.tar.gz", "has_sig": false, "md5_digest": "21ed53f36a9958f7997fea45ae988a73", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13580, "upload_time": "2012-10-17T18:08:07", "url": "https://files.pythonhosted.org/packages/53/28/5c7367a95acc8efeeea9bd9b34bca0a07c80d35b164b81d8078ead15ff65/duo-0.2.4.tar.gz" } ], "0.2.5": [ { "comment_text": "", "digests": { "md5": "3f975a0c06114db9e40a2cd895019c07", "sha256": "210fd4d9596dad656865afd5d6d2ff9e3df1c210817b342572b846f248dfa29e" }, "downloads": -1, "filename": "duo-0.2.5.tar.gz", "has_sig": false, "md5_digest": "3f975a0c06114db9e40a2cd895019c07", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13635, "upload_time": "2013-04-10T15:53:02", "url": "https://files.pythonhosted.org/packages/01/54/8c978c818fb1380dbd19efb1bbf186783cc83967b48d56712f7d9d7fae26/duo-0.2.5.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "a7c70bb1576abf828e1975659475aca8", "sha256": "dce5c069653dd40d12739b30befd6e3cdbd6e44806828745dd0ea1365e199b35" }, "downloads": -1, "filename": "duo-0.3.0.tar.gz", "has_sig": false, "md5_digest": "a7c70bb1576abf828e1975659475aca8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14203, "upload_time": "2016-10-24T19:15:14", "url": "https://files.pythonhosted.org/packages/4e/df/1f829464672dceab5920b2407e4f57518e7cefcd31f99abce2e7a31e34a3/duo-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "cb573bae4326f94ae9baa3f50e19ec5b", "sha256": "f123fa3653429e38450f84d5549ae13089dc25d235f6e50287da21785b6cbe2f" }, "downloads": -1, "filename": "duo-0.3.1.tar.gz", "has_sig": false, "md5_digest": "cb573bae4326f94ae9baa3f50e19ec5b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14446, "upload_time": "2016-11-14T19:29:01", "url": "https://files.pythonhosted.org/packages/8a/01/d1c259dac4c4a7a6512a31dcb010f1c93ea1c2962f5909ef08aa0e03294b/duo-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "28b3a401645ba65a8844baa357b22811", "sha256": "56f34077134c92a8c79094cbee387c92ab91838d4a3bce4fcec985518c4d1ad5" }, "downloads": -1, "filename": "duo-0.3.2.tar.gz", "has_sig": false, "md5_digest": "28b3a401645ba65a8844baa357b22811", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14485, "upload_time": "2017-05-15T15:02:46", "url": "https://files.pythonhosted.org/packages/79/6a/2f63fb684a8232ad9fb290e1a882c3c1740bd4231b854b9616eb0b535c7e/duo-0.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "28b3a401645ba65a8844baa357b22811", "sha256": "56f34077134c92a8c79094cbee387c92ab91838d4a3bce4fcec985518c4d1ad5" }, "downloads": -1, "filename": "duo-0.3.2.tar.gz", "has_sig": false, "md5_digest": "28b3a401645ba65a8844baa357b22811", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14485, "upload_time": "2017-05-15T15:02:46", "url": "https://files.pythonhosted.org/packages/79/6a/2f63fb684a8232ad9fb290e1a882c3c1740bd4231b854b9616eb0b535c7e/duo-0.3.2.tar.gz" } ] }