Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install duo

How to install duo

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install duo
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
Windows (64-bit)
Mac OS X (10.5+)
Linux (32-bit)
0.2.4
0.2.5Never BuiltWhy not?
0.2.4 Available View build log
0.2.3 Available View build log
0.2.2 Available View build log
0.2.1 Available View build log
Linux (64-bit)
0.2.5 Available View build log
0.2.4 Available View build log
0.2.3 Available View build log
0.2.2 Available View build log
0.2.1 Available View build log
 
Author
License
BSD
Dependencies
Imports
Lastest release
version 0.2.5 on May 1st, 2013

Duo provides a few straightforward, Pythonic abstractions for working with Amazon Web Services' DynamoDB. It's a very light wrapper around boto.dynamodb.layer2, so you have full access to that excellent library when you need it, but you don't have to sweat the details when you don't.

Stern warning:

No seriously, it's a very light wrapper around boto.dynamodb.layer2. If you stray much beyond the usage examples below, you'd do best to be familiar with Boto's DynamoDB API. The docs are excellent. Reading duo's source may also be helpful. It's kept short for that reason.

Usage:

duo is made up of one module:

>>> import duo

The module isn't very big (at the time of this writing, ~700 lines). If you want to know how something works, you should read it.

Pre-create your tables in the AWS console, then write simple classes to access them. duo.Table Sub-classes are automatically registered with the db:

>>> class MyHashKeyTable(duo.Table):
...     table_name = 'my_hashkey_table'
...     hash_key_name = 'slug'
...     range_key_name = None  # Implicit default

duo.Item is a thin wrapper around boto.dynamodb.items.Item, with lots of syntactic sugar. duo.Item sub-classs are automatically registered with the db:

>>> import datetime

>>> class MyHashKeyItem(duo.Item):
...     table_name = 'my_hashkey_table'
...     hash_key_name = 'slug'
...
...     slug = duo.UnicodeField()
...     my_field = duo.UnicodeField(default='foo')
...     on_this_date = duo.DateField(default=lambda o: datetime.date.today())

Databases and Tables use dict-like access syntax:

>>> db = duo.DynamoDB(key='access_key', secret='secret_key')

>>> # The correct Table sub-class is matched by table name:
>>> table = duo.DynamoDB['my_hashkey_table']

>>> # The correct Item sub-class is matched by table name:
>>> item = table['new-item']

>>> # Items are actually dict subclasses, but that's not where the
>>> # fun is. They can only store unicode strings and integers:
>>> item['slug']
u'new-item'

Specify a field on an Item sub-class to get useful data types:

>>> item.is_new
True

>>> # A field doesn't exist initially...
>>> item['my_field']
Traceback (most recent call last):
  File "...", line 1, in <module>
    item['my_field']
KeyError: 'my_field'

>>> # But we specified a default.
>>> item.my_field
'foo'

>>> # The default, once accessed, gets populated:
>>> item['my_field']
'foo'

>>> # Or we can set our own value...
>>> item.my_field = 'bar'

>>> item['my_field']
'bar'

>>> # Finally, we save it to DynamoDB.
>>> item.put()

>>> item.is_new
False

Caching:

Duo integrates with any cache that implements a python-memcached-compatible interface, namely, the following:

import pylibmc
cache = pylibmc.Client(['127.0.0.1'])
cache.get(<keyname>)
cache.set(<keyname>, <duration-in-seconds>)
cache.delete(<keyname>)

Integrate caching by passing the cache to the db constructor:

>>> import duo
>>> db = duo.DynamoDB(key='access_key', secret='secret_key', cache=cache)

You can also specify a cache object on a per-table or per-item basis:

>>> class MyHashKeyTable(duo.Table):
 ...     cache = pylibmc.Client(['127.0.0.1'])
 ...
 ...     table_name = 'my_hashkey_table'
 ...     hash_key_name = 'slug'
 ...     range_key_name = None  # Implicit default

Caching is turned off by default, but you can turn it on by specifying a cache_duration as an integer (0 is forever):

>>> class MyHashKeyItem(duo.Item):
...     cache_duration = 30  # 30 seconds
...
...     table_name = 'my_hashkey_table'
...     hash_key_name = 'slug'
...
...     slug = duo.UnicodeField()
...     my_field = duo.UnicodeField(default='foo')
...     on_this_date = duo.DateField(default=lambda o: datetime.date.today())

Cache keys are determined by hash key, range key, and a cache prefix (set on the Table). By default, the cache prefix is the table name:

>>> table = duo.DynamoDB['my_hashkey_table']
>>> item = table['new-item']
>>> item.cache_prefix is None
True
>>>item._cache_key
'my_hashkey_table_new-item'
>>> MyHashKeyTable.cache_prefix = 'hello_world'
>>> item._get_cache_key()
'hello_world_new-item'

CHANGELOG

0.2.5

get_item() now writes to the cache, even though it doesn't read from the cache.

0.2.4

Added a custom get_item to Table, for specifying consistent reads, etc. Used by __getitem__, for simpler code!

0.2.3

One more packaging fix, so pip won't explode. Thanks, cbrinker!

0.2.2

Table.scan() and .query() should return extended Items.

0.2.1

Corrections/improvements to setup.py. Packaging is HARD.

0.2

Initial public release.

Subscribe to package updates

Last updated May 1st, 2013

Download Stats

Last month:4

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.