Use StatelyDB with Python

Python developers value pragmatism, clarity, and speed. Yet, when it comes to databases, the landscape is often a mix of cumbersome abstractions and unstructured chaos. You are either navigating the heavy machinery of an Object-Relational Mapper (ORM) like SQLAlchemy, or you are working with raw dictionaries from a NoSQL database, sacrificing the very structure that makes robust applications possible.

StatelyDB offers a more Pythonic approach. We provide a schema-first workflow that generates clean, typed data classes, letting you interact with your database using an elegant, modern async API. Stop writing boilerplate and start building with a data layer that feels as clean and productive as Python itself.

The Python Data Disconnect

As a Python developer, you have likely encountered these familiar data-layer challenges:

ORM Complexity

You pull in SQLAlchemy and now you are managing Sessions, wrestling with a complex unit-of-work pattern, and trying to debug performance issues hidden behind a wall of abstraction. The tool meant to simplify things adds its own significant cognitive load.

The "Dict Soup" Problem

You use a NoSQL database like MongoDB or DynamoDB for its flexibility, but now your function signatures are filled with Dict[str, Any]. You have to write manual validation layers with libraries like Pydantic and your code is susceptible to KeyError exceptions at runtime because the shape of your data is not guaranteed.

Migration Hell

Evolving your data model means writing and managing complex migration scripts with tools like Alembic. Every change is a carefully orchestrated, high-risk deployment that can lead to downtime.

The StatelyDB Developer Experience

StatelyDB is designed to eliminate this friction, providing a developer experience that is simple, safe, and highly productive.

1
Define Your Schema Once

You use a NoSQL database like MongoDB or DynamoDB for its flexibility, but now your function signatures are filled with Dict[str, Any]. You have to write manual validation layers with libraries like Pydantic and your code is susceptible to KeyError exceptions at runtime because the shape of your data is not guaranteed.

import { itemType, string, uuid } from "@stately-cloud/schema";

/** A user of our new application. */
itemType("User", {
  keyPath: "/user-:id",
  fields: {
    id: { type: uuid, initialValue: "uuid" },
    name: { type: string },
    email: { type: string },
  },
});
2
Generate Native Python Data Classes

Run a single CLI command to generate a Python package containing type-hinted data classes for every item in your schema.

import { itemType, string, uuid } from "@stately-cloud/schema";

/** A user of our new application. */
itemType("User", {
  keyPath: "/user-:id",
  fields: {
    id: { type: uuid, initialValue: "uuid" },
    name: { type: string },
    email: { type: string },
  },
});

This generates Python code that you can import and use directly, with full support for tools like MyPy and editor autocompletion.

3
Interact with a Clean, Asynchronous API

With the generated client and data classes, working with StatelyDB feels natural in a modern Python codebase. Our API is minimal and leverages async/await for high-performance applications.

Compare the clarity of StatelyDB with the verbosity of a raw SDK like Boto3 for DynamoDB.

StatelyDB: Clean and Pythonic

from .stately_client import Client, User

async def create_user(client: Client, name: str, email: str) -> User:
    # Instantiate a typed data class.
    user_to_create = User(
        name=name,
        email=email
    )

    # The API is simple and returns a typed object.
    created_user = await client.put(user_to_create)
    print(f"Created user with ID: {created_user.id}")
    return created_user

Typical Boto3 for DynamoDB: Verbose and Untyped

import boto3
import uuid

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('my-table')

def create_user(name: str, email: str) -> dict:
    user_id = str(uuid.uuid4())

    # Manually construct a dictionary with DynamoDB's type descriptors.
    item = {
        'PK': {'S': f"USER#{user_id}"},
        'SK': {'S': 'METADATA'},
        'name': {'S': name},
        'email': {'S': email}
    }

    table.put_item(Item=item)

    # Return a raw dictionary, hoping the structure is correct.
    return {'id': user_id, 'name': name, 'email': email}

With StatelyDB, your code is cleaner, safer, and more maintainable. You spend less time writing boilerplate and more time delivering features.

4
Evolve Fearlessly

When your product requirements change, simply update your schema.ts file, add a migration command, and regenerate your Python client. StatelyDB's Elastic Schema guarantees that your changes are always backwards and forwards compatible. You can deploy new code with confidence, knowing you will not break older services or clients, and without the operational risk of traditional database migrations.

The StatelyDB Developer Experience

StatelyDB is designed to eliminate this friction, providing a developer experience that is simple, safe, and highly productive.

Define Your Schema Once

You use a NoSQL database like MongoDB or DynamoDB for its flexibility, but now your function signatures are filled with Dict[str, Any]. You have to write manual validation layers with libraries like Pydantic and your code is susceptible to KeyError exceptions at runtime because the shape of your data is not guaranteed.

import { itemType, string, uuid } from "@stately-cloud/schema";

/** A user of our new application. */
itemType("User", {
  keyPath: "/user-:id",
  fields: {
    id: { type: uuid, initialValue: "uuid" },
    name: { type: string },
    email: { type: string },
  },
});
Generate Native Python Data Classes

Run a single CLI command to generate a Python package containing type-hinted data classes for every item in your schema.

import { itemType, string, uuid } from "@stately-cloud/schema";

/** A user of our new application. */
itemType("User", {
  keyPath: "/user-:id",
  fields: {
    id: { type: uuid, initialValue: "uuid" },
    name: { type: string },
    email: { type: string },
  },
});

This generates Python code that you can import and use directly, with full support for tools like MyPy and editor autocompletion.

Interact with a Clean, Asynchronous API

With the generated client and data classes, working with StatelyDB feels natural in a modern Python codebase. Our API is minimal and leverages async/await for high-performance applications.

Compare the clarity of StatelyDB with the verbosity of a raw SDK like Boto3 for DynamoDB.

StatelyDB: Clean and Pythonic

from .stately_client import Client, User

async def create_user(client: Client, name: str, email: str) -> User:
    # Instantiate a typed data class.
    user_to_create = User(
        name=name,
        email=email
    )

    # The API is simple and returns a typed object.
    created_user = await client.put(user_to_create)
    print(f"Created user with ID: {created_user.id}")
    return created_user

Typical Boto3 for DynamoDB: Verbose and Untyped

import boto3
import uuid

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('my-table')

def create_user(name: str, email: str) -> dict:
    user_id = str(uuid.uuid4())

    # Manually construct a dictionary with DynamoDB's type descriptors.
    item = {
        'PK': {'S': f"USER#{user_id}"},
        'SK': {'S': 'METADATA'},
        'name': {'S': name},
        'email': {'S': email}
    }

    table.put_item(Item=item)

    # Return a raw dictionary, hoping the structure is correct.
    return {'id': user_id, 'name': name, 'email': email}

With StatelyDB, your code is cleaner, safer, and more maintainable. You spend less time writing boilerplate and more time delivering features.

Evolve Fearlessly

When your product requirements change, simply update your schema.ts file, add a migration command, and regenerate your Python client. StatelyDB's Elastic Schema guarantees that your changes are always backwards and forwards compatible. You can deploy new code with confidence, knowing you will not break older services or clients, and without the operational risk of traditional database migrations.

Get Started with Python

Ready to build with a database that feels like it was designed for Python?

1

Follow our Getting Started Guide to create your account, store, and schema.

2

Install the SDK: pip install statelydb

3

Generate your Python client code as shown above.

4

Initialize the client and start building with asyncio.

No items found.

No items found.

It is that simple

Start Building for Free