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 = "Code Review"
_body: str = "Review the supplied pull request as a senior engineer."
focus_areas: tuple[str, ...] = (
"Correctness and edge cases",
"Security and data handling",
"Clear, maintainable design",
)
output: str = "Return prioritized findings with a concrete fix for each one."
review = CodeReviewPrompt()
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, short scalar fields stay compact, 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.
Document-level controls
Renderer options apply across the complete model graph, including unmodified
Pydantic BaseModel instances:
from pydantic_promptmodel import render_markdown, render_xml
markdown_fragment = render_markdown(
existing_model,
naming="verbatim",
title="system_instructions",
start_level=3,
heading_overflow="bold",
scalar_style="auto",
empty_sequences="marker",
)
xml_prompt = render_xml(
existing_model,
naming="verbatim",
root_name="system_instructions",
fallback_item_name="criterion",
)
naming="verbatim" preserves field identifiers in Markdown labels and XML field
wrappers. fallback_item_name is used only when conservative singularization would
otherwise emit <item>. Local Label, XmlName, and ItemName metadata still
wins over document-level inference.
Markdown automatically renders single-line scalar values of up to 120 characters
as compact **Label:** value lines. Longer and multiline values retain headings.
scalar_style="block" restores heading-based scalars for a document;
Inline() and Block() provide local overrides. Empty sequences render as
- (none) by default or can be dropped with empty_sequences="omit".
PromptModel.to_markdown() and .to_xml() accept the same format-specific options.
Defaults retain the canonical output shown in the quick start.
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.2.0 supports 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.
Metadata
Release files for pydantic-promptmodel 0.2.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 | |
|---|---|---|---|---|
| pydantic_promptmodel-0.2.0.tar.gz | 14.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydantic_promptmodel-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.4 kB
Release files / pydantic_promptmodel-0.2.0.tar.gz
| Download URL | pydantic_promptmodel-0.2.0.tar.gz |
|---|---|
| Size | 14.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
83d22bef6afb39336a2db7c8a0cc2348425df0e111c02ba2d0f003e2387c8389
|
|
BLAKE2b-256 checksum How to use checksums |
bc45c5067d5d9c48b3f0bd0125ccac701672148aba8b813e2812b445d1a6e2ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.
Transparency logRelease files / pydantic_promptmodel-0.2.0-py3-none-any.whl
| Download URL | pydantic_promptmodel-0.2.0-py3-none-any.whl |
|---|---|
| Size | 18.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e9246542815013964741c0bf32e13361674022d3e03042abe8669935b8929dc9
|
|
BLAKE2b-256 checksum How to use checksums |
5f9b7c7f0a608fbb6802c0f937d29d7fec722f3693fa783b3452f4fbec905e06
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.
Transparency logSecurity for pydantic-promptmodel 0.2.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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pydantic_promptmodel-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 30, 2026.
Transparency logA 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.