Skip to main content

Type-safe DTOs for clean architecture in Python, built on Pydantic v2

Project description

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) and BuildDTO (inbound)
  • Field Mapping: Map domain fields to different names using Field(source=...)
  • Computed Fields: Add derived fields with @computed decorator
  • 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: BuildDTO with partial=True and apply_to()
  • Field Transforms: Transform values with Field(transform=...)
  • Field Visibility: Control visibility with Field(visible=...)
  • Lifecycle Hooks: @before_build and @after_build decorators
  • 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

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

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

potato_dto-0.1.0.tar.gz (239.1 kB view details)

Uploaded Source

Built Distribution

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

potato_dto-0.1.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file potato_dto-0.1.0.tar.gz.

File metadata

  • Download URL: potato_dto-0.1.0.tar.gz
  • Upload date:
  • Size: 239.1 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for potato_dto-0.1.0.tar.gz
Algorithm Hash digest
SHA256 42bb84ad4a72e2c8aa6180c6f950a68ad032d981fd617b42445c802d61f91ec4
MD5 d676116c393fca6833b90cefa1043edf
BLAKE2b-256 0a913a7a74c923d607f93717ce77470fee22895301ffeda865563810fd4407d8

See more details on using hashes here.

File details

Details for the file potato_dto-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: potato_dto-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for potato_dto-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d472a957a408c859572345c961a6839cdb31eecbb9031680356851451ac8b8c6
MD5 907ceec15df06311ada6d35d45d106e5
BLAKE2b-256 601746f1ffbb52e0c2262153c9a6b8b327b6b4f4fc197a759f9c52851610a981

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