# Pydantic Variants 🔄
> **Transform your Pydantic models into multiple variants without code duplication**
Create input schemas, output DTOs, and database models from a single source of truth. Perfect for FastAPI applications where you need different model variants for different parts of your data flow.
## 🎯 Motivation
When developing APIs, the main model in your schema often contains internal data such as revision numbers, IDs, timestamps, or sensitive information. Different parts of your application need different views of the same model:
- **Input validation** - exclude system-generated fields (IDs, timestamps)
- **Update operations** - make most fields optional for PATCH requests
- **Output responses** - hide sensitive or internal fields
- **Database models** - include all internal fields
This library avoids code duplication by creating hardcoded multiple variants of the same model. Instead, you define your schema once and use transformation pipelines to create the variants you need.
Built during a FastAPI + Beanie project where FastAPI generates automatic OpenAPI schemas from route definitions, this library provides a single source of truth for your schema without duplicating fields across model variants that are mostly overlapping.
Pipelines are defined per use case (input, output, admin), and are somewhat orthogonal to model definitions which define data schema.
pydantic-variants allows defining a few pipelines and applying them to as many models as needed.
By attaching the resulting variants to the root model, arbitrary deep variant nesting changes can be done. so the Input variant of `Customer` will also use the Input variant of `Address` for example.
## 🚀 Installation
```bash
pip install pydantic-variants
# or
uv add pydantic-variants
```
## 🏃♂️ Quick Start
```python
from datetime import datetime
from pydantic import BaseModel
from pydantic_variants import variants, basic_variant_pipeline
from pydantic_variants.transformers import FilterFields, MakeOptional
input_pipeline = basic_variant_pipeline('Input',
FilterFields(exclude=['id', 'created_at', 'updated_at']),
MakeOptional(all=True)
)
output_pipeline = basic_variant_pipeline('Output',
FilterFields(exclude=['password_hash', 'internal_notes'])
)
update_pipeline = basic_variant_pipeline('Update',
FilterFields(exclude=['id', 'created_at']),
MakeOptional(all=True)
)
@variants(input_pipeline, output_pipeline, update_pipeline)
class User(BaseModel):
id: int
username: str
email: str
password_hash: str
full_name: str | None = None
internal_notes: str = ""
created_at: datetime
updated_at: datetime
# Use the variants
user_input = User.Input(username="john", email="john@example.com")
user_output = User.Output(**user.model_dump(), id=1, created_at=datetime.now())
user_update = User.Update(full_name="John Doe")
```
## 🤔 Why Pydantic Variants?
### The Problem
Without Pydantic Variants, you'd write repetitive, error-prone code:
```python
# 😩 Multiple model definitions with duplicate fields
class UserBase(BaseModel):
username: str
email: str
full_name: str | None = None
class UserInput(UserBase):
pass
class UserOutput(UserBase):
id: int
created_at: datetime
class UserUpdate(BaseModel):
username: str | None = None
email: str | None = None
full_name: str | None = None
class User(UserBase):
id: int
password_hash: str
internal_notes: str = ""
created_at: datetime
updated_at: datetime
```
### The Solution
With Pydantic Variants, define once, transform many:
```python
# 😍 Single source of truth with transformation pipelines
input_pipeline = basic_variant_pipeline('Input',
FilterFields(exclude=['id', 'created_at'])
)
output_pipeline = basic_variant_pipeline('Output',
FilterFields(exclude=['password_hash'])
)
update_pipeline = basic_variant_pipeline('Update',
MakeOptional(all=True)
)
@variants(input_pipeline, output_pipeline, update_pipeline)
class User(BaseModel):
# Define once, use everywhere
...
```
## 🏗️ Architecture
Pydantic Variants uses a **pipeline architecture** with transformers. The architecture is designed to be easily enhanced with your own transformers.
```
BaseModel → VariantContext → [Field Transformers] → BuildVariant → [Model Transformers] → ConnectVariant
```
**Pipeline Order Matters:**
1. **VariantContext** - Opens the model into decomposed form
2. **Field Transformers** - Work with DecomposedModel (filter, rename, make optional)
3. **BuildVariant** - Converts to built Pydantic model
4. **Model Transformers** - Work with built models (attach attributes, etc.)
5. **ConnectVariant** - Attaches variant to original model
Use `basic_variant_pipeline()` to avoid this boilerplate if desired.
## 📚 Core Concepts
### Pipeline Composition
Define reusable pipeline components:
```python
from pydantic_variants.transformers import *
# Reusable pipeline components
api_input_base = [
FilterFields(exclude=['id', 'created_at', 'updated_at']),
MakeOptional(exclude=['email']) # email still required
]
public_output_base = [
FilterFields(exclude=['password_hash', 'internal_notes', 'deleted_at'])
]
# Compose into specific pipelines
user_input_pipeline = basic_variant_pipeline('Input', *api_input_base)
user_output_pipeline = basic_variant_pipeline('Output', *public_output_base)
admin_output_pipeline = basic_variant_pipeline('AdminView',
FilterFields(exclude=['password_hash']), # Admin sees more fields
SetFields({
'admin_notes': FieldInfo(annotation=str, default="")
})
)
```
### Available Transformers
```python
# Filter out fields
filter_sensitive = FilterFields(exclude=['password', 'internal_id'])
keep_public = FilterFields(include_only=['name', 'email'])
# Make fields optional
all_optional = MakeOptional(all=True)
except_required = MakeOptional(exclude=['id'])
specific_optional = MakeOptional(include_only=['description'])
# Rename fields
rename_legacy = RenameFields(mapping={'user_id': 'id', 'email_addr': 'email'})
# Modify field properties
update_validation = ModifyFields({
'email': {'validation_alias': 'email_address'},
'name': {'default': 'Anonymous'}
})
# Switch nested model variants
use_input_variants = SwitchVariant('Input')
```
## 🌟 Advanced Features
### Nested Model Variants
Automatically transform nested models using variants attached to the root model under the `_variants` dict attribute:
```python
address_input = basic_variant_pipeline('Input',
FilterFields(exclude=['id'])
)
@variants(address_input)
class Address(BaseModel):
id: int
street: str
city: str
country: str
user_input = basic_variant_pipeline('Input',
FilterFields(exclude=['id']),
SwitchVariant('Input') # Uses Address.Input for address field
)
@variants(user_input)
class User(BaseModel):
id: int
name: str
address: Address # Becomes Address.Input in User.Input variant
```
### Custom Advanced Pipelines
Build complex pipelines with the full pipeline API:
```python
from pydantic_variants import VariantPipe, VariantContext
from pydantic_variants.transformers import *
# Advanced pipeline with custom logic
admin_pipeline = VariantPipe(
VariantContext('Admin'),
FilterFields(exclude=['password_hash']),
SetFields({
'admin_notes': FieldInfo(annotation=str, default=""),
'permissions': FieldInfo(annotation=list[str], default_factory=list)
}),
SwitchVariant('Admin'), # Use Admin variants of nested models
BuildVariant(name_suffix="Admin"),
ConnectVariant()
)
@variants(admin_pipeline)
class User(BaseModel):
# Your model definition
...
```
### Dynamic Field Logic
Create complex field transformation logic:
```python
def smart_optional_logic(name: str, field: FieldInfo) -> tuple[bool, Any]:
"""Custom logic for making fields optional"""
if name.endswith('_id'):
return True, None
elif name == 'created_at':
return True, DefaultFactoryTag(datetime.now)
elif name.startswith('internal_'):
return True, ""
return False, None
smart_optional = basic_variant_pipeline('SmartOptional',
MakeOptional(optional_func=smart_optional_logic)
)
```
## 🔧 FastAPI Integration
Perfect integration with FastAPI's automatic OpenAPI schema generation:
```python
from fastapi import FastAPI
app = FastAPI()
# Define pipelines clearly
create_pipeline = basic_variant_pipeline('Create',
FilterFields(exclude=['id', 'created_at'])
)
response_pipeline = basic_variant_pipeline('Response',
FilterFields(exclude=['password_hash'])
)
@variants(create_pipeline, response_pipeline)
class User(BaseModel):
id: int
username: str
email: str
password_hash: str
created_at: datetime
@app.post("/users/", response_model=User.Response)
async def create_user(user: User.Create):
# FastAPI automatically generates:
# - User.Create schema for request body validation
# - User.Response schema for response documentation
return User.Response(**user.model_dump(), id=123, created_at=datetime.now())
```
## ⚠️ Schema Rebuilding
If your schema has forward references, use the variants decorator (as a simple function) **after** the schema is completely defined and rebuilt:
```python
# Define all models first
class User(BaseModel):
name: str
posts: list['Post']
class Post(BaseModel):
title: str
author: User
# Rebuild models to resolve forward references
User.model_rebuild()
# Apply variants after all models are well defined
user_pipeline = basic_variant_pipeline('Input', FilterFields(exclude=['id']))
post_pipeline = basic_variant_pipeline('Input', FilterFields(exclude=['id']))
User = variants(user_pipeline)(User)
Post = variants(post_pipeline)(Post)
```
## 📖 Complete API Reference
### Decorators
- `@variants(*pipelines)` - Main decorator for creating variants
- `basic_variant_pipeline(name, *transformers)` - Helper for common transformation patterns
### Core Classes
- `VariantPipe(*operations)` - Immutable pipeline for chaining transformations
- `VariantContext(name)` - Initializes transformation context
- `DecomposedModel` - Internal representation for field manipulation
### Field Transformers (work with DecomposedModel)
- `FilterFields(exclude/include_only/filter_func)` - Remove/keep specific fields
- `MakeOptional(all/exclude/include_only/optional_func)` - Make fields optional
- `RenameFields(mapping/rename_func)` - Rename fields
- `ModifyFields(field_modifications)` - Modify field properties
- `SetFields(fields)` - Add or replace fields
- `SwitchVariant(variant_name)` - Use variants of nested models
### Model Transformers (work with built models)
- `BuildVariant(base, name_suffix, doc)` - Build final Pydantic model
- `ConnectVariant(attach_directly, attach_root)` - Attach variant to original model
- `SetAttribute(variant_attrs, root_attrs)` - Set class attributes
## 🤝 Contributing
We welcome contributions! The architecture is designed to be easily enhanced with your own transformers.
## 📄 License
This project is licensed under the Apache V2.0 - see the [LICENSE](LICENSE) file for details.
## 🔗 Related Projects
- [Pydantic](https://pydantic.dev/) - Data validation using Python type hints
- [FastAPI](https://fastapi.tiangolo.com/) - Modern web framework for APIs
- [Beanie](https://beanie-odm.dev/) - Async ODM for MongoDB
## 🎉 Acknowledgments
Built during a FastAPI + Beanie project, inspired by the need for a single source of truth in API schema design.
---
⭐ **Star this repo if Pydantic Variants helps you build better APIs!**
Raw data
{
"_id": null,
"home_page": null,
"name": "pydantic-variants",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "api, crud, dataclass, decorator, fastapi, forms, json, model, models, orm, pydantic, rest, schema, serialization, typing, validation",
"author": null,
"author_email": "MikeOfZen <michael.zl.prime@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/34/87/decf36c7ad1ccc283bb7f9af59980df3641a991210946a219390b999c47e/pydantic_variants-0.2.0.tar.gz",
"platform": null,
"description": "# Pydantic Variants \ud83d\udd04\n\n> **Transform your Pydantic models into multiple variants without code duplication**\n\nCreate input schemas, output DTOs, and database models from a single source of truth. Perfect for FastAPI applications where you need different model variants for different parts of your data flow.\n\n## \ud83c\udfaf Motivation\n\nWhen developing APIs, the main model in your schema often contains internal data such as revision numbers, IDs, timestamps, or sensitive information. Different parts of your application need different views of the same model:\n\n- **Input validation** - exclude system-generated fields (IDs, timestamps)\n- **Update operations** - make most fields optional for PATCH requests \n- **Output responses** - hide sensitive or internal fields\n- **Database models** - include all internal fields\n\nThis library avoids code duplication by creating hardcoded multiple variants of the same model. Instead, you define your schema once and use transformation pipelines to create the variants you need.\n\nBuilt during a FastAPI + Beanie project where FastAPI generates automatic OpenAPI schemas from route definitions, this library provides a single source of truth for your schema without duplicating fields across model variants that are mostly overlapping.\n\nPipelines are defined per use case (input, output, admin), and are somewhat orthogonal to model definitions which define data schema.\npydantic-variants allows defining a few pipelines and applying them to as many models as needed.\n\nBy attaching the resulting variants to the root model, arbitrary deep variant nesting changes can be done. so the Input variant of `Customer` will also use the Input variant of `Address` for example.\n\n## \ud83d\ude80 Installation\n\n```bash\npip install pydantic-variants\n# or\nuv add pydantic-variants\n```\n\n## \ud83c\udfc3\u200d\u2642\ufe0f Quick Start\n\n```python\nfrom datetime import datetime\nfrom pydantic import BaseModel\nfrom pydantic_variants import variants, basic_variant_pipeline\nfrom pydantic_variants.transformers import FilterFields, MakeOptional\n\ninput_pipeline = basic_variant_pipeline('Input',\n FilterFields(exclude=['id', 'created_at', 'updated_at']),\n MakeOptional(all=True)\n)\n\noutput_pipeline = basic_variant_pipeline('Output',\n FilterFields(exclude=['password_hash', 'internal_notes'])\n)\n\nupdate_pipeline = basic_variant_pipeline('Update',\n FilterFields(exclude=['id', 'created_at']),\n MakeOptional(all=True)\n)\n\n@variants(input_pipeline, output_pipeline, update_pipeline)\nclass User(BaseModel):\n id: int\n username: str\n email: str\n password_hash: str\n full_name: str | None = None\n internal_notes: str = \"\"\n created_at: datetime\n updated_at: datetime\n\n# Use the variants\nuser_input = User.Input(username=\"john\", email=\"john@example.com\")\nuser_output = User.Output(**user.model_dump(), id=1, created_at=datetime.now())\nuser_update = User.Update(full_name=\"John Doe\")\n```\n\n## \ud83e\udd14 Why Pydantic Variants?\n\n### The Problem\nWithout Pydantic Variants, you'd write repetitive, error-prone code:\n\n```python\n# \ud83d\ude29 Multiple model definitions with duplicate fields\nclass UserBase(BaseModel):\n username: str\n email: str\n full_name: str | None = None\n\nclass UserInput(UserBase):\n pass\n\nclass UserOutput(UserBase):\n id: int\n created_at: datetime\n\nclass UserUpdate(BaseModel):\n username: str | None = None\n email: str | None = None\n full_name: str | None = None\n\nclass User(UserBase):\n id: int\n password_hash: str\n internal_notes: str = \"\"\n created_at: datetime\n updated_at: datetime\n```\n\n### The Solution\nWith Pydantic Variants, define once, transform many:\n\n```python\n# \ud83d\ude0d Single source of truth with transformation pipelines\ninput_pipeline = basic_variant_pipeline('Input', \n FilterFields(exclude=['id', 'created_at'])\n)\noutput_pipeline = basic_variant_pipeline('Output', \n FilterFields(exclude=['password_hash'])\n)\nupdate_pipeline = basic_variant_pipeline('Update', \n MakeOptional(all=True)\n)\n\n@variants(input_pipeline, output_pipeline, update_pipeline)\nclass User(BaseModel):\n # Define once, use everywhere\n ...\n```\n\n## \ud83c\udfd7\ufe0f Architecture\n\nPydantic Variants uses a **pipeline architecture** with transformers. The architecture is designed to be easily enhanced with your own transformers.\n\n```\nBaseModel \u2192 VariantContext \u2192 [Field Transformers] \u2192 BuildVariant \u2192 [Model Transformers] \u2192 ConnectVariant\n```\n\n**Pipeline Order Matters:**\n1. **VariantContext** - Opens the model into decomposed form\n2. **Field Transformers** - Work with DecomposedModel (filter, rename, make optional)\n3. **BuildVariant** - Converts to built Pydantic model \n4. **Model Transformers** - Work with built models (attach attributes, etc.)\n5. **ConnectVariant** - Attaches variant to original model\n\nUse `basic_variant_pipeline()` to avoid this boilerplate if desired.\n\n## \ud83d\udcda Core Concepts\n\n### Pipeline Composition\nDefine reusable pipeline components:\n\n```python\nfrom pydantic_variants.transformers import *\n\n# Reusable pipeline components\napi_input_base = [\n FilterFields(exclude=['id', 'created_at', 'updated_at']),\n MakeOptional(exclude=['email']) # email still required\n]\n\npublic_output_base = [\n FilterFields(exclude=['password_hash', 'internal_notes', 'deleted_at'])\n]\n\n# Compose into specific pipelines\nuser_input_pipeline = basic_variant_pipeline('Input', *api_input_base)\nuser_output_pipeline = basic_variant_pipeline('Output', *public_output_base)\n\nadmin_output_pipeline = basic_variant_pipeline('AdminView',\n FilterFields(exclude=['password_hash']), # Admin sees more fields\n SetFields({\n 'admin_notes': FieldInfo(annotation=str, default=\"\")\n })\n)\n```\n\n### Available Transformers\n\n```python\n# Filter out fields\nfilter_sensitive = FilterFields(exclude=['password', 'internal_id'])\nkeep_public = FilterFields(include_only=['name', 'email'])\n\n# Make fields optional\nall_optional = MakeOptional(all=True)\nexcept_required = MakeOptional(exclude=['id'])\nspecific_optional = MakeOptional(include_only=['description'])\n\n# Rename fields\nrename_legacy = RenameFields(mapping={'user_id': 'id', 'email_addr': 'email'})\n\n# Modify field properties\nupdate_validation = ModifyFields({\n 'email': {'validation_alias': 'email_address'},\n 'name': {'default': 'Anonymous'}\n})\n\n# Switch nested model variants\nuse_input_variants = SwitchVariant('Input')\n```\n\n## \ud83c\udf1f Advanced Features\n\n### Nested Model Variants\nAutomatically transform nested models using variants attached to the root model under the `_variants` dict attribute:\n\n```python\naddress_input = basic_variant_pipeline('Input',\n FilterFields(exclude=['id'])\n)\n\n@variants(address_input)\nclass Address(BaseModel):\n id: int\n street: str\n city: str\n country: str\n\nuser_input = basic_variant_pipeline('Input',\n FilterFields(exclude=['id']),\n SwitchVariant('Input') # Uses Address.Input for address field\n)\n\n@variants(user_input)\nclass User(BaseModel):\n id: int\n name: str\n address: Address # Becomes Address.Input in User.Input variant\n```\n\n### Custom Advanced Pipelines\nBuild complex pipelines with the full pipeline API:\n\n```python\nfrom pydantic_variants import VariantPipe, VariantContext\nfrom pydantic_variants.transformers import *\n\n# Advanced pipeline with custom logic\nadmin_pipeline = VariantPipe(\n VariantContext('Admin'),\n FilterFields(exclude=['password_hash']),\n SetFields({\n 'admin_notes': FieldInfo(annotation=str, default=\"\"),\n 'permissions': FieldInfo(annotation=list[str], default_factory=list)\n }),\n SwitchVariant('Admin'), # Use Admin variants of nested models\n BuildVariant(name_suffix=\"Admin\"),\n ConnectVariant()\n)\n\n@variants(admin_pipeline)\nclass User(BaseModel):\n # Your model definition\n ...\n```\n\n### Dynamic Field Logic\nCreate complex field transformation logic:\n\n```python\ndef smart_optional_logic(name: str, field: FieldInfo) -> tuple[bool, Any]:\n \"\"\"Custom logic for making fields optional\"\"\"\n if name.endswith('_id'):\n return True, None\n elif name == 'created_at':\n return True, DefaultFactoryTag(datetime.now)\n elif name.startswith('internal_'):\n return True, \"\"\n return False, None\n\nsmart_optional = basic_variant_pipeline('SmartOptional',\n MakeOptional(optional_func=smart_optional_logic)\n)\n```\n\n## \ud83d\udd27 FastAPI Integration\n\nPerfect integration with FastAPI's automatic OpenAPI schema generation:\n\n```python\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n# Define pipelines clearly\ncreate_pipeline = basic_variant_pipeline('Create',\n FilterFields(exclude=['id', 'created_at'])\n)\n\nresponse_pipeline = basic_variant_pipeline('Response',\n FilterFields(exclude=['password_hash'])\n)\n\n@variants(create_pipeline, response_pipeline)\nclass User(BaseModel):\n id: int\n username: str\n email: str\n password_hash: str\n created_at: datetime\n\n@app.post(\"/users/\", response_model=User.Response)\nasync def create_user(user: User.Create):\n # FastAPI automatically generates:\n # - User.Create schema for request body validation\n # - User.Response schema for response documentation\n return User.Response(**user.model_dump(), id=123, created_at=datetime.now())\n```\n\n## \u26a0\ufe0f Schema Rebuilding\n\nIf your schema has forward references, use the variants decorator (as a simple function) **after** the schema is completely defined and rebuilt:\n\n```python\n# Define all models first\nclass User(BaseModel):\n name: str\n posts: list['Post']\n\nclass Post(BaseModel):\n title: str\n author: User\n\n# Rebuild models to resolve forward references\nUser.model_rebuild()\n\n# Apply variants after all models are well defined\nuser_pipeline = basic_variant_pipeline('Input', FilterFields(exclude=['id']))\npost_pipeline = basic_variant_pipeline('Input', FilterFields(exclude=['id']))\n\nUser = variants(user_pipeline)(User)\nPost = variants(post_pipeline)(Post)\n\n```\n\n## \ud83d\udcd6 Complete API Reference\n\n### Decorators\n- `@variants(*pipelines)` - Main decorator for creating variants\n- `basic_variant_pipeline(name, *transformers)` - Helper for common transformation patterns\n\n### Core Classes\n- `VariantPipe(*operations)` - Immutable pipeline for chaining transformations\n- `VariantContext(name)` - Initializes transformation context\n- `DecomposedModel` - Internal representation for field manipulation\n\n### Field Transformers (work with DecomposedModel)\n- `FilterFields(exclude/include_only/filter_func)` - Remove/keep specific fields\n- `MakeOptional(all/exclude/include_only/optional_func)` - Make fields optional\n- `RenameFields(mapping/rename_func)` - Rename fields\n- `ModifyFields(field_modifications)` - Modify field properties \n- `SetFields(fields)` - Add or replace fields\n- `SwitchVariant(variant_name)` - Use variants of nested models\n\n### Model Transformers (work with built models)\n- `BuildVariant(base, name_suffix, doc)` - Build final Pydantic model\n- `ConnectVariant(attach_directly, attach_root)` - Attach variant to original model\n- `SetAttribute(variant_attrs, root_attrs)` - Set class attributes\n\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! The architecture is designed to be easily enhanced with your own transformers.\n\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the Apache V2.0 - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udd17 Related Projects\n\n- [Pydantic](https://pydantic.dev/) - Data validation using Python type hints\n- [FastAPI](https://fastapi.tiangolo.com/) - Modern web framework for APIs \n- [Beanie](https://beanie-odm.dev/) - Async ODM for MongoDB\n\n## \ud83c\udf89 Acknowledgments\n\nBuilt during a FastAPI + Beanie project, inspired by the need for a single source of truth in API schema design.\n\n---\n\n\u2b50 **Star this repo if Pydantic Variants helps you build better APIs!**",
"bugtrack_url": null,
"license": "Apache-2.0",
"summary": "Create Pydantic model variants with transformation pipelines for different use cases (Input/Output/Update)",
"version": "0.2.0",
"project_urls": null,
"split_keywords": [
"api",
" crud",
" dataclass",
" decorator",
" fastapi",
" forms",
" json",
" model",
" models",
" orm",
" pydantic",
" rest",
" schema",
" serialization",
" typing",
" validation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "953b0584661ed908001df6e91ee21bed897e3f88bfb85bb8234c19ec719726da",
"md5": "a5a21af27add4aacc070083c520f8c43",
"sha256": "bdce2c17e4351c993ed1c1a1dc43b6b37534c79e5de8146dccbd7b94e9d1edac"
},
"downloads": -1,
"filename": "pydantic_variants-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a5a21af27add4aacc070083c520f8c43",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 24565,
"upload_time": "2025-08-04T11:32:28",
"upload_time_iso_8601": "2025-08-04T11:32:28.726193Z",
"url": "https://files.pythonhosted.org/packages/95/3b/0584661ed908001df6e91ee21bed897e3f88bfb85bb8234c19ec719726da/pydantic_variants-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3487decf36c7ad1ccc283bb7f9af59980df3641a991210946a219390b999c47e",
"md5": "1a470ce037bc503824ef19b6947bfff7",
"sha256": "b6625bf77a02ca183598c6287e6bd4cba599a06145a92bd53f1a185dd220470a"
},
"downloads": -1,
"filename": "pydantic_variants-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "1a470ce037bc503824ef19b6947bfff7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 75880,
"upload_time": "2025-08-04T11:32:30",
"upload_time_iso_8601": "2025-08-04T11:32:30.865370Z",
"url": "https://files.pythonhosted.org/packages/34/87/decf36c7ad1ccc283bb7f9af59980df3641a991210946a219390b999c47e/pydantic_variants-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-04 11:32:30",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "pydantic-variants"
}