Type-safe discriminated unions for Pydantic models
Project description
pydantic-discriminated
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d748b902d319a39142f4b0991bc50a0eb58e4d02aa277cc54ee9b07f5aa5367
|
|
| MD5 |
6963ad453b848e60c03d1441b792cae6
|
|
| BLAKE2b-256 |
e6c7bd57c8a50d53851cf886830295efa4d9c1ad954c156ccc44a9e384e3fe68
|
Provenance
The following attestation bundles were made for pydantic_discriminated-0.1.3.tar.gz:
Publisher:
publish.yml on TalbotKnighton/pydantic-discriminated
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_discriminated-0.1.3.tar.gz -
Subject digest:
7d748b902d319a39142f4b0991bc50a0eb58e4d02aa277cc54ee9b07f5aa5367 - Sigstore transparency entry: 412443778
- Sigstore integration time:
-
Permalink:
TalbotKnighton/pydantic-discriminated@d45041cacfc7614c67c3f5aa10bde5e8a34a71f0 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/TalbotKnighton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d45041cacfc7614c67c3f5aa10bde5e8a34a71f0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantic_discriminated-0.1.3-py3-none-any.whl.
File metadata
- Download URL: pydantic_discriminated-0.1.3-py3-none-any.whl
- Upload date:
- Size: 3.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e838b04954ba3bc43d1bb3cb704d570e0de3523dda4ca58e6de00b4450c9958d
|
|
| MD5 |
897daaae4a7f2dda75fc19a55f110475
|
|
| BLAKE2b-256 |
65047a27db2a7a624aa3dced698a37ac33da29ce8f8612aaf5aa737fff4b7db3
|
Provenance
The following attestation bundles were made for pydantic_discriminated-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on TalbotKnighton/pydantic-discriminated
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_discriminated-0.1.3-py3-none-any.whl -
Subject digest:
e838b04954ba3bc43d1bb3cb704d570e0de3523dda4ca58e6de00b4450c9958d - Sigstore transparency entry: 412443792
- Sigstore integration time:
-
Permalink:
TalbotKnighton/pydantic-discriminated@d45041cacfc7614c67c3f5aa10bde5e8a34a71f0 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/TalbotKnighton
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d45041cacfc7614c67c3f5aa10bde5e8a34a71f0 -
Trigger Event:
push
-
Statement type: