|
2 | 2 |
|
3 | 3 | DynamoDB data layer for [Chainlit](https://chainlit.io/).
|
4 | 4 |
|
5 |
| -## Usage |
| 5 | +## DynamoDB Data Layer |
| 6 | + |
| 7 | +This data layer supports Amazon DynamoDB with optional cloud storage integration for elements. |
| 8 | + |
| 9 | +Key features: |
| 10 | +- Single table design with efficient query patterns |
| 11 | +- Supports storage clients for attachments (S3, Azure Blob) |
| 12 | +- User/thread/step/element/feedback storage in DynamoDB |
| 13 | +- Built-in pagination and sorting |
| 14 | + |
| 15 | +## Setup Example (DynamoDB + Cloud Storage) |
| 16 | + |
| 17 | +1. Create DynamoDB table using the [CloudFormation template](#table-structure) |
| 18 | +2. Install required dependencies: |
| 19 | +```bash |
| 20 | +# Core requirements |
| 21 | +pip install chainlit-dynamodb |
| 22 | + |
| 23 | +# With cloud storage (choose one): |
| 24 | +pip install chainlit-dynamodb[s3] # AWS S3 |
| 25 | +pip install chainlit-dynamodb[azure-blob] # Azure Blob Storage |
| 26 | +pip install chainlit-dynamodb[gcs] # Google Cloud Storage |
| 27 | +pip install chainlit-dynamodb[azure] # Azure Data Lake |
| 28 | +``` |
| 29 | + |
| 30 | +3. Configure in your Chainlit app: |
| 31 | +```python |
| 32 | +import os |
| 33 | +import chainlit as cl |
| 34 | +from chainlit.data.dynamodb import DynamoDBDataLayer |
| 35 | +from chainlit.data.storage_clients import ( |
| 36 | + S3StorageClient, |
| 37 | + AzureBlobStorageClient, |
| 38 | + GCSStorageClient, |
| 39 | + AzureStorageClient |
| 40 | +) |
| 41 | + |
| 42 | +# Security Note: Always store secrets in environment variables |
| 43 | +# Never commit credentials to source control |
| 44 | +# Consider using secret managers like AWS Secrets Manager |
| 45 | + |
| 46 | +@cl.data_layer |
| 47 | +def get_data_layer(): |
| 48 | + # Choose one storage provider: |
| 49 | + |
| 50 | + # AWS S3 Example |
| 51 | + storage_client = S3StorageClient( |
| 52 | + bucket="<your-bucket>", |
| 53 | + region_name="<your-region>", |
| 54 | + aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"], |
| 55 | + aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"] |
| 56 | + ) |
| 57 | + |
| 58 | + # Azure Blob Example |
| 59 | + # storage_client = AzureBlobStorageClient( |
| 60 | + # container_name="<your-container>", |
| 61 | + # storage_account="<your-account>", |
| 62 | + # storage_key="<your-key>" |
| 63 | + # ) |
| 64 | + |
| 65 | + # Google Cloud Storage Example |
| 66 | + # storage_client = GCSStorageClient( |
| 67 | + # project_id="<your-project>", |
| 68 | + # client_email="<your-email>", |
| 69 | + # private_key="<your-key>", |
| 70 | + # bucket_name="<your-bucket>" |
| 71 | + # ) |
| 72 | + |
| 73 | + # Azure Data Lake Example |
| 74 | + # storage_client = AzureStorageClient( |
| 75 | + # account_url="https://<account>.dfs.core.windows.net", |
| 76 | + # credential="<your-credential>", |
| 77 | + # container_name="<your-container>" |
| 78 | + # ) |
| 79 | + |
| 80 | + return DynamoDBDataLayer( |
| 81 | + table_name="<your-table-name>", |
| 82 | + storage_provider=storage_client, |
| 83 | + user_thread_limit=10 |
| 84 | + ) |
| 85 | +``` |
| 86 | + |
| 87 | +## Table Structure |
| 88 | +```yaml |
| 89 | +# CloudFormation template for required table structure |
| 90 | +AWSTemplateFormatVersion: 2010-09-09 |
| 91 | +Resources: |
| 92 | + DynamoDBTable: |
| 93 | + Type: AWS::DynamoDB::Table |
| 94 | + Properties: |
| 95 | + TableName: "<YOUR-TABLE-NAME>" |
| 96 | + AttributeDefinitions: |
| 97 | + - AttributeName: PK |
| 98 | + AttributeType: S |
| 99 | + - AttributeName: SK |
| 100 | + AttributeType: S |
| 101 | + - AttributeName: UserThreadPK |
| 102 | + AttributeType: S |
| 103 | + - AttributeName: UserThreadSK |
| 104 | + AttributeType: S |
| 105 | + KeySchema: |
| 106 | + - AttributeName: PK |
| 107 | + KeyType: HASH |
| 108 | + - AttributeName: SK |
| 109 | + KeyType: RANGE |
| 110 | + GlobalSecondaryIndexes: |
| 111 | + - IndexName: UserThread |
| 112 | + KeySchema: |
| 113 | + - AttributeName: UserThreadPK |
| 114 | + KeyType: HASH |
| 115 | + - AttributeName: UserThreadSK |
| 116 | + KeyType: RANGE |
| 117 | + Projection: |
| 118 | + ProjectionType: INCLUDE |
| 119 | + NonKeyAttributes: [id, name] |
| 120 | + BillingMode: PAY_PER_REQUEST |
| 121 | +``` |
| 122 | +
|
| 123 | +## Logging |
| 124 | +```python |
| 125 | +import logging |
| 126 | +from chainlit import logger |
| 127 | + |
| 128 | +# Enable debug logging for DynamoDB operations |
| 129 | +logger.getChild("DynamoDB").setLevel(logging.DEBUG) |
| 130 | +``` |
| 131 | + |
| 132 | +## Limitations |
| 133 | +- Feedback filtering not supported |
| 134 | +- Boto3-based implementation uses blocking IO (not async) |
| 135 | +- Decimal types in feedback values require special handling |
| 136 | + |
| 137 | +## Design |
| 138 | +Uses single-table design with entity prefixes: |
| 139 | +- Users: `USER#{identifier}` |
| 140 | +- Threads: `THREAD#{thread_id}` |
| 141 | +- Steps: `STEP#{step_id}` |
| 142 | +- Elements: `ELEMENT#{element_id}` |
| 143 | + |
| 144 | +Global Secondary Index (UserThread) enables efficient user thread queries. |
0 commit comments