Skip to main content

Prompty is an asset class and format for LLM prompts

Project description

Prompty — Python Runtime

PyPI Python 3.11+

Prompty is a markdown file format (.prompty) for LLM prompts. The Python runtime loads, renders, parses, and executes these files. Every .prompty file becomes a typed Prompty object.

Installation

# Core + Jinja2 renderer + OpenAI provider
pip install prompty[jinja2,openai]

# Core + Microsoft Foundry provider
pip install prompty[jinja2,foundry]

# Core + Anthropic provider
pip install prompty[jinja2,anthropic]

# Everything (all renderers, providers, OpenTelemetry)
pip install prompty[all]

Extras

Extra Packages What it enables
[openai] openai OpenAI provider
[foundry] openai, azure-identity Microsoft Foundry provider
[anthropic] anthropic Anthropic provider
[jinja2] jinja2 Jinja2 template rendering
[mustache] chevron Mustache template rendering
[otel] opentelemetry-api OpenTelemetry tracing
[all] All of the above Everything

Quick Start

1. Write a .prompty File

---
name: greeting
model:
  id: gpt-4o-mini
  provider: openai
  connection:
    kind: key
    apiKey: ${env:OPENAI_API_KEY}
inputs:
  - name: name
    kind: string
    default: World
template:
  format:
    kind: jinja2
  parser:
    kind: prompty
---
system:
You are a friendly assistant.

user:
Say hello to {{name}}.

2. Run It

import prompty

# One-shot: load + prepare + run
result = prompty.execute(
    "greeting.prompty", inputs={"name": "Jane"}
)
print(result)

# Step-by-step
agent = prompty.load("greeting.prompty")
messages = prompty.prepare(
    agent, inputs={"name": "Jane"}
)
result = prompty.run(agent, messages)

3. Async

result = await prompty.execute_async(
    "greeting.prompty", inputs={"name": "Jane"}
)

API Reference

Core Functions

Function What it does
load(path) Parse .promptyPrompty
render(agent, inputs) Template → rendered string
parse(agent, rendered) Rendered string → list[Message]
prepare(agent, inputs) Render + parse + threads → list[Message]
run(agent, msgs) Executor + process → clean result
process(agent, resp) Extract content → clean result
execute(prompt, inputs) Full pipeline: load + prepare + run
execute_agent(prompt, ...) Full pipeline with tool-call loop
headless(api, ...) Create Prompty w/o a file
validate_inputs(...) Check required inputs present

All functions have _async variants (e.g., execute_async, run_async, execute_agent_async).

Agent Mode (Tool Calling)

def get_weather(location: str) -> str:
    return f"72°F and sunny in {location}"

result = prompty.execute_agent(
    "my-agent.prompty",
    inputs={"question": "Weather in Seattle?"},
    tools={"get_weather": get_weather},
    max_iterations=10,  # default
)

The agent loop: calls the LLM, if it returns tool_calls, executes the matching functions, sends results back, repeats until the model returns a normal response or max_iterations is exceeded.

Error handling:

  • Bad JSON in tool arguments → error sent back to model for self-correction
  • Tool exception → error string sent back to model
  • Missing tool → error message sent back (no crash)
  • Max iterationsValueError raised

Connection Registry

For pre-configured SDK clients or token-based auth:

# .prompty file — reference a named connection
model:
  id: gpt-4o
  provider: foundry
  connection:
    kind: reference
    name: my-foundry
from openai import AzureOpenAI
from azure.identity import (
    DefaultAzureCredential,
    get_bearer_token_provider,
)

client = AzureOpenAI(
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
    azure_ad_token_provider=get_bearer_token_provider(
        DefaultAzureCredential(),
        "https://cognitiveservices.azure.com/.default",
    ),
)
prompty.register_connection("my-foundry", client=client)

# Now run — executor resolves the client by name
result = prompty.execute(
    "my-prompt.prompty", inputs={...}
)

Structured Output

Define outputs in frontmatter to get JSON-parsed results:

outputs:
  - name: city
    kind: string
    description: The city name
  - name: temperature
    kind: integer
    description: Temperature in Fahrenheit

The executor sends this as OpenAI's response_format with json_schema, and the processor automatically JSON-parses the result.

Streaming

