Potato
Type-safe DTOs for clean architecture in Python
Potato is a Python library that enforces clean separation between your domain models and external data representations. Built on Pydantic v2, it provides type-safe Data Transfer Objects (DTOs) with class-definition-time validation via metaclasses.
Features
- Type Safety: Class-definition-time validation via metaclasses
- Unidirectional Data Flow: Separate
ViewDTO(outbound) andBuildDTO(inbound) - Field Mapping: Map domain fields to different names using
Field(source=...) - Computed Fields: Add derived fields with
@computeddecorator - Auto Fields: Handle auto-generated fields with
Auto[T] - Private Fields: Protect sensitive fields with
Private[T](never exposed in DTOs) - Aggregates: Compose multiple domains with field-based aggregates
- Nested ViewDTOs: Auto-build nested ViewDTO types
- ViewDTO Inheritance: Extend ViewDTOs for summary/detail patterns
- Partial Updates:
BuildDTOwithpartial=Trueandapply_to() - Field Transforms: Transform values with
Field(transform=...) - Field Visibility: Control visibility with
Field(visible=...) - Lifecycle Hooks:
@before_buildand@after_builddecorators - Immutability: ViewDTOs are frozen by default
Quick Example
from potato import Domain, ViewDTO, BuildDTO, Field, Auto, Private, computed
# Define your domain model
class User(Domain):
id: Auto[int] # Auto-managed field
username: str
email: str
password_hash: Private[str] # Never exposed in DTOs
# Create a ViewDTO for API responses (outbound)
class UserView(ViewDTO[User]):
id: int
login: str = Field(source=User.username) # Map username -> login
email: str
@computed
def display_name(self, user: User) -> str:
return f"@{user.username}"
# Create a BuildDTO for API requests (inbound)
class UserCreate(BuildDTO[User]):
username: str
email: str
# 'id' (Auto) and 'password_hash' (Private) are excluded
# Usage - Outbound
user = User(id=1, username="alice", email="alice@example.com", password_hash="hashed")
view = UserView.from_domain(user)
print(view.login) # "alice"
print(view.display_name) # "@alice"
# Usage - Inbound
dto = UserCreate(username="bob", email="bob@example.com")
user = dto.to_domain(id=2, password_hash="hashed_value") # Provide auto & private fields
Installation
pip install potato
Or with uv:
uv add potato
Documentation
- Quickstart Guide - Get started in 5 minutes
- Philosophy - Understand the philosophy and design
- ViewDTO Guide - Outbound data flow
- BuildDTO Guide - Inbound data flow
- Aggregates - Multi-domain composition
- Validation - Class-definition-time validation
- Examples - Real-world use cases
Why Potato?
Modern applications need clear boundaries between:
- External data (API requests, database records)
- Domain logic (business models and rules)
- External representations (API responses, serialized data)
Potato enforces these boundaries with:
- Type-safe DTOs that prevent coupling
- Explicit transformations that are easy to trace
- Class-definition-time validation that catches errors early
- Immutable views that prevent accidental mutations
Development
# Install dependencies
uv sync
# Run tests
uv run pytest
# Type check
uv run mypy src/
# Run all checks
uv run pytest && uv run mypy src/
License
MIT
Ready to get started? -> Quickstart Guide
Metadata
Release files for potato-dto 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| potato_dto-0.1.0.tar.gz | 239.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| potato_dto-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 261.2 kB
Release files / potato_dto-0.1.0.tar.gz
| Download URL | potato_dto-0.1.0.tar.gz |
|---|---|
| Size | 239.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
42bb84ad4a72e2c8aa6180c6f950a68ad032d981fd617b42445c802d61f91ec4
|
|
BLAKE2b-256 checksum How to use checksums |
0a913a7a74c923d607f93717ce77470fee22895301ffeda865563810fd4407d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / potato_dto-0.1.0-py3-none-any.whl
| Download URL | potato_dto-0.1.0-py3-none-any.whl |
|---|---|
| Size | 22.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d472a957a408c859572345c961a6839cdb31eecbb9031680356851451ac8b8c6
|
|
BLAKE2b-256 checksum How to use checksums |
601746f1ffbb52e0c2262153c9a6b8b327b6b4f4fc197a759f9c52851610a981
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|