Convention-first typed prompt models with canonical Markdown and XML
Project description
pydantic-promptmodel
Write prompts as typed Python. Render them as clean Markdown or XML.
pydantic-promptmodel turns a natural class hierarchy into a ready-to-send LLM
prompt. Define the structure once, validate values with Pydantic, and switch output
formats with one method call—useful for comparing models, providers, and prompting
strategies without maintaining two templates.
Quick start
uv add pydantic-promptmodel
Or:
pip install pydantic-promptmodel
Define the meaning of your prompt, without specifying heading levels, list markers, or XML tags:
from pydantic_promptmodel import PromptModel, prompt
@prompt
class CodeReviewPrompt(PromptModel):
_title: str
_body: str
focus_areas: list[str]
output: str
review = CodeReviewPrompt(
_title="Code Review",
_body="Review the supplied pull request as a senior engineer.",
focus_areas=[
"Correctness and edge cases",
"Security and data handling",
"Clear, maintainable design",
],
output="Return prioritized findings with a concrete fix for each one.",
)
markdown_prompt = review.to_markdown()
xml_prompt = review.to_xml()
The Markdown is immediately useful:
# Code Review
Review the supplied pull request as a senior engineer.
## Focus Areas
- Correctness and edge cases
- Security and data handling
- Clear, maintainable design
## Output
Return prioritized findings with a concrete fix for each one.
The same instance also produces equivalent XML:
<code-review-prompt title="Code Review">
<content>Review the supplied pull request as a senior engineer.</content>
<focus-areas>
<focus-area>Correctness and edge cases</focus-area>
<focus-area>Security and data handling</focus-area>
<focus-area>Clear, maintainable design</focus-area>
</focus-areas>
<output>Return prioritized findings with a concrete fix for each one.</output>
</code-review-prompt>
Why use it?
- One prompt model, multiple formats. Change
.to_markdown()to.to_xml()without rewriting or synchronizing templates. - Natural structure. Nested models become nested sections,
list[str]becomes a readable list, andsnake_casenames become human-friendly labels. - Pydantic validation. Prompt inputs are typed and validated before they reach the model provider.
- Deterministic output. The same prompt instance always renders the same text, making snapshots, reviews, and A/B tests straightforward.
- Useful defaults first. Most prompts need no formatting metadata. Local overrides are available when a label, XML name, ordering rule, literal block, or runtime slot needs special treatment.
_title names the current prompt or nested section, while _body is prose owned
directly by it. Ordinary fields named title and body remain available for your
domain.
Design philosophy
The model is the source of truth. The library aims to produce one beautiful, correct, and useful representation for each format—not reproduce every possible hand-written Markdown or XML layout.
Version 0.1.0 is an alpha release for Python 3.11+ and Pydantic 2.
Learn more
Development
make format
make lint
make test
make check
make build
Release maintainers should follow the trusted-publishing guide.
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_promptmodel-0.1.0.tar.gz.
File metadata
- Download URL: pydantic_promptmodel-0.1.0.tar.gz
- Upload date:
- Size: 11.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
977911042c2236ab61224d76a0180c39685e7915dce3765d0eceb9e9b13aebe7
|
|
| MD5 |
599e9f8388c2ac682cc04b11c5cc0ece
|
|
| BLAKE2b-256 |
98c76111d96ed4266c5e0a8f74440f5c5de2a08382f86108450a789d68f9a7fe
|
Provenance
The following attestation bundles were made for pydantic_promptmodel-0.1.0.tar.gz:
Publisher:
release.yml on Thillel/pydantic-promptmodel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_promptmodel-0.1.0.tar.gz -
Subject digest:
977911042c2236ab61224d76a0180c39685e7915dce3765d0eceb9e9b13aebe7 - Sigstore transparency entry: 2255963668
- Sigstore integration time:
-
Permalink:
Thillel/pydantic-promptmodel@efdcb98da9d067f0e4e52b7ae3b4194ae0c90f87 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Thillel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@efdcb98da9d067f0e4e52b7ae3b4194ae0c90f87 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantic_promptmodel-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydantic_promptmodel-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
181c919d672c110976f6956ecc3525ce27d9a1848e089e77ccae063e9101c055
|
|
| MD5 |
af238b5616c138048c05551bf974e8c9
|
|
| BLAKE2b-256 |
4d256b546745676787bd04c21f260a2060f1fc665a2b66a29c77843432ecb315
|
Provenance
The following attestation bundles were made for pydantic_promptmodel-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Thillel/pydantic-promptmodel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_promptmodel-0.1.0-py3-none-any.whl -
Subject digest:
181c919d672c110976f6956ecc3525ce27d9a1848e089e77ccae063e9101c055 - Sigstore transparency entry: 2255963672
- Sigstore integration time:
-
Permalink:
Thillel/pydantic-promptmodel@efdcb98da9d067f0e4e52b7ae3b4194ae0c90f87 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Thillel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@efdcb98da9d067f0e4e52b7ae3b4194ae0c90f87 -
Trigger Event:
push
-
Statement type: