pyrompt
pyrompt: Python Prompt Management
A flexible framework for managing, sharing, and searching prompts and prompt templates with support for multiple templating languages and idiomatic Python interfaces.
- Quick Start:
>>> import tempfile >>> from pyrompt import PromptCollection, TemplateCollection >>> _base = tempfile.mkdtemp() >>> prompts = PromptCollection('my_project', base_path=_base) >>> templates = TemplateCollection('my_project', base_path=_base) >>> prompts['system'] = "You are a helpful Python expert." >>> templates['greeting.txt'] = "Hello, {name}!" >>> print(templates.render('greeting.txt', name='Alice')) Hello, Alice!
- Main Components:
PromptCollection: Store and manage prompts
TemplateCollection: Store and manage templates with multi-engine support
PromptMall: Collection of collections
SemanticIndex: Semantic search over prompts
GitHubPromptCollection: GitHub-backed collections
- class pyrompt.GitHubPromptCollection(repo: str, *, token: str | None = None, readonly: bool = True, branch: str = 'main', local_cache: str | None = None, collection_type: str = 'prompts')[source]
Prompt collection backed by GitHub repository.
Repositories must end with ‘_pyrompt’ suffix for discovery. Contains prompts/ and/or templates/ directories.
Examples
>>> # Publishing a collection >>> gh = GitHubPromptCollection( ... repo='username/my_prompts_pyrompt', ... token='ghp_...', ... readonly=False ... ) >>> gh['greeting'] = "Hello, {name}!" >>> gh.sync() # Commits and pushes to GitHub
- class pyrompt.PromptCollection(collection_name: str, *, base_path: str | None = None, with_metadata: bool = False, store_factory: Callable | None = None)[source]
Collection of prompts with MutableMapping interface.
Backed by file storage via dol, with optional metadata.
Examples
>>> import tempfile >>> prompts = PromptCollection('my_project', base_path=tempfile.mkdtemp()) >>> prompts['system'] = "You are a helpful assistant." >>> print(prompts['system']) You are a helpful assistant. >>> len(prompts) 1
- class pyrompt.PromptMall(workspace_name: str, *, base_path: str | None = None, collection_names: List[str] | None = None, with_metadata: bool = False)[source]
Collection of collections - a “mall” of stores.
Provides nested access: mall[‘collection_name’][‘prompt_key’]
Examples
>>> mall = PromptMall('my_workspace') >>> mall['system']['python_expert'] = "You are a Python expert." >>> mall['templates']['greeting'] = "Hello {name}!" >>> list(mall.keys()) ['system', 'templates'] >>> results = mall.search('python')
- add_collection(name: str, collection_type: str = 'prompt')[source]
Add a new collection to the mall.
- Parameters:
name – Collection name
collection_type – ‘prompt’ or ‘template’
Example
>>> mall.add_collection('personas', 'prompt') >>> mall['personas']['analyst'] = "You are a data analyst."
- get_collection_type(name: str) str | None[source]
Get the type of a collection.
- Parameters:
name – Collection name
- Returns:
‘prompt’, ‘template’, or None if not found
- remove_collection(name: str)[source]
Remove a collection from the mall.
Note: This only removes it from the mall, not from disk.
- Parameters:
name – Collection name
- search(query: str, collections: List[str] | None = None, **search_kwargs) Dict[str, List[tuple]][source]
Search across multiple collections.
- Parameters:
query – Search query
collections – Collection names to search (None = all)
**search_kwargs – Additional args for SemanticIndex.search
- Returns:
Dict mapping collection_name -> search results
Example
>>> results = mall.search('python expert', top_k=3) >>> for coll_name, matches in results.items(): ... print(f"\n{coll_name}:") ... for key, score in matches: ... print(f" {key}: {score:.3f}")
- class pyrompt.SemanticIndex(collection: Mapping[str, str], *, auto_update: bool = False, embedding_model: str = 'text-embedding-3-small', batch_size: int = 100)[source]
Semantic search index for prompts/templates.
Uses oa.embeddings to create vector representations, then supports similarity search.
Examples
>>> from pyrompt import PromptCollection, SemanticIndex >>> prompts = PromptCollection('my_project') >>> prompts['python'] = "You are a Python expert." >>> prompts['data'] = "You specialize in data analysis." >>> index = SemanticIndex(prompts) >>> results = index.search("help with pandas", top_k=2)
- cluster(n_clusters: int = 5)[source]
Cluster prompts/templates into groups.
- Parameters:
n_clusters – Number of clusters
- Returns:
Dict mapping cluster_id -> list of keys
- Raises:
ImportError – If scikit-learn not available
- search(query: str, top_k: int = 5, filters: dict | None = None, diversity_threshold: float | None = None) List[Tuple[str, float]][source]
Search for similar prompts.
- Parameters:
query – Search query text
top_k – Number of results to return
filters – Metadata filters (if collection has metadata)
diversity_threshold – If set, exclude results too similar to each other
- Returns:
List of (key, similarity_score) tuples, sorted by score descending
Example
>>> results = index.search("help with data analysis", top_k=3) >>> for key, score in results: ... print(f"{key}: {score:.3f}")
- class pyrompt.TemplateCollection(collection_name: str, *, base_path: str | None = None, with_metadata: bool = False, default_engine: str = 'format')[source]
Collection of templates with multi-engine support.
Automatically detects template engine based on file extension or content. Provides rendering capabilities.
Examples
>>> import tempfile >>> templates = TemplateCollection('my_project', base_path=tempfile.mkdtemp()) >>> templates['greeting.txt'] = "Hello {name}!" >>> templates.render('greeting.txt', name='Alice') 'Hello Alice!' >>> # With Jinja2 (if installed) >>> templates['greeting.jinja2'] = "Hello {{ name }}!" >>> templates.render('greeting.jinja2', name='Bob') 'Hello Bob!'
- create_prompt_functions(keys: List[str] | None = None, **common_kwargs)[source]
Create an
aix.PromptFuncscollection from templates (one function per key).LLM generation routes through
aix(lazy import).- Parameters:
keys – Template keys to include (None = all)
**common_kwargs – Common kwargs for all prompt functions (e.g. ‘model’)
- Returns:
aix.PromptFuncsobject with a function for each template
Example
>>> import tempfile >>> from pyrompt import TemplateCollection >>> tc = TemplateCollection('demo', base_path=tempfile.mkdtemp()) >>> tc['greeting.txt'] = "Greet {name}" >>> funcs = tc.create_prompt_functions() >>> funcs['greeting.txt'](name='Alice') 'Hello Alice!'
- parse(key: str) dict[source]
Parse a template to extract structure.
Returns dict with placeholders, defaults, metadata.
- Parameters:
key – Template key
- Returns:
Dict with ‘placeholders’, ‘defaults’, ‘metadata’
Example
>>> import tempfile >>> templates = TemplateCollection('demo', base_path=tempfile.mkdtemp()) >>> templates['greeting.txt'] = "Hello {name}!" >>> info = templates.parse('greeting.txt') >>> info['placeholders'] ['name']
- render(key: str, **kwargs) str[source]
Render a template with provided values.
- Parameters:
key – Template key
**kwargs – Values to inject
- Returns:
Rendered template string
Example
>>> import tempfile >>> templates = TemplateCollection('demo', base_path=tempfile.mkdtemp()) >>> templates['greeting.txt'] = "Hello {name}!" >>> templates.render('greeting.txt', name='Alice') 'Hello Alice!'
- to_prompt_function(key: str, **prompt_func_kwargs)[source]
Convert template to an AI-enabled function using
aix.prompt_func.LLM generation is routed through
aix(the multi-provider facade) so the model/provider is switchable.aixis imported lazily, only when called.- Parameters:
key – Template key
**prompt_func_kwargs – Additional kwargs for
aix.prompt_func(e.g., ‘model’, ‘temperature’, ‘name’)
- Returns:
Callable function that invokes the LLM with the rendered template
Example
>>> import tempfile >>> from pyrompt import TemplateCollection >>> tc = TemplateCollection('demo', base_path=tempfile.mkdtemp()) >>> tc['explain.txt'] = "Explain {concept} in simple terms." >>> explain = tc.to_prompt_function('explain.txt') >>> explain(concept="quantum computing") 'Quantum computing is ...'
- to_prompt_json_function(key: str, json_schema: dict, **prompt_func_kwargs)[source]
Convert template to a JSON-returning AI function.
Uses
aix.prompt_func(output_schema=dict): aix requests JSON and parses it robustly (tolerating fenced output), returning a parsed dict.json_schemais accepted for API compatibility; aix does best-effort JSON rather than strict JSON-Schema enforcement. LLM generation routes throughaix(lazy import).- Parameters:
key – Template key
json_schema – Desired JSON schema (kept for API compatibility)
**prompt_func_kwargs – Additional kwargs for
aix.prompt_func
- Returns:
Function that returns a parsed JSON dict
Example
>>> import tempfile >>> from pyrompt import TemplateCollection >>> tc = TemplateCollection('demo', base_path=tempfile.mkdtemp()) >>> tc['extract.txt'] = "Extract people from: {text}" >>> extract = tc.to_prompt_json_function('extract.txt', {}) >>> extract(text="Alice met Bob") {'people': ['Alice', 'Bob']}
- class pyrompt.TemplateEngine[source]
Abstract base class for template engines.
Template engines parse and render templates with different syntaxes. They must provide: - name: Unique identifier (e.g., ‘format’, ‘jinja2’) - extensions: List of file extensions (e.g., [‘.jinja2’, ‘.j2’]) - parse_template: Extract placeholders and defaults - render: Render template with values - detect: Optionally detect if content uses this engine
- detect(content: str) bool[source]
Detect if content uses this engine based on syntax.
Used when extension doesn’t clearly indicate engine. Override to provide content-based detection.
- Parameters:
content – Template content
- Returns:
True if content appears to use this engine
- pyrompt.clone_collection(repo: str, local_path: str, token: str | None = None)[source]
Clone a GitHub collection to local directory.
- Parameters:
repo – Repository name (user/repo_pyrompt)
local_path – Local directory path
token – Optional GitHub token
Example
>>> clone_collection( ... 'thorwhalen/awesome_prompts_pyrompt', ... '/tmp/my_prompts' ... )
- pyrompt.create_project_structure(project_name: str, base_path: str | None = None, include_examples: bool = True) str[source]
Create a complete project structure for prompt management.
Creates directories and example files for a new pyrompt project.
- Parameters:
project_name – Name of the project
base_path – Optional base path
include_examples – Whether to include example prompts
- Returns:
Path to created project directory
Example
>>> path = create_project_structure('my_ai_app') >>> print(f"Project created at: {path}")
- pyrompt.detect_engine(content: str, extension: str = None) TemplateEngine[source]
Detect appropriate engine for content.
Priority: 1. Extension match (if provided) 2. Content-based detection 3. Default (format)
- Parameters:
content – Template content
extension – Optional file extension
- Returns:
TemplateEngine instance (never None, falls back to ‘format’)
- pyrompt.discover_prompt_collections(search_term: str | None = None, min_stars: int = 0, language: str = 'Python', max_results: int = 50) List[dict][source]
Discover public *_pyrompt repositories on GitHub.
- Parameters:
search_term – Search query (e.g., “python data”)
min_stars – Minimum star count
language – Programming language filter
max_results – Maximum number of results
- Returns:
List of dicts with repo info (name, description, stars, url)
Example
>>> collections = discover_prompt_collections( ... search_term='python', ... min_stars=5 ... ) >>> for repo in collections: ... print(f"{repo['name']}: {repo['stars']} stars")
- pyrompt.export_to_dict(collection, include_metadata: bool = True) Dict[str, Any][source]
Export collection to a dictionary.
- Parameters:
collection – PromptCollection or TemplateCollection
include_metadata – Whether to include metadata
- Returns:
Dict with ‘prompts’ and optionally ‘metadata’ keys
Example
>>> import tempfile >>> from pyrompt import PromptCollection >>> prompts = PromptCollection('my_project', base_path=tempfile.mkdtemp()) >>> prompts['system'] = 'You are helpful.' >>> export_to_dict(prompts, include_metadata=False) {'prompts': {'system': 'You are helpful.'}}
- pyrompt.fork_collection(source: str, token: str, organization: str | None = None) GitHubPromptCollection[source]
Fork a collection to your account or organization.
- Parameters:
source – Source repo (user/repo_pyrompt)
token – GitHub token with repo permissions
organization – Optional organization to fork to
- Returns:
GitHubPromptCollection for the new fork
Example
>>> forked = fork_collection( ... 'thorwhalen/awesome_prompts_pyrompt', ... token='ghp_...' ... )
- pyrompt.get_default_base_path() str[source]
Get platform-appropriate base path for pyrompt data.
- Returns:
%LOCALAPPDATA%/pyrompt - macOS/Linux: ~/.local/share/pyrompt
- Return type:
Windows
- pyrompt.get_engine(name: str) TemplateEngine | None[source]
Get engine by name.
- Parameters:
name – Engine name (e.g., ‘format’, ‘jinja2’)
- Returns:
TemplateEngine instance or None if not found
- pyrompt.get_stats(collection) Dict[str, Any][source]
Get statistics about a collection.
- Parameters:
collection – PromptCollection or TemplateCollection
- Returns:
Dict with statistics
Example
>>> import tempfile >>> from pyrompt import PromptCollection >>> prompts = PromptCollection('my_project', base_path=tempfile.mkdtemp()) >>> get_stats(prompts)['total_prompts'] 0
- pyrompt.import_from_dict(collection, prompts: Dict[str, str], metadata: Dict[str, dict] | None = None)[source]
Import prompts from a dictionary.
- Parameters:
collection – PromptCollection or TemplateCollection
prompts – Dict mapping keys to prompt/template strings
metadata – Optional dict mapping keys to metadata dicts
Example
>>> import tempfile >>> from pyrompt import PromptCollection >>> prompts = PromptCollection('my_project', base_path=tempfile.mkdtemp()) >>> import_from_dict(prompts, {'system': 'You are helpful.', 'user': 'Hello!'}) >>> sorted(prompts) ['system', 'user']
- pyrompt.list_available_engines() Dict[str, Dict[str, Any]][source]
List all available template engines with their details.
- Returns:
Dict mapping engine name to info dict
Example
>>> engines = list_available_engines() >>> print(engines['format']['extensions']) ['.txt', '']
- pyrompt.list_engines() List[str][source]
List all registered engine names.
- Returns:
List of engine names
- pyrompt.merge_collections(target, *sources, conflict_strategy: str = 'skip')[source]
Merge multiple collections into a target collection.
- Parameters:
target – Target collection to merge into
*sources – Source collections to merge from
conflict_strategy – How to handle conflicts (‘skip’, ‘overwrite’, ‘error’)
Example
>>> import tempfile >>> from pyrompt import PromptCollection >>> base = tempfile.mkdtemp() >>> target = PromptCollection('merged', base_path=base) >>> source1 = PromptCollection('source1', base_path=base) >>> source1['a'] = 'A' >>> merge_collections(target, source1, conflict_strategy='skip') >>> sorted(target) ['a']
- pyrompt.quick_setup(project_name: str, with_templates: bool = True, with_metadata: bool = False, base_path: str | None = None) Dict[str, Any][source]
Quick setup for a new pyrompt project.
Creates both prompt and template collections with sensible defaults.
- Parameters:
project_name – Name of the project
with_templates – Whether to create a template collection
with_metadata – Whether to enable metadata
base_path – Optional base path
- Returns:
Dict with ‘prompts’ and optionally ‘templates’ keys
Example
>>> import tempfile >>> collections = quick_setup('my_ai_project', base_path=tempfile.mkdtemp()) >>> collections['prompts']['system'] = "You are a helpful assistant." >>> collections['templates']['greeting.txt'] = "Hello {name}!" >>> sorted(collections) ['prompts', 'templates']
- pyrompt.register_engine(engine: TemplateEngine)[source]
Register a template engine.
- Parameters:
engine – TemplateEngine instance to register
- pyrompt.render_template_file(file_path: str, output_path: str | None = None, **kwargs) str[source]
Render a template file directly.
- Parameters:
file_path – Path to template file
output_path – Optional path to save rendered output
**kwargs – Template parameters
- Returns:
Rendered string
Example
>>> result = render_template_file( ... 'templates/greeting.txt', ... name='Alice' ... )
- pyrompt.validate_template(template_str: str, engine_name: str = 'format', required_params: List[str] | None = None) Dict[str, Any][source]
Validate a template string.
- Parameters:
template_str – Template content
engine_name – Engine to use (‘format’, ‘jinja2’, ‘mustache’)
required_params – Optional list of required parameter names
- Returns:
Dict with ‘valid’, ‘errors’, ‘warnings’, ‘placeholders’
Example
>>> result = validate_template("Hello {name}!", required_params=['name']) >>> assert result['valid'] >>> result = validate_template("Hello {name}!", required_params=['name', 'age']) >>> assert not result['valid']