Skip to main content

Lightweight DynamoDB JSON storage with automatic TTL support

Project description

Dynamorator

Lightweight DynamoDB JSON storage with automatic TTL support. A simple, reliable wrapper for storing and retrieving JSON data in AWS DynamoDB.

Features

  • Simple key-value JSON storage in DynamoDB
  • Automatic TTL (Time To Live) support
  • Automatic table creation with proper configuration
  • Silent error handling - never crashes your application
  • Shared boto3 client for efficiency
  • Optional logging with logorator
  • Minimal dependencies (boto3, logorator)

Installation

pip install dynamorator

Quick Start

from dynamorator import DynamoDBStore

# Initialize (table will be auto-created if it doesn't exist)
store = DynamoDBStore(table_name="my-data-store")

# Store data (expires in 7 days)
store.put("user:123", {"name": "Alice", "score": 100}, ttl_days=7)

# Retrieve data
data = store.get("user:123")  # Returns dict or None
print(data)  # {'name': 'Alice', 'score': 100}

# List all keys
result = store.list_keys(limit=50)
print(result['keys'])  # ['user:123', ...]

# Delete data
store.delete("user:123")

Silent Mode

Disable logging for production environments:

# With logging (default)
store = DynamoDBStore(table_name="my-store")

# Silent mode - no logging
store = DynamoDBStore(table_name="my-store", silent=True)

AWS Credentials Setup

Dynamorator uses boto3, which follows the standard AWS credential chain:

  1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  2. AWS credentials file (~/.aws/credentials)
  3. IAM role (when running on EC2, ECS, Lambda, etc.)

See AWS Boto3 Configuration for details.

Required IAM Permissions

Your AWS credentials need the following DynamoDB permissions:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:CreateTable",
        "dynamodb:DescribeTable",
        "dynamodb:UpdateTimeToLive",
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:DeleteItem",
        "dynamodb:Scan"
      ],
      "Resource": "arn:aws:dynamodb:*:*:table/your-table-name"
    }
  ]
}

If the table already exists, you only need: PutItem, GetItem, DeleteItem, and Scan.

API Reference

DynamoDBStore(table_name=None, silent=False)

Initialize the store.

Parameters:

  • table_name (str, optional): DynamoDB table name. If None, the store is disabled.
  • silent (bool, optional): If True, disables all logging output. Default is False.

Behavior:

  • Automatically creates the table if it doesn't exist
  • Uses PAY_PER_REQUEST billing mode
  • Configures TTL on the ttl attribute
  • Table schema: partition key cache_id (String)

is_enabled() -> bool

Check if the store is enabled.

Returns: True if table_name is set, False otherwise.

store = DynamoDBStore(table_name="my-store")
if store.is_enabled():
    print("Store is ready!")

get(key: str) -> Optional[dict]

Retrieve JSON data by key.

Parameters:

  • key (str): The key to retrieve

Returns: Dictionary if found, None if not found or on error.

data = store.get("user:123")
if data:
    print(f"Found: {data}")
else:
    print("Not found")

put(key: str, data: dict, ttl_days: float)

Store JSON data with TTL.

Parameters:

  • key (str): The key to store under
  • data (dict): JSON-serializable dictionary
  • ttl_days (float): Expiration time in days (can be fractional, e.g., 0.5 for 12 hours)

Behavior:

  • Silently fails on error (no exceptions raised)
  • Automatically handles datetime objects in data using DateTimeEncoder
  • Stores creation timestamp for tracking
from datetime import datetime

store.put("session:abc", {
    "user_id": 123,
    "created": datetime.now(),
    "expires": datetime(2026, 12, 31)
}, ttl_days=1)

delete(key: str)

Delete an entry by key.

Parameters:

  • key (str): The key to delete

Behavior:

  • Silently fails on error (no exceptions raised)
store.delete("user:123")

list_keys(limit=100, last_key=None) -> dict

List keys in the table with pagination support.

Parameters:

  • limit (int): Maximum number of keys to return (default: 100)
  • last_key (str, optional): Pagination token from previous call