agent = prompty.load("chat.prompty")
messages = prompty.prepare(
    agent, inputs={"question": "Tell me a story"}
)

# Set stream option
agent.model.options.additionalProperties = {
    "stream": True,
}
response = prompty.run(agent, messages, raw=True)

# response is a PromptyStream — iterate for chunks
for chunk in prompty.process(agent, response):
    print(chunk, end="", flush=True)

Streaming handles tool call deltas (accumulated across chunks), refusal detection, and empty heartbeat chunks.

Tracing

from prompty import Tracer, PromptyTracer, trace

# Register a tracer
Tracer.add("console", prompty.console_tracer)
Tracer.add(
    "json", PromptyTracer("./traces").tracer
)

# All pipeline functions automatically emit traces
result = prompty.execute(
    "my-prompt.prompty", inputs={...}
)

# Custom functions
@trace
def my_function():
    ...

OpenTelemetry integration:

from prompty.tracing.otel import otel_tracer
Tracer.add("otel", otel_tracer())

.prompty File Format

Structure

---
# YAML frontmatter (Prompty schema)
---
# Markdown body (becomes `instructions`)
# Uses role markers and template syntax

Role Markers

system:
You are a helpful assistant.

user:
{{question}}

assistant:
I'd be happy to help.

Thread Inputs

Conversation history is passed via a kind: thread input property:

inputs:
  - name: conversation
    kind: thread

Place {{conversation}} in the template where thread messages should be injected:

system:
You are a helpful assistant.
{{conversation}}
user:
{{question}}

The caller passes a list of messages as the thread input value.

Variable References

Syntax Purpose
${env:VAR} Env variable (required)
${env:VAR:default} Env variable with fallback
${file:path.json} Load file content

Connection Kinds

Kind When to use
key API key auth (self-contained)
reference Pre-registered SDK client
anonymous Endpoint only, no credentials

Legacy Format Support

Prompty v1 .prompty files are automatically migrated with deprecation warnings. Key changes:

  • model.configurationmodel.connection
  • model.parametersmodel.options
  • inputs (dict format) → inputs (list of Property)
  • inputSchemainputs
  • outputSchemaoutputs
  • template: jinja2 → structured template with format and parser

Development

# Install for development
uv pip install -e ".[dev,all]"

# Unit tests (excludes integration by default)
uv run pytest tests/ -q

# Lint
uv run ruff check .
uv run ruff format --check .

# Integration tests (requires API keys in .env)
uv run pytest tests/integration/ -v -o "addopts="

License

See LICENSE in the repository root.

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

prompty-2.0.0a3.tar.gz (192.4 kB view details)

Uploaded Source

Built Distribution

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

prompty-2.0.0a3-py3-none-any.whl (81.5 kB view details)

Uploaded Python 3

File details

Details for the file prompty-2.0.0a3.tar.gz.

File metadata

  • Download URL: prompty-2.0.0a3.tar.gz
  • Upload date:
  • Size: 192.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for prompty-2.0.0a3.tar.gz
Algorithm Hash digest
SHA256 c1fc2210e5d5644ebab5d6081b48f92fd8ad342d4e0e2f5a7cada3ac4b4a5099
MD5 36a083bd1c1be0be4d2e05e1b453dd3c
BLAKE2b-256 269a844281a0a42e9f3940be972a45f87b758c370d6695738c28fdab1981107a

See more details on using hashes here.

Provenance

The following attestation bundles were made for prompty-2.0.0a3.tar.gz:

Publisher: prompty-python.yml on microsoft/prompty

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

File details

Details for the file prompty-2.0.0a3-py3-none-any.whl.

File metadata

  • Download URL: prompty-2.0.0a3-py3-none-any.whl
  • Upload date:
  • Size: 81.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for prompty-2.0.0a3-py3-none-any.whl
Algorithm Hash digest
SHA256 30223b34c137f2dd99342c7a47d5e26ed32eaed5e063fd1d3233231a80635f80
MD5 bcf4c7083e99c970b4895feaa9dea696
BLAKE2b-256 b2645ce26b4243d1a3ea3fa26564306f2329eb41cee40a5470581884c7387684

See more details on using hashes here.

Provenance

The following attestation bundles were made for prompty-2.0.0a3-py3-none-any.whl:

Publisher: prompty-python.yml on microsoft/prompty

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