Skip to main content

A module to create prompt templates dynamically

Project description

Proteas

A domain-agnostic library for composing prompts from reusable units.

Installation

pip install proteas

Quick Start

from proteas import Proteas, PromptTemplateUnit

# Define reusable units
header = PromptTemplateUnit(
    name="header",
    content="You are a helpful assistant.",
    order=1
)

task = PromptTemplateUnit(
    name="task",
    content="Analyze the following data: $data",
    order=2
)

# Compose and compile
prompt = (Proteas()
    .add(header)
    .add(task)
    .compile(data="user input here"))

print(prompt)
# Output:
# You are a helpful assistant.
#
# Analyze the following data: user input here

Core Concepts

PromptTemplateUnit

A unit is a single, reusable piece of prompt content:

from proteas import PromptTemplateUnit

unit = PromptTemplateUnit(
    name="greeting",           # Identifier for lookup
    content="Hello $name!",    # The actual text (with optional placeholders)
    order=10,                  # Position when combining (lower = earlier)
    prefix="=== START ===",    # Optional text before content
    suffix="=== END ===",      # Optional text after content
    enabled=True               # Whether to include when rendering
)

Placeholder Syntax

Proteas uses $variable syntax for placeholders (via Python's string.Template). This allows JSON and other content with curly braces to work without escaping:

unit = PromptTemplateUnit(
    name="schema",
    content='Return JSON: {"result": $value}'
)

# JSON braces are preserved, only $value is substituted
result = unit.render(value='"hello"')
# Output: Return JSON: {"result": "hello"}

Both $variable and ${variable} syntaxes are supported.

Proteas Combiner

The Proteas class combines multiple units into a single prompt:

from proteas import Proteas, PromptTemplateUnit

p = Proteas(separator="\n\n")  # Default separator is double newline

# Add units (method chaining supported)
p.add(PromptTemplateUnit(name="a", content="First"))
p.add(PromptTemplateUnit(name="b", content="Second"))

# Or add many at once
p.add_many([unit1, unit2, unit3])

# Compile with placeholder values
prompt = p.compile(messages="...", context="...")

Ordering

Units can be ordered explicitly or by insertion order:

# Explicit order (lower numbers first)
header = PromptTemplateUnit(name="header", content="...", order=1)
body = PromptTemplateUnit(name="body", content="...", order=50)
footer = PromptTemplateUnit(name="footer", content="...", order=100)

# order=None uses insertion order
p = Proteas()
p.add(footer)   # Added first, but order=100
p.add(header)   # Added second, but order=1
p.add(body)     # Added third, order=50

# Result: header, body, footer (by explicit order)

When orders are equal or all None, insertion order is the tiebreaker.

Enable/Disable Units

Units can be toggled on or off:

unit = PromptTemplateUnit(name="optional", content="...", enabled=False)

# Enable/disable on the unit
unit.enable()
unit.disable()

# Or via Proteas by name
p = Proteas()
p.add(unit)
p.disable("optional")
p.enable("optional")

Unit Management

p = Proteas()
p.add(unit1)
p.add(unit2)

# Get a unit by name
unit = p.get_unit("unit1")

# Remove a unit
p.remove("unit1")

# Clear all units
p.clear()

# Properties
p.units          # All units in insertion order
p.enabled_units  # Only enabled units
len(p)           # Number of units

Generating Combinations

For scenarios where you need all combinations of units:

from proteas import generate_combinations, count_combinations, PromptTemplateUnit

units = [
    PromptTemplateUnit(name="a", content="A"),
    PromptTemplateUnit(name="b", content="B"),
    PromptTemplateUnit(name="c", content="C"),
]

# Count combinations
total = count_combinations(n=3, min_size=2, max_size=2)  # 3

# Generate combinations
for names, proteas_instance in generate_combinations(units, min_size=2, max_size=2):
    print(names)  # ('a', 'b'), ('a', 'c'), ('b', 'c')
    prompt = proteas_instance.compile()

You can also include base units that appear in all combinations:

header = PromptTemplateUnit(name="header", content="Header", order=1)
footer = PromptTemplateUnit(name="footer", content="Footer", order=100)

for names, p in generate_combinations(
    units=dimension_units,
    min_size=2,
    max_size=4,
    base_units=[header, footer]
):
    prompt = p.compile(messages="...")

Immutable Copies

Create modified copies without mutating the original:

original = PromptTemplateUnit(name="test", content="Hello", order=10)

# Create copies with modifications
with_new_content = original.with_content("Goodbye")
with_new_order = original.with_order(99)

# Original is unchanged
assert original.content == "Hello"
assert original.order == 10

API Reference

PromptTemplateUnit

Attribute Type Description
name str Identifier for the unit
content str The prompt text (supports $placeholder syntax)
order int | None Sort position (None = use insertion order)
prefix str | None Text added before content
suffix str | None Text added after content
enabled bool Include in output when True
Method Returns Description
render(**kwargs) str Render with placeholder substitution
enable() self Enable the unit
disable() self Disable the unit
with_content(str) PromptTemplateUnit Copy with new content
with_order(int) PromptTemplateUnit Copy with new order

Proteas

Method Returns Description
add(unit) self Add a unit
add_many(units) self Add multiple units
compile(**kwargs) str Assemble all enabled units
get_unit(name) Unit | None Find unit by name
remove(name) self Remove unit by name
clear() self Remove all units
enable(name) self Enable unit by name
disable(name) self Disable unit by name
Property Type Description
units list[Unit] All units
enabled_units list[Unit] Only enabled units

Combination Functions

Function Description
generate_combinations(units, min_size, max_size, base_units) Yield (names, Proteas) for all combinations
count_combinations(n, min_size, max_size) Count total combinations

License

MIT

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

proteas-0.0.5.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

proteas-0.0.5-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file proteas-0.0.5.tar.gz.

File metadata

  • Download URL: proteas-0.0.5.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for proteas-0.0.5.tar.gz
Algorithm Hash digest
SHA256 8b562a67a65bdcbdf7267d30e54fd050fb7e0064d43d325386291c937a7937cb
MD5 25045bb69c0a1df91be1ea387ee6f128
BLAKE2b-256 23a7b5970b5474efa66b221d43deca496a9906e1794dc5df5556ecae325aa3ee

See more details on using hashes here.

File details

Details for the file proteas-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: proteas-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for proteas-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 15208332b1701e059d9860ab976ca70bc384b83bef4e660582a76efe04fd4e3a
MD5 bebcd5f378c3d89810a7e90b77989fcd
BLAKE2b-256 7b1a0feba613eec35ba16e3cdbf491a67caf51146f75c33f8e6b2891e0c0f03b

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