Source code for dbutils_batch_query.prompts
# ====================================================================
# Author: William Muntean
# Copyright (C) 2025 William Muntean. All rights reserved.
#
# Licensed under the MIT License;
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://opensource.org/licenses/MIT
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ====================================================================
"""
=======================================================
prompts
=======================================================
This module provides utilities for loading and rendering Jinja2-based markdown prompt templates from directories or files.
Prompt Template Loading and Rendering
=====================================
The module supports recursive loading of all markdown templates in a directory and rendering individual templates with custom arguments.
.. Note::
- Templates must use the ``.md`` extension and be compatible with Jinja2 syntax.
.. currentmodule:: dbutils_batch_query.prompts
Functions
=========
.. autosummary::
:toctree: generated/
:nosignatures:
:template: function_name_only.rst
load_all
load_prompt
"""
__author__ = "William Muntean"
__email__ = "williamjmuntean@gmail.com"
__license__ = "GPL v3"
__maintainer__ = "William Muntean"
__date__ = "2025-03-23"
from pathlib import Path
from jinja2 import Template
[docs]
def load_all(directory_path: str | Path) -> dict[str, Template]:
"""
Recursively load all markdown prompt templates from a directory into a dictionary.
This function traverses the given directory and its subdirectories to find
markdown template files (with .md extension) and loads them into Jinja2 Template objects.
The templates are stored in a dictionary with filenames as keys, with folder
names prepended in case of duplicate filenames.
Parameters
----------
directory_path : str or Path
Path to the directory containing markdown prompt template files.
Returns
-------
dict[str, Template]
A dictionary where:
- ``key``: Filename (with folder name prepended if duplicate).
- ``value``: jinja Template object.
.. Note::
Template files are expected to be markdown files (.md extension) that can be parsed
by Jinja2.
Examples
--------
>>> templates = load_all("/path/to/templates")
>>> admission_template = templates["admission_note"]
"""
templates = {}
directory = Path(directory_path)
for file_path in directory.glob("**/*.md"):
# Skip directories and hidden files
if file_path.is_dir() or file_path.name.startswith("."):
continue
# Load the file content and create a template
template_content = file_path.read_text()
template = Template(template_content)
# Use filename as key, handle duplicates by prepending folder name
key = file_path.stem
if key in templates:
# Get the parent folder name
folder_name = file_path.parent.name
key = f"{folder_name}-{file_path.stem}"
templates[key] = template
return templates
[docs]
def load_prompt(file_path: str | Path, **kwargs: list | str) -> str:
"""
Load and render a single prompt template from a file.
Parameters
----------
file_path : str or Path
Path to the template file to load.
**kwargs : list or str
Additional keyword arguments to pass to the template renderer.
For example, you can pass ``examples`` as a list or string to provide
example data for rendering.
Returns
-------
str
The rendered template content.
Examples
--------
>>> prompt = load_prompt("/path/to/template.md")
>>> prompt_with_examples = load_prompt(
... "/path/to/template.md", examples=[]"example1", "example2"]
... )
"""
template_path = Path(file_path)
template_content = template_path.read_text()
# Render the template with the provided keyword arguments
template = Template(template_content)
rendered_prompt = template.render(**kwargs)
return rendered_prompt