prompt-template-manager 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,358 @@
1
+ Metadata-Version: 2.4
2
+ Name: prompt-template-manager
3
+ Version: 1.0.0
4
+ Summary: A lightweight and extensible Python library for managing, versioning, and composing reusable prompt templates from YAML or text files.
5
+ Home-page: https://promptmanager.davman.dev
6
+ Author: Dave Manufor
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
10
+ Classifier: Topic :: Text Processing :: Linguistic
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Operating System :: OS Independent
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: PyYAML
19
+ Dynamic: author
20
+ Dynamic: classifier
21
+ Dynamic: description
22
+ Dynamic: description-content-type
23
+ Dynamic: home-page
24
+ Dynamic: requires-dist
25
+ Dynamic: summary
26
+
27
+ # Prompt Manager
28
+
29
+ A robust **Python utility** for loading, versioning, and managing prompt templates from YAML files or flat file directories.
30
+
31
+ Prompt Manager is designed to solve the problem of managing a **large, complex, and evolving library of prompts**. It allows you to compose prompts from reusable parts, manage versions (e.g., for A/B testing or model-specific tuning), and safely inject variables at runtime.
32
+
33
+ ---
34
+
35
+ ## 📚 Table of Contents
36
+
37
+ * [Core Features](#-core-features)
38
+ * [Installation](#-installation)
39
+ * [Quick Start](#-quick-start)
40
+ * [YAML Configuration Schema](#-yaml-configuration-schema)
41
+
42
+ * [Versioned Prompts (Recommended)](#1-versioned-prompts-recommended)
43
+ * [Simple Prompts (Non-versioned)](#2-simple-prompts-non-versioned)
44
+ * [Include Directives – {include prompt_name}](#3-include-directives--include-prompt_name)
45
+ * [Variable Placeholders – {variable_name}](#4-variable-placeholders--variable_name)
46
+ * [Loading from a Directory](#-loading-from-a-directory)
47
+ * [API Reference](#-api-reference)
48
+
49
+ * [Class: PromptManager](#class-promptmanager)
50
+ * [Class: Prompt](#class-prompt)
51
+ * [Advanced Usage Examples](#-advanced-usage-examples)
52
+
53
+ * [Example 1: Version A/B Testing](#example-1-version-ab-testing)
54
+ * [Example 2: Partial Formatting (Chain-of-Thought)](#example-2-partial-formatting-chain-of-thought)
55
+ * [Validation Rules](#-validation-rules)
56
+ * [Testing](#-testing)
57
+ * [License](#-license)
58
+
59
+ ---
60
+
61
+ ## 🚀 Core Features
62
+
63
+ * **Centralized Prompt Management:** Load all prompts from a single structured YAML file.
64
+ * **Fallback Directory Loading:** Optionally load simple prompts from a directory of `.txt` files.
65
+ * **Prompt Versioning:** Native support for versions (e.g., `v1`, `v2`) with a `_default` key.
66
+ * **Recursive Composition:** Build complex prompts from smaller, reusable components using `{include ...}` directives.
67
+ * **Safe Variable Substitution:** Format prompts with `{variable}` placeholders using a strict or non-strict API.
68
+ * **Partial Formatting:** Fill variables incrementally for chain-of-thought or multi-step prompt sequences.
69
+ * **Configuration Validation:** Validate prompt configurations at load time to catch errors early.
70
+
71
+ ---
72
+
73
+ ## 💾 Installation
74
+
75
+ ```bash
76
+ pip install prompt_template_manager
77
+ ```
78
+
79
+ ---
80
+
81
+ ## ⚡ Quick Start
82
+
83
+ ### 1. Create your `prompts.yaml` file
84
+
85
+ ```yaml
86
+ # prompts.yaml
87
+
88
+ system_persona:
89
+ _default: v2
90
+ _meta:
91
+ description: "The standard AI persona."
92
+ v1: "You are a helpful AI."
93
+ v2: "You are a helpful, concise, and polite AI assistant."
94
+
95
+ summarize_task:
96
+ _default: v1
97
+ v1: |
98
+ {include system_persona}
99
+
100
+ Your task is to summarize the following document into {num_sentences} sentences.
101
+ Document: {text}
102
+
103
+ Your summary:
104
+ ```
105
+
106
+ ### 2. Use `PromptManager` in your Python code
107
+
108
+ ```python
109
+ from source.PromptManager import PromptManager
110
+
111
+ try:
112
+ manager = PromptManager('prompts.yaml')
113
+ prompt = manager.get('summarize_task')
114
+
115
+ my_data = {
116
+ "num_sentences": 3,
117
+ "text": "The quick brown fox jumps over the lazy dog."
118
+ }
119
+
120
+ formatted_prompt = prompt.format(my_data)
121
+ print(formatted_prompt)
122
+
123
+ except FileNotFoundError:
124
+ print("Error: prompts.yaml not found.")
125
+ except (ValueError, KeyError) as e:
126
+ print(f"Error loading or getting prompt: {e}")
127
+ ```
128
+
129
+ **Output:**
130
+
131
+ ```
132
+ You are a helpful, concise, and polite AI assistant.
133
+
134
+ Your task is to summarize the following document into 3 sentences.
135
+ Document: The quick brown fox jumps over the lazy dog.
136
+
137
+ Your summary:
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 🧩 YAML Configuration Schema
143
+
144
+ The `PromptManager` supports two main structures for defining prompts.
145
+
146
+ ### 1. Versioned Prompts (Recommended)
147
+
148
+ A “versioned prompt” is a dictionary containing:
149
+
150
+ * `_default` (Required): Default version key (e.g., `v1`).
151
+ * `v{number}` (Required): Version key(s) with prompt text.
152
+ * `_meta` (Optional): Arbitrary metadata.
153
+
154
+ **Example:**
155
+
156
+ ```yaml
157
+ system_persona_default:
158
+ _default: v2
159
+ _meta:
160
+ description: "The standard AI persona."
161
+ author: "Admin"
162
+ v1: "You are a helpful AI."
163
+ v2: "You are a helpful, concise, and polite AI assistant. You always answer the user's question directly."
164
+ ```
165
+
166
+ ---
167
+
168
+ ### 2. Simple Prompts (Non-versioned)
169
+
170
+ For simple, static prompts:
171
+
172
+ ```yaml
173
+ simple_greeting: "Hello, {name}. This is a simple, non-versioned prompt."
174
+ ```
175
+
176
+ > ⚠️ Not recommended for complex systems — lacks versioning, metadata, and include support.
177
+
178
+ ---
179
+
180
+ ### 3. Include Directives – `{include prompt_name}`
181
+
182
+ Compose prompts from other prompts:
183
+
184
+ ```yaml
185
+ system_persona:
186
+ _default: v1
187
+ v1: "You are a helpful AI."
188
+
189
+ output_format_json:
190
+ _default: v1
191
+ v1: "Your response MUST be a single, valid JSON object."
192
+
193
+ generate_user_profile:
194
+ _default: v1
195
+ _meta:
196
+ description: "Generates a JSON profile from a user's bio."
197
+ v1: |
198
+ {include system_persona}
199
+ {include output_format_json}
200
+
201
+ Analyze the following user bio and generate a profile.
202
+ Bio: {bio_text}
203
+ ```
204
+
205
+ Circular references (e.g., A includes B and B includes A) raise an **ImportError**.
206
+
207
+ ---
208
+
209
+ ### 4. Variable Placeholders – `{variable_name}`
210
+
211
+ * Any text enclosed in `{}` is treated as a variable.
212
+ * Variables are filled using `.format()` or `.partial()`.
213
+ * Variable names are validated on load.
214
+
215
+ ---
216
+
217
+ ## 📁 Loading from a Directory
218
+
219
+ You can also load prompts from a directory:
220
+
221
+ ```
222
+ my_txt_prompts/
223
+ ├── greet.txt
224
+ └── farewell.txt
225
+ ```
226
+
227
+ ```python
228
+ manager = PromptManager('my_txt_prompts/')
229
+ prompt = manager.get('greet')
230
+ ```
231
+
232
+ **Notes:**
233
+
234
+ * Only `.txt` files are loaded.
235
+ * Filenames become prompt names.
236
+ * Each prompt defaults to version `v1`.
237
+ * No support for metadata, includes, or multiple versions.
238
+
239
+ ---
240
+
241
+ ## 🧠 API Reference
242
+
243
+ ### **Class: `PromptManager`**
244
+
245
+ #### `__init__(self, source_path: str | Path)`
246
+
247
+ Loads and validates prompts from a YAML file or `.txt` directory.
248
+
249
+ **Raises:**
250
+ `FileNotFoundError`, `ValueError`, `yaml.YAMLError`
251
+
252
+ #### `get(self, name: str, version: int | None = None) -> Prompt`
253
+
254
+ Retrieves a fully resolved `Prompt` object.
255
+
256
+ **Raises:**
257
+ `KeyError`, `ValueError`, `ImportError`
258
+
259
+ ---
260
+
261
+ ### **Class: `Prompt`**
262
+
263
+ #### `format(self, data: dict, strict: bool = True) -> str`
264
+
265
+ Substitutes all variables.
266
+
267
+ #### `partial(self, data: dict) -> Prompt`
268
+
269
+ Partially fills variables, returning a new `Prompt`.
270
+
271
+ #### `get_raw_content(self) -> str`
272
+
273
+ Returns resolved, unformatted prompt text.
274
+
275
+ #### `get_variables(self) -> dict`
276
+
277
+ Lists remaining variable placeholders.
278
+
279
+ #### `get_meta(self) -> dict`
280
+
281
+ Returns the `_meta` dictionary (if any).
282
+
283
+ ---
284
+
285
+ ## ⚙️ Advanced Usage Examples
286
+
287
+ ### Example 1: Version A/B Testing
288
+
289
+ ```python
290
+ manager = PromptManager('prompts.yaml')
291
+
292
+ prompt_v2 = manager.get('system_persona')
293
+ prompt_v1 = manager.get('system_persona', version=1)
294
+
295
+ print(f"Default: {prompt_v2.get_raw_content()}")
296
+ print(f"V1: {prompt_v1.get_raw_content()}")
297
+ ```
298
+
299
+ **Output:**
300
+
301
+ ```
302
+ Default: You are a helpful, concise, and polite AI assistant.
303
+ V1: You are a helpful AI.
304
+ ```
305
+
306
+ ---
307
+
308
+ ### Example 2: Partial Formatting (Chain-of-Thought)
309
+
310
+ ```python
311
+ manager = PromptManager('prompts.yaml')
312
+ prompt = manager.get('summarize_task')
313
+
314
+ print(f"Original variables: {prompt.get_variables().keys()}")
315
+
316
+ partial_prompt = prompt.partial({
317
+ "text": "This is a long document about the history of computing."
318
+ })
319
+
320
+ print(f"Partial variables: {partial_prompt.get_variables().keys()}")
321
+ print("--- Partial Content ---")
322
+ print(partial_prompt.get_raw_content())
323
+
324
+ final_prompt_str = partial_prompt.format({
325
+ "num_sentences": 2
326
+ })
327
+
328
+ print("\n--- Final Content ---")
329
+ print(final_prompt_str)
330
+ ```
331
+
332
+ ---
333
+
334
+ ## ✅ Validation Rules
335
+
336
+ **Prompt Names**
337
+
338
+ * Must be valid Python identifiers (e.g., `my_prompt`, `_internal_prompt`).
339
+
340
+ **Variable Names**
341
+
342
+ * Must start with a letter.
343
+ * May include letters, numbers, `-`, and `_`.
344
+ * Cannot end with `-` or `_`.
345
+
346
+ **Include Names**
347
+
348
+ * Follow the same rules as variable names.
349
+
350
+ Invalid configurations raise `ValueError` during load.
351
+
352
+ ---
353
+
354
+ ## 🧰 License
355
+
356
+ MIT License — Prompt Manager Contributors
357
+
358
+ ---
@@ -0,0 +1,332 @@
1
+ # Prompt Manager
2
+
3
+ A robust **Python utility** for loading, versioning, and managing prompt templates from YAML files or flat file directories.
4
+
5
+ Prompt Manager is designed to solve the problem of managing a **large, complex, and evolving library of prompts**. It allows you to compose prompts from reusable parts, manage versions (e.g., for A/B testing or model-specific tuning), and safely inject variables at runtime.
6
+
7
+ ---
8
+
9
+ ## 📚 Table of Contents
10
+
11
+ * [Core Features](#-core-features)
12
+ * [Installation](#-installation)
13
+ * [Quick Start](#-quick-start)
14
+ * [YAML Configuration Schema](#-yaml-configuration-schema)
15
+
16
+ * [Versioned Prompts (Recommended)](#1-versioned-prompts-recommended)
17
+ * [Simple Prompts (Non-versioned)](#2-simple-prompts-non-versioned)
18
+ * [Include Directives – {include prompt_name}](#3-include-directives--include-prompt_name)
19
+ * [Variable Placeholders – {variable_name}](#4-variable-placeholders--variable_name)
20
+ * [Loading from a Directory](#-loading-from-a-directory)
21
+ * [API Reference](#-api-reference)
22
+
23
+ * [Class: PromptManager](#class-promptmanager)
24
+ * [Class: Prompt](#class-prompt)
25
+ * [Advanced Usage Examples](#-advanced-usage-examples)
26
+
27
+ * [Example 1: Version A/B Testing](#example-1-version-ab-testing)
28
+ * [Example 2: Partial Formatting (Chain-of-Thought)](#example-2-partial-formatting-chain-of-thought)
29
+ * [Validation Rules](#-validation-rules)
30
+ * [Testing](#-testing)
31
+ * [License](#-license)
32
+
33
+ ---
34
+
35
+ ## 🚀 Core Features
36
+
37
+ * **Centralized Prompt Management:** Load all prompts from a single structured YAML file.
38
+ * **Fallback Directory Loading:** Optionally load simple prompts from a directory of `.txt` files.
39
+ * **Prompt Versioning:** Native support for versions (e.g., `v1`, `v2`) with a `_default` key.
40
+ * **Recursive Composition:** Build complex prompts from smaller, reusable components using `{include ...}` directives.
41
+ * **Safe Variable Substitution:** Format prompts with `{variable}` placeholders using a strict or non-strict API.
42
+ * **Partial Formatting:** Fill variables incrementally for chain-of-thought or multi-step prompt sequences.
43
+ * **Configuration Validation:** Validate prompt configurations at load time to catch errors early.
44
+
45
+ ---
46
+
47
+ ## 💾 Installation
48
+
49
+ ```bash
50
+ pip install prompt_template_manager
51
+ ```
52
+
53
+ ---
54
+
55
+ ## ⚡ Quick Start
56
+
57
+ ### 1. Create your `prompts.yaml` file
58
+
59
+ ```yaml
60
+ # prompts.yaml
61
+
62
+ system_persona:
63
+ _default: v2
64
+ _meta:
65
+ description: "The standard AI persona."
66
+ v1: "You are a helpful AI."
67
+ v2: "You are a helpful, concise, and polite AI assistant."
68
+
69
+ summarize_task:
70
+ _default: v1
71
+ v1: |
72
+ {include system_persona}
73
+
74
+ Your task is to summarize the following document into {num_sentences} sentences.
75
+ Document: {text}
76
+
77
+ Your summary:
78
+ ```
79
+
80
+ ### 2. Use `PromptManager` in your Python code
81
+
82
+ ```python
83
+ from source.PromptManager import PromptManager
84
+
85
+ try:
86
+ manager = PromptManager('prompts.yaml')
87
+ prompt = manager.get('summarize_task')
88
+
89
+ my_data = {
90
+ "num_sentences": 3,
91
+ "text": "The quick brown fox jumps over the lazy dog."
92
+ }
93
+
94
+ formatted_prompt = prompt.format(my_data)
95
+ print(formatted_prompt)
96
+
97
+ except FileNotFoundError:
98
+ print("Error: prompts.yaml not found.")
99
+ except (ValueError, KeyError) as e:
100
+ print(f"Error loading or getting prompt: {e}")
101
+ ```
102
+
103
+ **Output:**
104
+
105
+ ```
106
+ You are a helpful, concise, and polite AI assistant.
107
+
108
+ Your task is to summarize the following document into 3 sentences.
109
+ Document: The quick brown fox jumps over the lazy dog.
110
+
111
+ Your summary:
112
+ ```
113
+
114
+ ---
115
+
116
+ ## 🧩 YAML Configuration Schema
117
+
118
+ The `PromptManager` supports two main structures for defining prompts.
119
+
120
+ ### 1. Versioned Prompts (Recommended)
121
+
122
+ A “versioned prompt” is a dictionary containing:
123
+
124
+ * `_default` (Required): Default version key (e.g., `v1`).
125
+ * `v{number}` (Required): Version key(s) with prompt text.
126
+ * `_meta` (Optional): Arbitrary metadata.
127
+
128
+ **Example:**
129
+
130
+ ```yaml
131
+ system_persona_default:
132
+ _default: v2
133
+ _meta:
134
+ description: "The standard AI persona."
135
+ author: "Admin"
136
+ v1: "You are a helpful AI."
137
+ v2: "You are a helpful, concise, and polite AI assistant. You always answer the user's question directly."
138
+ ```
139
+
140
+ ---
141
+
142
+ ### 2. Simple Prompts (Non-versioned)
143
+
144
+ For simple, static prompts:
145
+
146
+ ```yaml
147
+ simple_greeting: "Hello, {name}. This is a simple, non-versioned prompt."
148
+ ```
149
+
150
+ > ⚠️ Not recommended for complex systems — lacks versioning, metadata, and include support.
151
+
152
+ ---
153
+
154
+ ### 3. Include Directives – `{include prompt_name}`
155
+
156
+ Compose prompts from other prompts:
157
+
158
+ ```yaml
159
+ system_persona:
160
+ _default: v1
161
+ v1: "You are a helpful AI."
162
+
163
+ output_format_json:
164
+ _default: v1
165
+ v1: "Your response MUST be a single, valid JSON object."
166
+
167
+ generate_user_profile:
168
+ _default: v1
169
+ _meta:
170
+ description: "Generates a JSON profile from a user's bio."
171
+ v1: |
172
+ {include system_persona}
173
+ {include output_format_json}
174
+
175
+ Analyze the following user bio and generate a profile.
176
+ Bio: {bio_text}
177
+ ```
178
+
179
+ Circular references (e.g., A includes B and B includes A) raise an **ImportError**.
180
+
181
+ ---
182
+
183
+ ### 4. Variable Placeholders – `{variable_name}`
184
+
185
+ * Any text enclosed in `{}` is treated as a variable.
186
+ * Variables are filled using `.format()` or `.partial()`.
187
+ * Variable names are validated on load.
188
+
189
+ ---
190
+
191
+ ## 📁 Loading from a Directory
192
+
193
+ You can also load prompts from a directory:
194
+
195
+ ```
196
+ my_txt_prompts/
197
+ ├── greet.txt
198
+ └── farewell.txt
199
+ ```
200
+
201
+ ```python
202
+ manager = PromptManager('my_txt_prompts/')
203
+ prompt = manager.get('greet')
204
+ ```
205
+
206
+ **Notes:**
207
+
208
+ * Only `.txt` files are loaded.
209
+ * Filenames become prompt names.
210
+ * Each prompt defaults to version `v1`.
211
+ * No support for metadata, includes, or multiple versions.
212
+
213
+ ---
214
+
215
+ ## 🧠 API Reference
216
+
217
+ ### **Class: `PromptManager`**
218
+
219
+ #### `__init__(self, source_path: str | Path)`
220
+
221
+ Loads and validates prompts from a YAML file or `.txt` directory.
222
+
223
+ **Raises:**
224
+ `FileNotFoundError`, `ValueError`, `yaml.YAMLError`
225
+
226
+ #### `get(self, name: str, version: int | None = None) -> Prompt`
227
+
228
+ Retrieves a fully resolved `Prompt` object.
229
+
230
+ **Raises:**
231
+ `KeyError`, `ValueError`, `ImportError`
232
+
233
+ ---
234
+
235
+ ### **Class: `Prompt`**
236
+
237
+ #### `format(self, data: dict, strict: bool = True) -> str`
238
+
239
+ Substitutes all variables.
240
+
241
+ #### `partial(self, data: dict) -> Prompt`
242
+
243
+ Partially fills variables, returning a new `Prompt`.
244
+
245
+ #### `get_raw_content(self) -> str`
246
+
247
+ Returns resolved, unformatted prompt text.
248
+
249
+ #### `get_variables(self) -> dict`
250
+
251
+ Lists remaining variable placeholders.
252
+
253
+ #### `get_meta(self) -> dict`
254
+
255
+ Returns the `_meta` dictionary (if any).
256
+
257
+ ---
258
+
259
+ ## ⚙️ Advanced Usage Examples
260
+
261
+ ### Example 1: Version A/B Testing
262
+
263
+ ```python
264
+ manager = PromptManager('prompts.yaml')
265
+
266
+ prompt_v2 = manager.get('system_persona')
267
+ prompt_v1 = manager.get('system_persona', version=1)
268
+
269
+ print(f"Default: {prompt_v2.get_raw_content()}")
270
+ print(f"V1: {prompt_v1.get_raw_content()}")
271
+ ```
272
+
273
+ **Output:**
274
+
275
+ ```
276
+ Default: You are a helpful, concise, and polite AI assistant.
277
+ V1: You are a helpful AI.
278
+ ```
279
+
280
+ ---
281
+
282
+ ### Example 2: Partial Formatting (Chain-of-Thought)
283
+
284
+ ```python
285
+ manager = PromptManager('prompts.yaml')
286
+ prompt = manager.get('summarize_task')
287
+
288
+ print(f"Original variables: {prompt.get_variables().keys()}")
289
+
290
+ partial_prompt = prompt.partial({
291
+ "text": "This is a long document about the history of computing."
292
+ })
293
+
294
+ print(f"Partial variables: {partial_prompt.get_variables().keys()}")
295
+ print("--- Partial Content ---")
296
+ print(partial_prompt.get_raw_content())
297
+
298
+ final_prompt_str = partial_prompt.format({
299
+ "num_sentences": 2
300
+ })
301
+
302
+ print("\n--- Final Content ---")
303
+ print(final_prompt_str)
304
+ ```
305
+
306
+ ---
307
+
308
+ ## ✅ Validation Rules
309
+
310
+ **Prompt Names**
311
+
312
+ * Must be valid Python identifiers (e.g., `my_prompt`, `_internal_prompt`).
313
+
314
+ **Variable Names**
315
+
316
+ * Must start with a letter.
317
+ * May include letters, numbers, `-`, and `_`.
318
+ * Cannot end with `-` or `_`.
319
+
320
+ **Include Names**
321
+
322
+ * Follow the same rules as variable names.
323
+
324
+ Invalid configurations raise `ValueError` during load.
325
+
326
+ ---
327
+
328
+ ## 🧰 License
329
+
330
+ MIT License — Prompt Manager Contributors
331
+
332
+ ---