Template Rendering
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
Template Rendering
Section titled “Template Rendering”Open Ticket AI uses template rendering to make configurations dynamic and adaptable to different environments and runtime conditions. This allows you to customize behavior without changing code.
What is Template Rendering?
Section titled “What is Template Rendering?”Template rendering processes special placeholders in your configuration files, replacing them with actual values at runtime. This enables:
- Using environment variables in configs
- Referencing results from previous pipeline steps
- Conditional logic based on context
- Dynamic service configurations
Jinja2 Templates
Section titled “Jinja2 Templates”Open Ticket AI uses Jinja2, a powerful templating engine for Python. Jinja2 provides:
- Variable substitution:
{{ variable }} - Conditional blocks:
{% if condition %}...{% endif %} - Loops:
{% for item in list %}...{% endfor %} - Filters:
{{ value | filter }}
For complete Jinja2 documentation, visit the official Jinja2 site.
Custom Template Helpers
Section titled “Custom Template Helpers”In addition to standard Jinja2 features, Open Ticket AI provides custom helper functions that expose runtime data to templates.
get_env(env_name)
Section titled “get_env(env_name)”Reads the value of an environment variable. Rendering fails if the variable is not defined, ensuring required values are provided.
params: api_key: "{{ get_env('API_KEY') }}" timeout_seconds: "{{ get_env('TIMEOUT_SECONDS') | int }}"get_pipe_result(pipe_id, data_key='value')
Section titled “get_pipe_result(pipe_id, data_key='value')”Retrieves a value from a previously executed pipe. Pipe results are stored as dictionaries; use data_key to select a
specific entry. The helper raises a render error if the key does not exist.
params: classification: "{{ get_pipe_result('classify') }}" # reads the default `value` confidence: "{{ get_pipe_result('classify', 'confidence') }}"has_failed(pipe_id)
Section titled “has_failed(pipe_id)”Returns True when the referenced pipe completed execution unsuccessfully (and was not skipped).
if: "{{ not has_failed('fetch_ticket') }}"at_path(data, path)
Section titled “at_path(data, path)”Traverses nested dictionaries or Pydantic models using dot notation.
params: requester_email: "{{ at_path(ticket, 'metadata.requester.email') }}"get_parent_param(param_key)
Section titled “get_parent_param(param_key)”Makes parameters from a parent context available to nested (composite) pipes. When no parent parameter is present or when the key is missing, rendering fails so configuration issues surface early.
params: expression: "{{ get_parent_param('threshold') * 100 }}"fail()
Section titled “fail()”Creates a special marker recognised by the Expression pipe. Returning this marker allows a template expression to explicitly fail a pipe instead of raising an exception.
expression: '{{ fail() if confidence < 0.6 else result }}'Template Context
Section titled “Template Context”Templates receive a context dictionary that varies with the rendering stage. The keys appear directly in the template
(global objects do not require a context. prefix).
Global Context (Always Available)
Section titled “Global Context (Always Available)”- Jinja helpers such as
get_env,get_pipe_result, andat_path - Configuration values passed explicitly in the render call
Pipeline Context
Section titled “Pipeline Context”When rendering pipeline-level configuration:
params: Pipeline parameters defined inorchestrator.pipelines[].paramspipe_results: Historical execution results keyed by pipe ID, when available
Pipe Context
Section titled “Pipe Context”When rendering individual pipes during execution:
params: Parameters passed to the current pipepipe_results: Results from previously executed pipes in the same pipelineparent_params: Parameters from the parent pipe (if the pipe is nested)
Parent parameters are now populated automatically for nested pipelines, so composite pipes can coordinate with their
children using get_parent_param() or by reading from parent_params directly. Service instances are not injected
into templates at this time. We plan to explore service injection in the future, but this documentation reflects the currently
implemented behaviour.
When Rendering Happens
Section titled “When Rendering Happens”Different parts of your configuration are rendered at different times:
Service Instantiation
Section titled “Service Instantiation”Services in the services section are rendered when the application starts, before any pipelines run. They have access
only to the global context provided for service creation.
Pipeline Creation
Section titled “Pipeline Creation”Pipeline definitions are rendered when pipelines are created. They have access to global context, pipeline parameters, and (when available) previous pipeline results.
Pipe Execution
Section titled “Pipe Execution”Individual pipes are rendered just before execution. They have access to global data, pipeline-level parameters, previous pipe results, and parent parameters if the pipe is nested.
What Gets Rendered
Section titled “What Gets Rendered”Template rendering applies to string values in these configuration sections:
Services
Section titled “Services”paramsvaluesinjectskeys and values
Orchestrator
Section titled “Orchestrator”pipelines[].paramsvaluespipelines[].pipes[].paramsvaluespipelines[].pipes[].ifconditionspipelines[].pipes[].depends_onlists
- All parameter values
- Conditional expressions
- Dependency specifications
The template renderer configuration itself (
infrastructure.template_renderer_config) is never rendered—it is used as raw input to bootstrap the rendering system. Rendering this configuration would create a circular dependency, since it is needed to initialize the renderer itself.
Examples
Section titled “Examples”Using Environment Variables
Section titled “Using Environment Variables”services: - id: api_client use: 'mypackage:APIClient' params: base_url: "{{ get_env('API_BASE_URL') }}" api_key: "{{ get_env('API_KEY') }}"Pipeline Parameters
Section titled “Pipeline Parameters”orchestrator: pipelines: - name: process_tickets params: threshold: 0.8 pipes: - id: classify use: 'mypackage:Classifier' params: confidence_threshold: '{{ params.threshold }}'Pipe Dependencies
Section titled “Pipe Dependencies”pipes: - id: fetch_data use: 'mypackage:Fetcher'
- id: process_data use: 'mypackage:Processor' params: input: "{{ get_pipe_result('fetch_data') }}" depends_on: [fetch_data] if: "{{ not has_failed('fetch_data') }}"Using Parent Parameters in a Composite Pipe
Section titled “Using Parent Parameters in a Composite Pipe”pipes: - id: composite use: 'mypackage:Composite' params: threshold: 0.75 steps: - id: evaluate use: 'mypackage:Expression' params: expression: "{{ get_parent_param('threshold') > 0.7 }}"Explicitly Failing a Pipe
Section titled “Explicitly Failing a Pipe”pipes: - id: evaluate use: 'mypackage:Expression' params: expression: "{{ fail() if get_pipe_result('validate', 'score') < 0.5 else 'ok' }}"Best Practices
Section titled “Best Practices”- Use environment variables for secrets and environment-specific values
- Prefer
get_env()over directly readingos.environfor better error messages - Keep templates simple and readable
- Test your templates with different context values
- Avoid complex logic in templates—prefer configuration over code