Elegant Jinja2-based chat template parser for AI applications
Project description
🤖 Olingo LLM Parser
Elegant Jinja2-based chat template parser for AI applications
Transform your Jinja2 templates into structured chat conversations for OpenAI API spec. Perfect for OpenAI, Anthropic, and other chat-based language models.
✨ Features
- 🎯 Simple & Elegant: Clean syntax with custom
{% chat %}blocks - 🔧 Jinja2 Powered: Full support for variables, loops, conditionals
- 📋 Schema Integration: Automatic JSON schema loading for structured responses
- 🚀 AI Ready: Perfect for OpenAI, Anthropic, and other chat APIs
- 🎨 Flexible: Use anywhere - scripts, web apps, AI agents
- 📦 Minimal Dependencies: Just Jinja2, nothing else
🚀 Quick Start
Installation
pip install olingo-llm-parser
Basic Usage
1. Create a template (chat_template.jinja):
{% chat role="system" %}
You are a helpful AI assistant specializing in {{ domain }}.
{% endchat %}
{% chat role="user" %}
{{ user_question }}
{% endchat %}
2. Parse and use:
from olingo_llm_parser import parse_chat_template
# Parse template with variables
messages = parse_chat_template("chat_template.jinja", {
"domain": "data science",
"user_question": "What is machine learning?"
})
# Use with OpenAI
import openai
response = openai.chat.completions.create(
model="gpt-4",
messages=messages
)
Output:
[
{"role": "system", "content": "You are a helpful AI assistant specializing in data science."},
{"role": "user", "content": "What is machine learning?"}
]
🎨 Advanced Examples
With Loops and Conditions
{% chat role="system" %}
You are an expert {{ role }}.
{% endchat %}
{% for example in examples %}
{% chat role="user" %}
Example: {{ example.question }}
{% endchat %}
{% chat role="assistant" %}
{{ example.answer }}
{% endchat %}
{% endfor %}
{% chat role="user" %}
Now answer: {{ final_question }}
{% endchat %}
With JSON Schema
from olingo_llm_parser import parse_template_and_schema
# Parse both template and schema from files
messages, response_format = parse_template_and_schema(
template="template.jinja",
schema="response_schema.json",
variables={"topic": "AI"}
)
# Or use strings/dictionaries directly
template_string = """{% chat role="system" %}
You are an expert on {{ topic }}.
{% endchat %}"""
schema_dict = {"type": "object", "properties": {"answer": {"type": "string"}}}
messages, response_format = parse_template_and_schema(
template=template_string,
schema=schema_dict,
variables={"topic": "AI"}
)
# Use with OpenAI structured output
response = openai.chat.completions.create(
model="gpt-4",
messages=messages,
response_format=response_format # Automatic structured JSON
)
Schema-Aware Templates
Your templates can even reference the schema:
{% chat role="system" %}
Respond in JSON format following this schema:
{{ json_schema }}
{% endchat %}
{% chat role="user" %}
Generate data about {{ topic }}.
{% endchat %}
Flexible Input Types
The new parse_template_and_schema function supports multiple input formats:
from olingo_llm_parser import parse_template_and_schema
# Template as file path, schema as file path
messages, format = parse_template_and_schema("template.jinja", "schema.json")
# Template as string, schema as dictionary
template_str = """{% chat role="user" %}Hello!{% endchat %}"""
schema_dict = {"type": "string"}
messages, format = parse_template_and_schema(template_str, schema_dict)
# Template as string, schema as JSON string
schema_json = '{"type": "object", "properties": {"name": {"type": "string"}}}'
messages, format = parse_template_and_schema(template_str, schema_json)
# Template only (no schema)
messages, format = parse_template_and_schema(template_str) # format will be None
📚 API Reference
Core Functions
parse_chat_template(template, variables=None)
Parse a Jinja2 template containing {% chat %} blocks.
Parameters:
template(str|Path): Either a file path or template string contentvariables(dict, optional): Variables to pass to the template
Returns:
List[Dict[str, str]]: List of message dictionaries with 'role' and 'content'
load_json_schema(schema_path)
Load a JSON schema and format it for AI APIs.
Parameters:
schema_path(str): Path to your JSON schema file
Returns:
Dict: Formatted response_format for AI APIs
parse_template_and_schema(template, schema=None, variables=None)
Parse both template and schema together with flexible input types.
Parameters:
template(str|Path): Either a file path or template string contentschema(str|Path|Dict, optional): Either a file path, JSON string, or schema dictionaryvariables(dict, optional): Variables to pass to the template
Returns:
Tuple[List[Dict], Dict]: (messages, response_format) ready for AI APIs
🏗️ Template Syntax
Chat Blocks
{% chat role="system" %}
Your system message here
{% endchat %}
{% chat role="user" %}
Your user message here
{% endchat %}
{% chat role="assistant" %}
Your assistant message here
{% endchat %}
Variables
{% chat role="user" %}
Hello {{ name }}, tell me about {{ topic }}.
{% endchat %}
Loops
{% for item in items %}
{% chat role="user" %}
Process this: {{ item }}
{% endchat %}
{% endfor %}
Conditionals
{% chat role="system" %}
{% if expert_mode %}
You are an expert assistant with advanced capabilities.
{% else %}
You are a helpful general assistant.
{% endif %}
{% endchat %}
🎯 Use Cases
- AI Chat Applications: Structure conversations for any chat API
- Prompt Engineering: Create reusable, dynamic prompt templates
- AI Agents: Build complex conversational flows
- Data Generation: Generate structured training data
- API Integration: Seamless integration with OpenAI, Anthropic, etc.
🤝 Why Choose Olingo LLM Parser?
| Feature | Olingo LLM Parser | Manual String Building | Other Solutions |
|---|---|---|---|
| Readability | ✅ Clean template syntax | ❌ Messy string concat | ⚠️ Complex APIs |
| Maintainability | ✅ Separate logic & content | ❌ Mixed code/content | ⚠️ Vendor lock-in |
| Flexibility | ✅ Full Jinja2 power | ❌ Limited logic | ⚠️ Restricted features |
| AI Integration | ✅ Perfect API format | ❌ Manual formatting | ⚠️ API-specific |
| Schema Support | ✅ Built-in JSON schema | ❌ No schema support | ❌ No schema support |
📋 Requirements
- Python 3.8+
- Jinja2 3.0+
🛠️ Development
# Clone repository
git clone https://github.com/ollsoft-ai/olingo-llm-parser.git
cd olingo-llm-parser
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black .
isort .
📦 Building and Publishing New Versions
1. Update Version Number
🎯 Recommended: Automated Version Bumping
We use bump2version for automated version management:
# Install bump2version (one-time setup)
pip install bump2version
# Bump patch version (0.1.2 → 0.1.3)
bump2version patch
# Bump minor version (0.1.3 → 0.2.0)
bump2version minor
# Bump major version (0.2.0 → 1.0.0)
bump2version major
This automatically:
- ✅ Updates version in
olingo_llm_parser/__init__.py - ✅ Creates a git commit with the version bump
- ✅ Creates a git tag (e.g.,
v0.1.3) - ✅ Single source of truth (version only in
__init__.py)
Manual Alternative:
If you prefer manual updates, just edit the version in olingo_llm_parser/__init__.py:
__version__ = "0.1.3" # Update this line only
Semantic Versioning Guidelines:
- Patch (0.1.1 → 0.1.2): Bug fixes, no breaking changes
- Minor (0.1.2 → 0.2.0): New features, backward compatible
- Major (0.2.0 → 1.0.0): Breaking changes
2. Install Build Tools
pip install build twine
3. Run Tests
Make sure all tests pass before publishing:
python -m pytest -v
4. Clean Previous Builds
# PowerShell (Windows)
Remove-Item -Recurse -Force dist, build, *.egg-info -ErrorAction SilentlyContinue
# Bash (Linux/Mac)
rm -rf dist/ build/ *.egg-info/
5. Build the Package
python -m build
This creates two files in dist/:
olingo-llm-parser-X.X.X.tar.gz(source distribution)olingo_llm_parser-X.X.X-py3-none-any.whl(wheel distribution)
7. Upload to PyPI
Once verified on TestPyPI:
python -m twine upload dist/*
8. Tag the Release
git add .
git commit -m "chore: bump version to X.X.X"
git tag vX.X.X
git push origin main --tags
🔐 PyPI Authentication
Option A: API Token (Recommended)
- Go to PyPI Account Settings
- Create an API token
- Use
__token__as username and your token as password
Option B: Configure ~/.pypirc
[pypi]
username = __token__
password = pypi-your-token-here
[testpypi]
username = __token__
password = pypi-your-testpypi-token-here
📄 License
MIT License - see LICENSE file for details.
Made with ❤️ by the Ollsoft Team
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file olingo_llm_parser-0.1.6.tar.gz.
File metadata
- Download URL: olingo_llm_parser-0.1.6.tar.gz
- Upload date:
- Size: 14.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13a06915f4f18a6146938e707b0ed2bbb1cd3ac35b513a256acbdb3d73922ad9
|
|
| MD5 |
9c1f2de71b7667031be7fef82eeb12c0
|
|
| BLAKE2b-256 |
57cf4dbfd405a48a8b74d5bb2f3545847b3aa96e519d249797b53c924857ef62
|
File details
Details for the file olingo_llm_parser-0.1.6-py3-none-any.whl.
File metadata
- Download URL: olingo_llm_parser-0.1.6-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ef4e8abb5724cd9b130ce9efb33be22c1381ca366a9d44379fdfc8439067e7d
|
|
| MD5 |
13321cba9cf8bbb65fb1db5de8a448f0
|
|
| BLAKE2b-256 |
25fea3756da6ab17edb3451db0919fe5a3a8fd2ce48a542c1f0a53502a4cb2fc
|