Templated Features

Templated features are code templates that Kibo uses to generate infrastructure code from DSM definitions.

Understanding Templates

A templated feature is like a code snippet that expands based on your DSM model. Kibo consumes DSM definitions and generates code using StringTemplate files (.stg).

DSM Model + Template → Generated Code

C++ Template Categories

Templates in templates/cpp/ are organized by feature:

Core Types

Template

Purpose

Data

Type implementations for enum, struct, concept, club

Model

DSM definitions, paths, fields

Persistence

Template

Purpose

Attachments

Attachment accessors

Database

SQLite persistence layer

Serialization

Template

Purpose

Stream

Binary encoder/decoder

Json

JSON encoder/decoder

ValueCodec

Bridge between static C++ and dynamic Viper values

ValueHasher

Content hashing for values

ValueType

Viper type mappings

Function Pools

Template

Purpose

FunctionPool

Pure function bindings

FunctionPoolRemote

Remote function call API

AttachmentFunctionPool

Stateful function bindings

AttachmentFunctionPoolRemote

Remote stateful calls

AttachmentFunctionPool_Attachments

Pool exposing attachment API

Python Integration

Template

Purpose

Python

Python module constants for types and paths

Testing

Template

Purpose

Fuzz

Random value generation

Test

Unit tests for fuzzing, JSON, streaming, storing

TestApp

Test application entry points

Python Template Categories

Templates in templates/python/package/:

Template

Generated File

Purpose

__init__.py

__init__.py

Package initialization

definitions

definitions.py

Type definitions for Viper

data

data.py

Classes for concepts, clubs, enums, structures

attachments

attachments.py

Attachment API wrappers

database_attachments

database_attachments.py

Database attachment API wrappers

path

path.py

Field path constants

value_type

value_type.py

Dynamic type definitions

function_pools

function_pools.py

Function pool wrappers

attachment_function_pools

attachment_function_pools.py

Stateful pool wrappers

function_pool_remotes

function_pool_remotes.py

Remote function call wrappers

attachment_function_pool_remotes

attachment_function_pool_remotes.py

Remote stateful call wrappers

Generation Workflow

1. Prepare Binary Definitions

from dsviper import DSMBuilder

builder = DSMBuilder.assemble("model.dsm")
report, dsm_defs, definitions = builder.parse()

# Save binary format for Kibo
with open("model.dsmb", "wb") as f:
    f.write(dsm_defs.encode().encoded())

2. Generate Embedded Resource

# For C++ Model/Definitions.cpp
blob = definitions.encode()
with open("Resources.hpp", "w") as f:
    f.write(blob.embed("definitions"))

3. Call Kibo

import subprocess


def generate(namespace, dsmb_path, template, output):
    subprocess.run([
        'java', '-jar', 'tools/kibo-1.2.0.jar',
        '-c', 'cpp',
        '-n', namespace,
        '-d', dsmb_path,
        '-t', f'templates/cpp/{template}',
        '-o', output
    ])


# Generate all features
templates = ['Model', 'Data', 'Attachments', 'Stream', 'Json', 'Database']
for t in templates:
    generate('MyApp', 'model.dsmb', t, 'src/MyApp')

4. Generate Python Package

import subprocess
import base64
import zlib


def generate_package(name, dsmb_path, definitions, output):
    # Generate Python files
    subprocess.run([
        'java', '-jar', 'tools/kibo-1.2.0.jar',
        '-c', 'python',
        '-n', name,
        '-d', dsmb_path,
        '-t', 'templates/python/package',
        '-o', output
    ])

    # Generate embedded definitions
    blob = definitions.encode()
    encoded = base64.b64encode(zlib.compress(blob.encoded()))
    with open(f'{output}/resources.py', 'w') as f:
        f.write(f"B64_DEFINITIONS = {encoded}")

Selecting Features

You don’t need all templates. Select based on your needs:

Minimal (Data Only)

templates = ['Data']  # Just type classes

Persistence

templates = ['Model', 'Data', 'Attachments', 'Database']

Full Stack

templates = [
    'Model', 'Data',
    'Stream', 'Json',
    'Attachments', 'Database',
    'ValueType', 'ValueCodec', 'ValueHasher',
    'FunctionPool', 'AttachmentFunctionPool'
]

With Testing

templates = [..., 'Fuzz', 'Test', 'TestApp']

Example: generate.py

A typical project has a generate.py script:

#!/usr/bin/env python3
import subprocess
from dsviper import DSMBuilder

NAMESPACE = "MyApp"
DSM_PATH = "definitions/model.dsm"
DSMB_PATH = "build/model.dsmb"
OUTPUT = "src/generated"

# Parse and encode
builder = DSMBuilder.assemble(DSM_PATH)
report, dsm_defs, defs = builder.parse()
with open(DSMB_PATH, "wb") as f:
    f.write(dsm_defs.encode().encoded())

# Generate C++
for template in ['Model', 'Data', 'Attachments', 'Database']:
    subprocess.run([
        'java', '-jar', 'tools/kibo-1.2.0.jar',
        '-c', 'cpp', '-n', NAMESPACE,
        '-d', DSMB_PATH,
        '-t', f'templates/cpp/{template}',
        '-o', OUTPUT
    ])

# Generate Python package
subprocess.run([
    'java', '-jar', 'tools/kibo-1.2.0.jar',
    '-c', 'python', '-n', 'myapp',
    '-d', DSMB_PATH,
    '-t', 'templates/python/package',
    '-o', 'python/myapp'
])

print("Generation complete!")

Summary

Step

Tool

Input

Output

Parse

dsviper

.dsm

DSMDefinitions

Encode

dsviper

DSMDefinitions

.dsmb

Generate

Kibo

.dsmb + templates

C++/Python code

Compile

CMake/pip

Generated code

Binary/wheel

Templates let you generate exactly the infrastructure you need, from minimal type definitions to full-stack persistence with RPC.