Rust-Python Interface
This page explains how the Rust core and Python interface interact in Angreal.
Angreal is primarily implemented in Rust, with Python providing a convenient interface through PyO3 bindings. The main components include:
- Command Registration - Python decorators register tasks with the Rust command system
- Argument Parsing - Rust code processes command-line arguments and passes them to Python
- Template Rendering - Rust’s Tera templating engine handles all template operations
When you create a command in Python:
@angreal.command(name='hello', about='Say hello')
@angreal.argument(name='name', long='name', takes_value=True, help='Name to greet')
def hello(name='World'):
print(f"Hello, {name}!")
The following happens under the hood:
- The
@command
decorator calls a Rust function that registers the command metadata - The
@argument
decorator registers argument metadata with the command - When executed, Rust parses the command-line arguments and calls the Python function
-
Command Registration
- Python decorators call Rust functions through PyO3
- Command and argument metadata is stored in Rust data structures
-
Function Calls
- Python functions are bound to Rust functions
- Python values are converted and passed to Rust
-
Logging
- Python logging messages are sent to a Rust subscriber for unified logging
- Command Execution
- Rust loads Python task files and executes decorated functions
- Arguments are converted from Rust types to Python
The Rust-Python interface is implemented in several key files:
src/task.rs
- Command registration and executionsrc/builder/command_tree.rs
- Command-line argument processingsrc/lib.rs
- PyO3 module registration and core functionalitysrc/utils.rs
- Template rendering and file operationssrc/git.rs
- Git operationssrc/init.rs
- Template initialization and project setup
Each Python function decorated with @command
is stored in a global registry in Rust, which is used to build the command-line interface and execute commands. The Python interface primarily serves as a convenient way to interact with Angreal’s Rust core functionality.