Skip to main content

Type-safe discriminated unions for Pydantic models

Project description

pydantic-discriminated

PyPI Version Python Versions License Documentation

Type-safe discriminated unions for Pydantic models.

What are Discriminated Unions?

Discriminated unions (also called tagged unions) let you work with polymorphic data in a type-safe way. A "discriminator" field tells you which concrete type you're dealing with.

from pydantic_discriminated import discriminated_model, DiscriminatedBaseModel

@discriminated_model("shape_type", "circle")
class Circle(DiscriminatedBaseModel):
    radius: float
    
    def area(self) -> float:
        return 3.14159 * self.radius ** 2

@discriminated_model("shape_type", "rectangle")
class Rectangle(DiscriminatedBaseModel):
    width: float
    height: float
    
    def area(self) -> float:
        return self.width * self.height

# Parse data with the correct type
data = {"shape_type": "circle", "radius": 5}
circle = Circle.model_validate(data)  # Fully typed as Circle
print(f"Area: {circle.area()}")  # 78.53975

Features

  • 🔍 Type Safety: Proper type hints for IDE autocomplete and static analysis
  • 📦 Nested Models: Works with models nested at any level
  • 🔄 Seamless Integration: Uses standard Pydantic methods (model_validate, model_dump)
  • 🧩 Polymorphic Validation: Automatically validates and dispatches to the correct model type
  • 📚 OpenAPI Compatible: Works great with FastAPI for generating correct schemas

Installation

pip install pydantic-discriminated

Quick Example

Define discriminated models for different event types:

from enum import Enum
from typing import List, Union
from pydantic import BaseModel

from pydantic_discriminated import discriminated_model, DiscriminatedBaseModel

class EventType(str, Enum):
    USER_CREATED = "user_created"
    USER_UPDATED = "user_updated"
    LOGIN_ATTEMPT = "login_attempt"

@discriminated_model(EventType, EventType.USER_CREATED)
class UserCreatedEvent(DiscriminatedBaseModel):
    user_id: str
    username: str

@discriminated_model(EventType, EventType.USER_UPDATED)
class UserUpdatedEvent(DiscriminatedBaseModel):
    user_id: str
    fields_changed: List[str]

@discriminated_model(EventType, EventType.LOGIN_ATTEMPT)
class LoginAttemptEvent(DiscriminatedBaseModel):
    user_id: str
    success: bool
    ip_address: str

# Container that handles any event type
class EventProcessor(BaseModel):
    events: List[Union[UserCreatedEvent, UserUpdatedEvent, LoginAttemptEvent]]
    
    def process(self):
        for event in self.events:
            if isinstance(event, UserCreatedEvent):
                print(f"New user created: {event.username}")
            elif isinstance(event, UserUpdatedEvent):
                print(f"User {event.user_id} updated fields: {event.fields_changed}")
            elif isinstance(event, LoginAttemptEvent):
                result = "succeeded" if event.success else "failed"
                print(f"Login {result} for user {event.user_id} from {event.ip_address}")

Documentation

When To Use

This library is perfect for:

  • API Responses: When endpoints return different object types
  • Event Systems: Handling different event types in a type-safe way
  • State Machines: Representing different states with specific properties
  • Polymorphic Data: Working with heterogeneous data structures

Resources

License

MIT


Built by Talbot Knighton

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

pydantic_discriminated-0.1.3.tar.gz (5.2 kB view details)

Uploaded Source

Built Distribution

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

pydantic_discriminated-0.1.3-py3-none-any.whl (3.6 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_discriminated-0.1.3.tar.gz.

File metadata

  • Download URL: pydantic_discriminated-0.1.3.tar.gz
  • Upload date:
  • Size: 5.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pydantic_discriminated-0.1.3.tar.gz
Algorithm Hash digest
SHA256 7d748b902d319a39142f4b0991bc50a0eb58e4d02aa277cc54ee9b07f5aa5367
MD5 6963ad453b848e60c03d1441b792cae6
BLAKE2b-256 e6c7bd57c8a50d53851cf886830295efa4d9c1ad954c156ccc44a9e384e3fe68

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_discriminated-0.1.3.tar.gz:

Publisher: publish.yml on TalbotKnighton/pydantic-discriminated

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydantic_discriminated-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_discriminated-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e838b04954ba3bc43d1bb3cb704d570e0de3523dda4ca58e6de00b4450c9958d
MD5 897daaae4a7f2dda75fc19a55f110475
BLAKE2b-256 65047a27db2a7a624aa3dced698a37ac33da29ce8f8612aaf5aa737fff4b7db3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydantic_discriminated-0.1.3-py3-none-any.whl:

Publisher: publish.yml on TalbotKnighton/pydantic-discriminated

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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