Skip to main content

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

Metadata

Release files for proteas 0.0.5

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

Source distribution (sdist)

Source distribution for proteas 0.0.5
File Size Uploaded
proteas-0.0.5.tar.gz 11.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for proteas 0.0.5
File Interpreter ABI Platform
proteas-0.0.5-py3-none-any.whl Python 3 none any Details

Total release size: 22.1 kB

Release files / proteas-0.0.5.tar.gz

Download URL proteas-0.0.5.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
8b562a67a65bdcbdf7267d30e54fd050fb7e0064d43d325386291c937a7937cb
BLAKE2b-256 checksum
How to use checksums
23a7b5970b5474efa66b221d43deca496a9906e1794dc5df5556ecae325aa3ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / proteas-0.0.5-py3-none-any.whl

Download URL proteas-0.0.5-py3-none-any.whl
Size 10.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
15208332b1701e059d9860ab976ca70bc384b83bef4e660582a76efe04fd4e3a
BLAKE2b-256 checksum
How to use checksums
7b1a0feba613eec35ba16e3cdbf491a67caf51146f75c33f8e6b2891e0c0f03b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release history Release notifications | RSS feed

This release

0.0.5 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

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