pydantic-wizard
Interactive wizard-style CLI for configuring Pydantic v2 models, with YAML serialization.
Point it at any BaseModel subclass and it will walk you through every field — with type-aware prompts, constraint validation, and nested model support — then save the result as a clean YAML file.
Features
- Zero boilerplate — works with any Pydantic v2
BaseModel, no registration needed - Type-aware prompts — booleans get yes/no, enums get dropdowns, nested models recurse automatically
- Constraint enforcement — respects
ge,le,gt,ltand other Pydantic field validators - 15+ built-in type handlers — scalars,
Decimal,Enum,Literal,datetime,Optional,list,set,dict,Union, nested models - YAML round-trip — serialize with metadata, load back, edit, and re-save
- Interactive validation — on error, re-prompts only the failing fields
- Extensible — register custom
TypeHandlerimplementations for domain-specific types - Rich terminal output — field panels, summary tables, and colored messages via Rich
- Web UI — optional Streamlit-based browser interface for visual configuration
Installation
pip install pydantic-wizard
Or with uv:
uv add pydantic-wizard
To include the optional web UI:
pip install pydantic-wizard[web]
Quick Start
Define a model
# myapp/config.py
from decimal import Decimal
from pydantic import BaseModel, Field
class DatabaseConfig(BaseModel):
host: str = Field(description="Database hostname")
port: int = Field(default=5432, ge=1, le=65535)
name: str = Field(description="Database name")
pool_size: int = Field(default=10, ge=1)
timeout: Decimal = Field(default=Decimal("30.0"), ge=0)
ssl_enabled: bool = Field(default=True)
Run the wizard from the CLI
pydantic-wizard new myapp.config.DatabaseConfig -o db.yaml
The wizard will prompt you for each field with type-appropriate inputs, validate the result, and save to db.yaml.
Or use it programmatically
from pydantic_wizard import prompt_model, serialize_to_yaml, validate_and_fix
from myapp.config import DatabaseConfig
from pathlib import Path
# Interactive prompt for all fields
data = prompt_model(DatabaseConfig)
# Validate (re-prompts on errors)
instance = validate_and_fix(DatabaseConfig, data)
# Save to YAML
serialize_to_yaml(data, DatabaseConfig, Path("db.yaml"), model_name="database")
CLI Commands
new — Create a configuration
pydantic-wizard new <MODEL_FQN> [--output, -o PATH]
Walks through every field interactively, validates, and saves to YAML.
edit — Edit an existing configuration
pydantic-wizard edit <CONFIG_FILE> [--output, -o PATH]
Loads an existing YAML file and re-runs the wizard with current values as defaults.
validate — Validate a configuration
pydantic-wizard validate <CONFIG_FILE> [--model, -m FQN]
Validates a YAML file against its Pydantic model. The model class is resolved from YAML metadata or the --model flag.
show-schema — Show model schema
pydantic-wizard show-schema <MODEL_FQN>
Displays a formatted table of all fields, types, defaults, and descriptions.
web — Launch the web UI
pydantic-wizard web
Opens a Streamlit-based browser interface with pages for creating, editing, validating, and inspecting configurations. Requires the [web] extra.
Supported Types
| Category | Types |
|---|---|
| Scalars | str, int, float, bool, Decimal |
| Enums & Literals | Enum subclasses, Literal["a", "b", "c"] |
| Date & Time | datetime, time, timedelta |
| Optional | T | None, Optional[T] |
| Collections | list[T], set[T], dict[K, V] |
| Unions | A | B | C (type selection prompt) |
| Nested Models | Any BaseModel subclass (recursive prompting) |
Programmatic API
Introspection
from pydantic_wizard import introspect_model, FieldSpec
specs: list[FieldSpec] = introspect_model(DatabaseConfig)
for spec in specs:
print(f"{spec.name}: {spec.inner_type}, required={spec.is_required}")
Custom Type Handlers
Register custom handlers for domain-specific types:
from pydantic_wizard import TypeHandlerRegistry, prompt_model
from pydantic_wizard.type_handlers import TypeHandler
class MoneyHandler:
def can_handle(self, spec):
return spec.inner_type is Money
def prompt(self, spec, default=None):
raw = questionary.text(f" {spec.name} (e.g. 100.00 USD):").ask()
return Money.parse(raw)
def serialize(self, value):
return str(value)
def deserialize(self, raw, spec):
return Money.parse(raw)
# Use the custom registry
registry = TypeHandlerRegistry()
registry.register(MoneyHandler()) # inserted at front, takes priority
data = prompt_model(MyConfig, registry=registry)
YAML Output Format
Generated YAML files include metadata for round-trip support:
_metadata:
model_type: DatabaseConfig
configuration_class: myapp.config.DatabaseConfig
version: 0.1.0
configuration:
host: localhost
port: 5432
name: mydb
pool_size: 10
timeout: "30.0"
ssl_enabled: true
- Decimals are serialized as quoted strings to preserve precision
- Enums are serialized as their
.value - Sets are serialized as sorted lists
- Datetimes use ISO 8601 format
License
MIT
Metadata
Release files for pydantic-wizard 0.3.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 | Provenance | Actions |
|---|---|---|---|---|
| pydantic_wizard-0.3.0.tar.gz | 107.7 kB | Without provenance | Details for pydantic_wizard-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pydantic_wizard-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for pydantic_wizard-0.3.0-py3-none-any.whl |
Total release size: 138.5 kB
Release files / pydantic_wizard-0.3.0.tar.gz
| Download URL | pydantic_wizard-0.3.0.tar.gz |
|---|---|
| Size | 107.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f3f3f888de49048ad172a14de46da52cef393734c83109ec1d4ba962a67bb8b0
|
|
BLAKE2b-256 checksum How to use checksums |
911d059eaeb4c6336797c9029a53f725a9adeaa18f7574b4bacccaab06e7efa1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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 / pydantic_wizard-0.3.0-py3-none-any.whl
| Download URL | pydantic_wizard-0.3.0-py3-none-any.whl |
|---|---|
| Size | 30.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
15fc6fcb54ba1eaab85b6154a37ee6d15d2bb9577908c56fefc66472ac4dc1fe
|
|
BLAKE2b-256 checksum How to use checksums |
a3b8a2b14506b882f6f637367eba6cd02ad081d12a484a79038d81cfa211ee16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","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}
|
Security for pydantic-wizard 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.