Skip to main content

Post-process rendered Jinja2 templates and compile them into OpenAI messages

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

prompt-template-to-messages

Turn richly annotated Jinja2 prompts into OpenAI-compatible message payloads without giving up the ergonomics of plain text version control.

Why this project exists

Most prompt repositories still manage prompts as plain text. Diffing, reviewing, and versioning become easy, but multimodal prompts are hard to author and ship. prompt-template-to-messages embraces templates: you keep a single text file that mixes roles, function calls, and rich metadata via helper functions, which render into HTML-like tags prefixed with pt2m-. Under the hood, we combine Jinja2 for rendering dynamic content and BeautifulSoup-powered parsing to compile the result into the structured messages array required by OpenAI-compatible APIs. Welcome to the template era.

Key features

  • Author prompts once and render them as OpenAI messages.
  • Keep prompts in Git-friendly text files while supporting multimodal content.
  • Compose translators to customize how tags produce message fragments.
  • Strict rendering: Jinja2 runs with StrictUndefined so missing variables fail fast.

Install

pip install prompt-template-to-messages

Quick start

  1. Create a template file welcome.pt2m.jinja:

    {% set user_name = user_name or "friend" %}
    {% call _pt2m_message('system') %}
    You are a concise onboarding assistant.
    {% endcall %}
    {% call _pt2m_message('user') %}
    Hello, {{ user_name }}!
    {{ _pt2m_resolve_image(intro_image_url, alt='Welcome illustration') }}
    {% endcall %}
    
  2. Render it with Python:

    from prompt_template_to_messages import compile_prompt_to_messages
    
    template_text = open("welcome.pt2m.jinja", "r", encoding="utf-8").read()
    messages = compile_prompt_to_messages(
        template_text,
        scope={"user_name": "Ada", "intro_image_url": "https://example.com/welcome.png"},
    )
    
  3. Send messages to your favorite chat completion client.

Examples

Image-only broadcast

Use a scope variable to supply an image URL and render a message that contains only image_url content:

template

{% call _pt2m_message('user') -%}
{{ _pt2m_resolve_image(hero_image, detail='high') }}
{%- endcall %}

scope

scope = {"hero_image": "https://cdn.example/hero.png"}
messages = compile_prompt_to_messages(template, scope=scope)
# -> [{'role': 'user', 'content': [{'type': 'image_url', 'image_url': {'url': 'https://cdn.example/hero.png', 'detail': 'high'}}]}]

Custom translator with plain tags

Plain HTML-like tags that appear in the rendered template can be whitelisted by registering translators. The example below mixes _pt2m_ helpers with a scope function that emits <multi-modal> tags:

from prompt_template_to_messages import compile_prompt_to_messages

template = """{% call _pt2m_message('assistant') -%}Gallery incoming: {{ render_multi_modal(featured) }}{%- endcall %}"""

def render_multi_modal(asset):
    return f'<multi-modal ref="{asset["ref"]}" caption="{asset["caption"]}" detail="{asset["detail"]}" />'

def multi_modal_translator(tag, context):
    return {
        "type": "multi-modal",
        "multi_modal": {
            "ref": tag.attrs.get("ref"),
            "caption": tag.attrs.get("caption"),
            "detail": tag.attrs.get("detail"),
        },
    }

scope = {"featured": {"ref": "hero.png", "caption": "Hero", "detail": "medium"}, "render_multi_modal": render_multi_modal}
messages = compile_prompt_to_messages(template, scope=scope, translators=[("multi-modal", multi_modal_translator)])

Any translator added through translators=[...] is treated as part of the whitelist, so its tag will be parsed even without the pt2m- prefix.

CLI usage

This package ships a CLI named ptm.

ptm render TEMPLATE_PATH --scope scope.json --output messages.json

--scope accepts a JSON file, and --output writes the compiled messages. Run ptm --help for all options.

Formatting and release workflow

The Makefile encodes the recommended workflow:

  • make format runs ruff format on src/ and tests/.
  • make git-push formats your code before pushing.
  • make release formats, tests, lints, type-checks, builds, and then tags the release.

Contributing

  1. Clone the repo and run make install-dev.
  2. Use make format, make lint, and make test while iterating.
  3. Before pushing, run make git-push to enforce formatting.
  4. For publishing, follow make release and make upload.

License

MIT Licensed. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

prompt_template_to_messages-0.1.0.tar.gz (9.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

prompt_template_to_messages-0.1.0-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file prompt_template_to_messages-0.1.0.tar.gz.

File metadata

File hashes

Hashes for prompt_template_to_messages-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3ace4e83de67363cf731aee1e4dcc39b4087ed2eb25fd1f43d34e03dda64c39d
MD5 83308a9ea69712252f6591d27c1b04e3
BLAKE2b-256 2c0c550f9338040605fcd0b05af3bcb7551487470cf14ff24b7189fb12e93d8a

See more details on using hashes here.

File details

Details for the file prompt_template_to_messages-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for prompt_template_to_messages-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6078f54872a6f93c0ebb96e0c1d73b1d5ce1be53aa506bf35a99580911ab3496
MD5 a25b2e819e389189eae13f773d48ce86
BLAKE2b-256 68d74096df6af9e88971ae4fd6beff9afcaecf173b454ffa323874b4c8768c80

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page