Claude
Skills
Sign in
Back

angreal-integrations

Included with Lifetime
$97 forever

This skill should be used when the user asks to "use Git in a task", "manage virtual environments", "use Docker Compose", "use the Docker class", "run docker container from task", "list docker containers in angreal", "clone a repository", "create a venv", "run docker-compose", "use angreal.integrations", "render a template", "scaffold files", "generate files from template", "use render_template", "use render_directory", "use Flox", "flox environment", "cross-language environment", "flox services", "@flox_required", or needs guidance on the built-in Git, VirtualEnv, Docker (compose or low-level client), Flox, or Tera templating integrations available in angreal tasks.

Image & Video

What this skill does


# Angreal Integrations

Angreal provides built-in integrations for common development tools: Git, virtual environments, Docker Compose, Flox environments, and Tera templating.

## Tera Templating

Generate files and directories using the Tera template engine. Useful for scaffolding code, configs, or any structured files within tasks.

### Import

```python
import angreal
```

### render_template()

Render a template string with variable substitution:

```python
import angreal

# Simple variable substitution
template = "Hello {{ name }}!"
result = angreal.render_template(template, {"name": "World"})
# result == "Hello World!"

# With conditionals and loops
template = """
# {{ project_name }}

{% if use_docker %}
## Docker Setup
Run `docker-compose up` to start.
{% endif %}

## Dependencies
{% for dep in dependencies %}
- {{ dep }}
{% endfor %}
"""

result = angreal.render_template(template, {
    "project_name": "My App",
    "use_docker": True,
    "dependencies": ["requests", "click"]
})
```

**Signature**: `angreal.render_template(template: str, context: dict) -> str`

### render_directory()

Render an entire directory tree, processing both file contents and file/directory names:

```python
import angreal

# Source directory structure:
# templates/
#   {{ module_name }}/
#     __init__.py
#     {{ module_name }}.py

rendered_files = angreal.render_directory(
    "templates",           # src: source directory
    "output",              # dst: destination directory
    False,                 # force: overwrite existing files?
    {"module_name": "mymodule"}  # context: template variables
)

# Creates:
# output/
#   mymodule/
#     __init__.py
#     mymodule.py

print(f"Created {len(rendered_files)} files")

# Context is optional - copy without templating
angreal.render_directory("static_files", "output", False, None)
```

**Signature**: `angreal.render_directory(src: str, dst: str, force: bool, context: dict | None) -> list[str]`

Returns a list of created file paths.

### generate_context()

Load variables from a TOML file, optionally prompting the user:

```python
import angreal

# Load from TOML without prompting
context = angreal.generate_context("config.toml", take_input=False)

# Load and prompt user for values
context = angreal.generate_context("config.toml", take_input=True)
```

**Signature**: `angreal.generate_context(path: str, take_input: bool) -> dict`

### get_context()

Get the context from the current project's `.angreal/angreal.toml`:

```python
import angreal

# Returns dict from .angreal/angreal.toml or empty dict if not found
context = angreal.get_context()
project_name = context.get("project_name", "unknown")
```

**Signature**: `angreal.get_context() -> dict`

### Tera Syntax Quick Reference

```jinja2
{# Comments #}

{{ variable }}                    {# Variable substitution #}
{{ name | upper }}                {# Common filters: upper, lower, title, trim, capitalize #}
{{ path | replace(from="-", to="_") }} {# replace #}
{{ name | slugify }}              {# url-safe slug #}
{{ text | truncate(length=80) }}  {# truncate to N chars #}
{{ items | length }}              {# get length #}
{{ value | default(value="fallback") }} {# default if undefined #}

{% if condition %}                {# Conditionals #}
{% elif other %}
{% else %}
{% endif %}

{% for item in items %}           {# Loops #}
  {{ loop.index }}: {{ item }}
{% endfor %}

{% raw %}{{ not processed }}{% endraw %}  {# Escape template syntax #}
```

### Complete Scaffolding Example

