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.
As a Python developer, you have likely encountered these familiar data-layer challenges:
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.
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.
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.
StatelyDB is designed to eliminate this friction, providing a developer experience that is simple, safe, and highly productive.
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 },
},
});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.
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_userTypical 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.
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.
StatelyDB is designed to eliminate this friction, providing a developer experience that is simple, safe, and highly productive.
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 },
},
});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.
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_userTypical 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.
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.
Ready to build with a database that feels like it was designed for Python?
Follow our Getting Started Guide to create your account, store, and schema.
Install the SDK: pip install statelydb
Generate your Python client code as shown above.
Initialize the client and start building with asyncio.
It is that simple