Skip to content

Python API

In addition to the command-line interface and the editor plugins, Viv ships a Python API to its compiler. Once you’ve installed the compiler, its Python API can be accessed by importing viv_compiler into your project, as seen in the usage examples below.

Compiles a Viv source file (.viv) into a content bundle.

compile_from_path(
source_file_path: Path,
*,
default_importance: float = config.DEFAULT_IMPORTANCE_SCORE,
default_salience: float = config.DEFAULT_SALIENCE_SCORE,
default_reaction_priority: float = config.DEFAULT_REACTION_PRIORITY_VALUE,
use_memoization: bool = True,
verbose_parser: bool = False,
) -> ContentBundle
  • source_file_path
    • Relative or absolute path to a .viv source file. This will be treated as the entry file, meaning the top-level file that pulls in all the others, directly or transitively, via include statements.
  • default_importance
    • Default importance for actions when unspecified.
  • default_salience
    • Default salience for actions when unspecified.
  • default_reaction_priority
  • use_memoization
    • Whether to enable memoization in the underlying PEG parser. Memoization makes parsing faster, but it uses more memory.
  • verbose_parser
    • Whether to engage a verbose debugging mode in the underlying PEG parser.

The compiled content bundle, as a JSON-serializable dict conforming to the ContentBundle schema. Typed definitions for this shape and its inner structures (e.g., ActionDefinition, PlanDefinition) are available via viv_compiler.external_types, for advanced use cases, but are not part of the stable public API.

  • VivParseError
    • The source file, or a file that it includes, could not be parsed.
  • VivCompileError
    • An issue occurred during compilation, but after parsing. Usually this is raised when a validation check discovers a problem.

Compiles a string containing Viv source code into a content bundle.

compile_from_string(
source_code: str,
*,
entry_dir: Path | None = None,
default_importance: float = config.DEFAULT_IMPORTANCE_SCORE,
default_salience: float = config.DEFAULT_SALIENCE_SCORE,
default_reaction_priority: float = config.DEFAULT_REACTION_PRIORITY_VALUE,
use_memoization: bool = True,
verbose_parser: bool = False,
) -> ContentBundle
  • source_code
    • A string containing (only) the Viv source code to compile.
  • entry_dir
    • Relative or absolute path to a directory that will be used for resolving any include paths in the source code. Defaults to the current working directory, and it can be ignored if source_code has no includes.
  • All other parameters are the same as compile_from_path().

Same as compile_from_path().

Same as compile_from_path().

Raised when a source file cannot be parsed.

class VivParseError(VivCompileError):
msg: str
file_path: Path
original: Exception
line: int | None
column: int | None
detail: str
  • msg
    • A brief message explaining the issue.
  • file_path
    • Absolute path to the file that failed to parse. This may be a file that was included in the source file, or one imported through a more complex include chain.
  • original
    • The underlying parser error.
  • line
    • Line number where the parse error occurred, if applicable.
  • column
    • Column number where the parse error occurred, if applicable.
  • detail
    • The full formatted diagnostic string. This is also what str(error) returns.

Raised when parsing succeeds but compilation still fails downstream, usually due to a failed validation check.

class VivCompileError(Exception):
msg: str
file_path: Path | None
line: int | None
column: int | None
end_line: int | None
end_column: int | None
code: str | None
detail: str
  • msg
    • A brief message explaining the issue.
  • file_path
    • Absolute path to the offending source file, if applicable.
  • line
    • Line number at the start of the offending source, if applicable.
  • column
    • Column number at the start of the offending source, if applicable.
  • end_line
    • Line number at the end of the offending source, if applicable.
  • end_column
    • Column number at the end of the offending source, if applicable.
  • code
    • The offending source code snippet, if applicable.
  • detail
    • The full formatted diagnostic string. This is also what str(error) returns.

Print out versions for the compiler, content-bundle schema, and DSL grammar associated with your installation:

import viv_compiler
print(f"Package: {viv_compiler.__version__}")
print(f"Schema: {viv_compiler.__schema_version__}")
print(f"Grammar: {viv_compiler.__grammar_version__}")

Compile a source file into a dictionary conforming to the ContentBundle shape:

from pathlib import Path
from viv_compiler import compile_from_path, VivCompileError, VivParseError
from viv_compiler.external_types import ContentBundle
try:
content_bundle: ContentBundle = compile_from_path(
source_file_path=Path("my-actions.viv")
)
print("Compilation succeeded:", content_bundle)
except VivParseError as e: # Handle first, because it's a subclass of VivCompileError
print(e)
except VivCompileError as e:
print(e)

Compile Viv source code directly from a string:

from viv_compiler import compile_from_string
source_code = """
action greet:
roles:
@greeter:
as: initiator
"""
bundle = compile_from_string(source_code)

Print out a parse error:

from pathlib import Path
from viv_compiler import compile_from_path, VivParseError
try:
compile_from_path(Path("hamlet.viv"))
except VivParseError as e:
print(e)
Source file could not be parsed:
- File: /Users/vivian/hamlet.viv
- Position: line 21, col 13
- Context (failed at *): ...queue [*]plot-reven...
- Viable next tokens: action, action-selector, plan, plan-selector

Print out a compile error:

from pathlib import Path
from viv_compiler import compile_from_path, VivCompileError
try:
compile_from_path(Path("hamlet.viv"))
except VivCompileError as e:
print(e)
Action 'greet' has no 'initiator' role (every action requires exactly one role labeled 'as: initiator')
/Users/vivian/hamlet.viv:14:1
action greet:
roles:
@greeter:
as: greeter

Inspect an error’s structured fields to build a custom diagnostic (e.g., for a CI reporter or editor integration):

from pathlib import Path
from viv_compiler import compile_from_path, VivCompileError
try:
compile_from_path(Path("hamlet.viv"))
except VivCompileError as e:
location = f"{e.file_path.name}:{e.line}:{e.column}" if e.file_path else "unknown"
print(f"[{location}] {e.msg}")
if e.code:
print()
for line in e.code.splitlines():
print(f" | {line}")