Skip to main content

Type-safe Jinja prompt trees with runtime validation and generated Python stubs.

Project description

promptree

promptree turns a directory of Jinja templates into a type-safe Python prompt tree, with runtime validation and generated .pyi stubs for IDE autocomplete.

It gives you:

  • Dot-notation access to prompt folders and files
  • Runtime validation through Jinja StrictUndefined
  • Generated .pyi stubs for IDE autocomplete
  • Full Jinja support, including include, extends, and macros
  • Raw strings as the only integration format, so there is no adapter layer

Install

pip install promptree

Optional extras:

pip install promptree[watch]
pip install promptree[pydantic-ai]

Quick Start

Directory layout:

prompts/
├── system.md
└── user/
    ├── greeting.md
    └── farewell.txt

Example templates:

{# prompts/system.md #}
System prompt for {{ name }}.
{# prompts/user/greeting.md #}
Hello {{ name }}!
{# prompts/user/farewell.txt #}
Goodbye {{ name }}.

Use them from Python:

from promptree import Promptree

prompts = Promptree("./prompts")

print(prompts.system(name="Claude"))
print(prompts.user.greeting(name="Tim"))
print(prompts.user.farewell(name="Tim"))

This direct Promptree(...) usage is runtime-dynamic. Editors can execute the code correctly, but they cannot infer from the filesystem whether prompts.system is a directory node or a template file. For precise VS Code autocomplete and call signatures, generate the prompt package and import its tree object:

promptree generate ./prompts
from prompts import tree

print(tree.system(name="Claude"))
print(tree.user.greeting(name="Tim"))

The CLI can generate an importable package and matching type stubs inside the prompt directory:

promptree generate ./prompts
promptree check ./prompts

You can also run the CLI as a module:

python -m promptree generate ./prompts

Pre-commit And CI

promptree check regenerates the stubs in memory and exits non-zero if the files on disk are stale. That makes it useful for both local pre-commit enforcement and CI.

If you keep a hand-written __init__.py in a prompt directory, promptree generate will leave it alone and promptree check will ignore that file.

The repository includes a hook definition in .pre-commit-hooks.yaml, and a consumer can wire it up like this:

- repo: https://github.com/your-org/promptree
  rev: v0.1.0
  hooks:
    - id: promptree-check
      files: ^prompts/

For CI, run the same command directly:

promptree check ./prompts

Why No Adapter Layer

Rendered prompt text is the common format across libraries like pydantic_ai, LangChain, and the OpenAI Python client. promptree focuses on generating and validating that text well, rather than wrapping every downstream API.

If you want IDE type safety, prefer importing the generated prompt package over constructing Promptree(...) inline in application code.

pydantic_ai

Full runnable example:

from dataclasses import dataclass

from pydantic_ai import Agent, RunContext
from prompts import tree as prompts


@dataclass
class MyDeps:
    user_name: str
    language: str


agent = Agent("openai:gpt-4o", deps_type=MyDeps)

# Static: render once at agent creation
agent_static = Agent(
    "openai:gpt-4o",
    instructions=prompts.system(name="Claude"),
)


# Dynamic: re-evaluated every run with access to ctx.deps
@agent.instructions
def dynamic_instructions(ctx: RunContext[MyDeps]) -> str:
    return prompts.system(
        name=ctx.deps.user_name,
        language=ctx.deps.language,
    )


result = agent.run_sync(
    prompts.user.greeting(name="Tim"),
    deps=MyDeps(user_name="Tim", language="en"),
)
print(result.output)

LangChain

from langchain_core.messages import HumanMessage, SystemMessage

from promptree import Promptree

prompts = Promptree("./prompts")

messages = [
    SystemMessage(content=prompts.system(name="Claude")),
    HumanMessage(content=prompts.user.greeting(name="Tim")),
]

Raw OpenAI Client

from openai import OpenAI

from promptree import Promptree

client = OpenAI()
prompts = Promptree("./prompts")

client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": prompts.system(name="Claude")},
        {"role": "user", "content": prompts.user.greeting(name="Tim")},
    ],
)

Generated Package

When you run promptree generate ./prompts, promptree writes two files into the prompt directory:

  • __init__.py with a tree object backed by Promptree
  • __init__.pyi with nested classes and typed call signatures for autocomplete

That means you can import the generated package and get both runtime access and IDE support from the same directory.

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

promptree-0.1.2.tar.gz (33.2 kB view details)

Uploaded Source

Built Distribution

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

promptree-0.1.2-py3-none-any.whl (11.6 kB view details)

Uploaded Python 3

File details

Details for the file promptree-0.1.2.tar.gz.

File metadata

  • Download URL: promptree-0.1.2.tar.gz
  • Upload date:
  • Size: 33.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for promptree-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c8356ac88c2b5c5b1625e6664cc63b917d202fee21ed24521d9127f906f0e3ab
MD5 8e742cb176de7800a6936e3eb5f73d13
BLAKE2b-256 2523392bef595ff98a60a6bb2bb503aac0f0763de83991dee66856453c7ddcc5

See more details on using hashes here.

Provenance

The following attestation bundles were made for promptree-0.1.2.tar.gz:

Publisher: python-package.yml on TKaluza/promptree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file promptree-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: promptree-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for promptree-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 902ff188c6bd6f9ad72928a0eacbddc688c6ab890322e19dbe4aece75721b201
MD5 3ea1d2db566b547d313f39dc7d72b278
BLAKE2b-256 6ed2b7f8b8ae9e3cc802ea3daa29deba417500c069257f6673881ef11d134147

See more details on using hashes here.

Provenance

The following attestation bundles were made for promptree-0.1.2-py3-none-any.whl:

Publisher: python-package.yml on TKaluza/promptree

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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