Returns: Dictionary with:

  • keys (list): List of key strings
  • last_key (str or None): Token for next page, or None if no more results
# Get first page
result = store.list_keys(limit=50)
print(result['keys'])

# Get next page if available
if result['last_key']:
    next_result = store.list_keys(limit=50, last_key=result['last_key'])
    print(next_result['keys'])

Table Structure

Dynamorator creates tables with the following structure:

Partition Key: cache_id (String)

Attributes:
  - data (String)       - JSON serialized dictionary
  - ttl (Number)        - Unix timestamp for expiration
  - created_at (Number) - Unix timestamp of creation

TTL: Enabled on 'ttl' attribute
Billing: PAY_PER_REQUEST

TTL Behavior

DynamoDB's TTL feature:

  • Automatically deletes expired items (usually within 48 hours of expiration)
  • Doesn't consume write capacity
  • Items may still be returned by queries shortly after expiration
  • Free of charge

Example TTL values:

store.put(key, data, ttl_days=7)      # 7 days
store.put(key, data, ttl_days=0.5)    # 12 hours
store.put(key, data, ttl_days=30)     # 30 days
store.put(key, data, ttl_days=365)    # 1 year

Error Handling

Dynamorator follows a "silent failure" philosophy:

  • get() returns None on errors
  • put() and delete() fail silently
  • Only table creation operations raise exceptions

This design ensures your application continues running even if DynamoDB is temporarily unavailable.

# Safe to use without try/except
data = store.get("key")  # Returns None on error
store.put("key", {"value": 1}, ttl_days=1)  # Silent on error
store.delete("key")  # Silent on error

DateTimeEncoder

Automatically handles datetime serialization:

from datetime import datetime
from dynamorator import DynamoDBStore

store = DynamoDBStore(table_name="events")

# Datetime objects are automatically converted to ISO format
store.put("event:1", {
    "name": "Meeting",
    "scheduled": datetime(2026, 3, 15, 14, 30),
    "created": datetime.now()
}, ttl_days=30)

# Retrieved as ISO strings
data = store.get("event:1")
# {'name': 'Meeting', 'scheduled': '2026-03-15T14:30:00', 'created': '2026-02-21T...'}

Use Cases

  • Session Storage: Store user sessions with automatic expiration
  • Cache Layer: Simple caching for API responses or computed data
  • Feature Flags: Store and retrieve feature flag configurations
  • Temporary Data: Any data that should automatically expire
  • User Preferences: Store user settings with optional expiration

Disabled Mode

Pass None as table_name to disable the store (useful for testing or optional features):

import os

# Only enable in production
table_name = os.getenv("DYNAMODB_TABLE") if os.getenv("ENV") == "production" else None
store = DynamoDBStore(table_name=table_name)

# Safe to call even when disabled
store.put("key", {"data": 1}, ttl_days=1)  # No-op when disabled
data = store.get("key")  # Returns None when disabled

License

MIT License - see LICENSE file for details.

Author

Arved Klöhn

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dynamorator-0.1.4.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dynamorator-0.1.4-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file dynamorator-0.1.4.tar.gz.

File metadata

  • Download URL: dynamorator-0.1.4.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for dynamorator-0.1.4.tar.gz
Algorithm Hash digest
SHA256 d005042e8b7db35811d864ede1e9fb955c8b3829dac6be3dbb5441a80100dc0a
MD5 00f14340c804f101bc5ce45f58864e37
BLAKE2b-256 f2827d1e8ad9814cf5014c0a44e6e9d63029e92c3a45119d862744495a8001fa

See more details on using hashes here.

File details

Details for the file dynamorator-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: dynamorator-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for dynamorator-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e38f67e1e0c927c0d02f6e4956a2f144a7322d8c572fdbc1a1edec39b81e9a3a
MD5 42e77e35b42c5e289f880f312bac6d45
BLAKE2b-256 68dc60eedec5d4a73ca2aca8e001569dfdc2076b6be968a933f6f78a0c5c3a0d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page