```python
import angreal
import os

@angreal.command(name="scaffold", about="Generate a new module")
@angreal.argument(name="name", long="name", required=True, help="Module name")
@angreal.argument(name="with_tests", long="with-tests", is_flag=True, takes_value=False)
def scaffold(name, with_tests=False):
    project_root = angreal.get_root().parent

    # Template for module file
    module_template = '''"""{{ name }} module."""

class {{ name | title }}:
    """{{ description }}"""

    def __init__(self):
        pass
'''

    # Template for test file
    test_template = '''"""Tests for {{ name }}."""
import pytest
from {{ name }} import {{ name | title }}

def test_{{ name }}_init():
    instance = {{ name | title }}()
    assert instance is not None
'''

    context = {
        "name": name,
        "description": f"The {name} module"
    }

    # Create module
    module_content = angreal.render_template(module_template, context)
    module_path = os.path.join(project_root, "src", f"{name}.py")
    os.makedirs(os.path.dirname(module_path), exist_ok=True)
    with open(module_path, "w") as f:
        f.write(module_content)
    print(f"Created {module_path}")

    # Create test if requested
    if with_tests:
        test_content = angreal.render_template(test_template, context)
        test_path = os.path.join(project_root, "tests", f"test_{name}.py")
        os.makedirs(os.path.dirname(test_path), exist_ok=True)
        with open(test_path, "w") as f:
            f.write(test_content)
        print(f"Created {test_path}")

    return 0
```

## Git Integration

Full-featured Git wrapper for repository operations.

### Import

```python
from angreal.integrations.git import Git, clone
```

### Basic Usage

```python
from angreal.integrations.git import Git

# Initialize with working directory (default: current directory)
git = Git()
git = Git("/path/to/repo")

# All methods return (exit_code, stderr, stdout) tuples
exit_code, stderr, stdout = git.status()
```

### Git Class Methods

| Method | Signature | Description |
|--------|-----------|-------------|
| `init` | `init(bare=False)` | Initialize a new repository |
| `add` | `add(*paths)` | Stage files for commit |
| `commit` | `commit(message, all=False)` | Create a commit |
| `push` | `push(remote=None, branch=None)` | Push to remote |
| `pull` | `pull(remote=None, branch=None)` | Pull from remote |
| `status` | `status(short=False)` | Show working tree status |
| `branch` | `branch(name=None, delete=False)` | List or manage branches |
| `checkout` | `checkout(branch, create=False)` | Switch branches |
| `tag` | `tag(name, message=None)` | Create a tag |

### Callable Interface

The Git object is callable for arbitrary git commands:

```python
git = Git()

# Call any git command
exit_code, stderr, stdout = git("log", "--oneline", "-5")
exit_code, stderr, stdout = git("diff", "HEAD~1")
exit_code, stderr, stdout = git("stash", "pop")
```

### Clone Function

```python
from angreal.integrations.git import clone

# Clone a repository
path = clone("https://github.com/user/repo.git")
path = clone("https://github.com/user/repo.git", "/custom/destination")
```

### Complete Example

```python
import angreal
from angreal.integrations.git import Git

@angreal.command(name="release", about="Create a release")
@angreal.argument(name="version", long="version", required=True, help="Version tag")
def release(version):
    git = Git()

    # Check for clean working tree
    exit_code, stderr, stdout = git.status(short=True)
    if stdout.strip():
        print("Error: Working tree not clean")
        return 1

    # Create and push tag
    git.tag(version, message=f"Release {version}")
    git.push("origin", version)

    print(f"Released {version}")
    return 0
```

## VirtualEnv Integration

Manage Python virtual environments with automatic activation.

### Import

```python
from angreal.integrations.venv import VirtualEnv, venv_required
```

### Creating Virtual Environments

```python
from angreal.integrations.venv import VirtualEnv

# Create venv (default path: .venv, created immediately)
venv = VirtualEnv()

# Custom path
venv = VirtualEnv("/path/to/venv")

# Defer creation
venv = VirtualEnv(".venv", now=False)
venv.create()  # Create manually later

# With requirements
venv = VirtualEnv(".venv", requirements="requirements.txt")
venv = VirtualEnv(".venv", requirements=["requests", "click"])
```

### VirtualEnv Constructor

```python
VirtualE

Related in Image & Video