Skip to main content

prompt-composer

A lightweight, section-based prompt composition library for LLM applications.

Features

  • Section-Based Composition: Build prompts from named sections that can be added, updated, or removed independently.
  • Template Variables: Use {variable} or {{variable}} placeholders within sections, filled at render time with global or section-scoped values.
  • Multi-Format Parsers: Load and parse prompt templates in XML (<section>...</section>), YAML, JSON, Markdown (## Section Heading), TOML, TOON, HCL, and BAML formats.
  • Forced Output Formatting: Output the final prompt rendered inside XML tags or as Markdown headers dynamically.
  • StrEnum Validation: Type-safe configuration via TemplateFormat, VariableStyle, and OutputFormat enums.
  • Minimal Dependencies: Only pyyaml, jinja2, and pydantic. Advanced file-type detection is an optional integration.
  • Method Chaining: Fluent API for concise prompt construction.
  • Optimized Performance: C-based string jumps and variable resolution caching.

Installation

pip install prompt-composer

prompt-composer never guesses the template format. Pass it explicitly via template_format=, or use the dedicated per-format constructor.

Quick Start

From Template File

The format must be provided explicitly; nothing is inferred from the file extension.

from prompt_composer import PromptComposer, TemplateFormat

prompt = PromptComposer.from_file("planner_prompt.yaml", prompts_dir, template_format=TemplateFormat.YAML)
prompt.set_variable("available_tools", tools_json)
prompt.set_variable("binding_instruction", "Use JMESPath syntax")

if not enable_fallback:
    prompt.set_variable("fallback_instruction", "")

text = prompt.render()

From a String (per-format constructors)

Each supported format has a dedicated constructor, so the right parser is always used:

from prompt_composer import PromptComposer

PromptComposer.from_json('{"sections": [{"name": "role", "content": "You are a planner."}]}')
PromptComposer.from_yaml("sections:\n  - name: role\n    content: You are a planner.")
PromptComposer.from_xml("<role>You are a planner.</role>")
PromptComposer.from_markdown("## role\nYou are a planner.")

Also available: from_toml, from_toon, from_hcl, from_baml. Alternatively pass template_format= to PromptComposer.from_text(...) or PromptComposer.from_file(...).

Programmatic Composition

from prompt_composer import PromptComposer, VariableStyle

prompt = (
    PromptComposer(variable_style=VariableStyle.BRACES)
    .set_section("role", "You are an expert AI planner.")
    .set_section("tools", "{available_tools}")
    .set_section("rules", "Follow these rules:\n1. Be precise\n2. Be concise")
    .set_variable("available_tools", '[{"name": "search"}]')
)

text = prompt.render()

Section-Scoped Variables

from prompt_composer import PromptComposer

prompt = PromptComposer()
prompt.set_section("header", "Model: {model}")
prompt.set_section("footer", "Model: {model}")
prompt.set_variable("model", "gemini-2.5-flash")
prompt.set_section_variable("footer", "model", "gpt-4o")

text = prompt.render()
# header uses "gemini-2.5-flash", footer uses "gpt-4o"

Formatting Filters

You can use built-in filters inside placeholders to format output values:

  • {var:upper}: Converts to uppercase.
  • {var:lower}: Converts to lowercase.
  • {var:json}: Dumps data structures to a JSON string.
  • {var:indent2}: Indents multi-line content by 2 spaces.
prompt.set_section("config", "Config: {config_dict:json}")
prompt.set_variable("config_dict", {"debug": True})

Forced Output Formatting

No matter how the template was loaded, you can force the rendered output format when calling render():

from prompt_composer import OutputFormat

# Wraps sections in XML tags
xml_prompt = prompt.render(output_format=OutputFormat.XML)

# Wraps sections as Level 2 Markdown headings
markdown_prompt = prompt.render(output_format=OutputFormat.MARKDOWN)

Introspection

prompt = PromptComposer.from_xml("<role>Expert</role><tools>{tools}</tools>")
prompt.list_sections()  # ["role", "tools"]
prompt.get_all_variables()  # ["tools"]
prompt.get_unresolved_variables()  # ["tools"]
prompt.set_variable("tools", "...")
prompt.get_unresolved_variables()  # []

Metadata

Release files for prompt-composer 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prompt-composer 0.2.0
File Size Uploaded
prompt_composer-0.2.0.tar.gz 65.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for prompt-composer 0.2.0
File Interpreter ABI Platform
prompt_composer-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 105.7 kB

Release files / prompt_composer-0.2.0.tar.gz

Download URL prompt_composer-0.2.0.tar.gz
Size 65.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d806699cfd482c2a4f1ab8a3ce1da20a38b77b3f1b4f203cee7fabef2bc57d0b
BLAKE2b-256 checksum
How to use checksums
d19dfa42c3f5e6e320387fbd25406d4eec892eb7f63fa6403a19abc368f96401
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 Oct 8, 2026.

Transparency log

Release files / prompt_composer-0.2.0-py3-none-any.whl

Download URL prompt_composer-0.2.0-py3-none-any.whl
Size 40.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d17c2f6cacb7cecded9dc91dd09fdb83c4ae58f718c82bf32bc3ea1a11207095
BLAKE2b-256 checksum
How to use checksums
98b418a2db884744687379472e22a75d8d60c10ddd45857f600df49b1dcbf5f5
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 Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page