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 |
|---|---|
|
Type implementations for enum, struct, concept, club |
|
DSM definitions, paths, fields |
Persistence¶
Template |
Purpose |
|---|---|
|
Attachment accessors |
|
SQLite persistence layer |
Serialization¶
Template |
Purpose |
|---|---|
|
Binary encoder/decoder |
|
JSON encoder/decoder |
|
Bridge between static C++ and dynamic Viper values |
|
Content hashing for values |
|
Viper type mappings |
Function Pools¶
Template |
Purpose |
|---|---|
|
Pure function bindings |
|
Remote function call API |
|
Stateful function bindings |
|
Remote stateful calls |
|
Pool exposing attachment API |
Python Integration¶
Template |
Purpose |
|---|---|
|
Python module constants for types and paths |
Testing¶
Template |
Purpose |
|---|---|
|
Random value generation |
|
Unit tests for fuzzing, JSON, streaming, storing |
|
Test application entry points |
Python Template Categories¶
Templates in templates/python/package/:
Template |
Generated File |
Purpose |
|---|---|---|
|
|
Package initialization |
|
|
Type definitions for Viper |
|
|
Classes for concepts, clubs, enums, structures |
|
|
Attachment API wrappers |
|
|
Database attachment API wrappers |
|
|
Field path constants |
|
|
Dynamic type definitions |
|
|
Function pool wrappers |
|
|
Stateful pool wrappers |
|
|
Remote function call wrappers |
|
|
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 |
|
DSMDefinitions |
Encode |
dsviper |
DSMDefinitions |
|
Generate |
Kibo |
|
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.