SimpleSpec
Convert Python typing annotations, Pydantic v2 models, and dataclasses into a compact, human‑readable schema specification.
Features
- 🔍 Clear, readable type strings - Modern Python syntax (e.g.,
list[T],dict[K, V],Unionvia|) - 📝 Preserve constraints and descriptions - Field descriptions and validation constraints
- 🏗️ First-class Pydantic & dataclass support - Referenced types with proper handling
- 🔄 Deterministic naming - Collision handling for types with same names
- 🛡️ Depth control - Configurable limits for cyclic/recursive structures
- ⚡ Fast and lightweight - Minimal dependencies
Quick Start
Installation
# Using uv (recommended)
uv add simplespec
# Using pip
pip install simplespec
Basic Usage
from pydantic import BaseModel, Field
from simplespec import generate_simple_spec
class Address(BaseModel):
street: str
city: str
class User(BaseModel):
name: str
age: int = Field(ge=18, description="User's age in years")
address: Address
spec = generate_simple_spec(User)
print(spec)
Output:
Referenced specs:
Address
street: str
city: str
Spec:
User
name: str
age: int, User's age in years [ge=18]
address: Address
API Reference
generate_simple_spec
from simplespec import generate_simple_spec, DepthLimitExceededError, SimpleSpecError
spec = generate_simple_spec(root_type_obj, max_depth: int | None = None)
Parameters:
root_type_obj: Any supported type (Pydantic BaseModel class, dataclass type, or typing annotations likelist[str],dict[str, int],Union, etc.)max_depth: Optional recursion limit for referenced types (default: 4)
Returns:
Spec: A dataclass containing:self:Ref— The root type definitionrefs:list[Ref]— Referenced Pydantic models/dataclasses, sorted by depth then name
Raises:
DepthLimitExceededError— When walking exceeds max_depthSimpleSpecError— For other analysis/build failures
Output Data Structures
@dataclass
class Prop:
type: str
description: str | None = None
@dataclass
class Ref:
type: str
description: str | None = None
properties: dict[str, Prop] = field(default_factory=dict)
@dataclass
class Spec:
self: Ref
refs: list[Ref] = field(default_factory=list)
Type Resolution Examples
SimpleSpec normalizes type names to modern Python syntax:
| Input Type | Output |
|---|---|
dict[str, int] |
"dict[str, int]" |
list[User | None] |
"list[User | None]" |
Optional[str] |
"str | None" |
Union[str, int, None] |
"int | str | None" |
tuple[str, int] |
"tuple[str, int]" |
set[int] |
"set[int]" |
Literal['a', 'b'] |
"Literal['a', 'b']" |
Advanced Examples
Recursive Types
class TreeNode(BaseModel):
value: str
children: list["TreeNode"] = []
parent: Optional["TreeNode"] = None
TreeNode.model_rebuild() # Required for forward references
spec = generate_simple_spec(TreeNode)
print(spec.self.properties["children"].type) # "list[TreeNode]"
Dataclass Support
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float = 0.0
class Shape(BaseModel):
center: Point
points: list[Point]
spec = generate_simple_spec(Shape)
# Point appears in spec.refs as a referenced type
Complex Constraints
class Product(BaseModel):
name: str = Field(min_length=1, max_length=100, description="Product name")
price: float = Field(gt=0, le=10000, description="Price in USD")
quantity: int = Field(ge=0, multiple_of=1)
spec = generate_simple_spec(Product)
# Constraints appear as: "str, Product name [min_length=1] [max_length=100]"
Development
Setup
# Clone the repository
git clone https://github.com/denizkenan/simplespec.git
cd simplespec
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync --all-extras
# Install pre-commit hooks
uv run pre-commit install
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=simplespec --cov-report=html
# Run specific test
uv run pytest tests/test_simplespec.py::test_simple_for_primitive_type -v
Code Quality
# Format code
uv run ruff format
# Lint code
uv run ruff check
# Type check
uv run mypy simplespec
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
uv run pytest) - Run code quality checks (
uv run ruff check && uv run mypy simplespec) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Compatibility
- Python: 3.11+
- Pydantic: v2.0+
- Dependencies:
pydantic>=2.0.0,annotated-types>=0.6.0
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments
- Built with Pydantic for model handling
- Uses annotated-types for constraint extraction
- Development tooling by uv and Ruff
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
simplespec-0.1.1.tar.gz
(78.1 kB
view details)
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 simplespec-0.1.1.tar.gz.
File metadata
- Download URL: simplespec-0.1.1.tar.gz
- Upload date:
- Size: 78.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
748d21000743b6215e745bea8b2e6caf9e4b0138db3eb9c56fab448cfb944a86
|
|
| MD5 |
13dae1dce8f4ec81282b4ae879b8e62f
|
|
| BLAKE2b-256 |
e1fbfa313069e58160ecca134054fe7971bcfcef1aa13ae916f8d068d646412c
|
File details
Details for the file simplespec-0.1.1-py3-none-any.whl.
File metadata
- Download URL: simplespec-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6545622a94c87f74f997fc4a9d1a4e7df7e6b57e27a65686bec4d251783a93c
|
|
| MD5 |
0ef3efd06b6ec0316e5148ca84230c68
|
|
| BLAKE2b-256 |
d6c990d3a5f09aa76a3b462e162ef1f93f18d737bbe641037f6e40ccaad88cfe
|