Metadata-Version: 2.5
Name: fsr_playbooks
Version: 0.6.59
Summary: FortiSOAR playbook authoring/compiler framework: YAML->FSR-JSON compiler, LLM co-authoring, and MCP server tools.
Project-URL: Homepage, https://github.com/ftnt-dspille/fsr-playbook-framework
Project-URL: Repository, https://github.com/ftnt-dspille/fsr-playbook-framework
Project-URL: Issues, https://github.com/ftnt-dspille/fsr-playbook-framework/issues
Author: Dylan Spille
License-Expression: MIT
License-File: LICENSE
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: jinja2>=3.1
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml>=6.0
Requires-Dist: ruamel-yaml>=0.18
Provides-Extra: llm
Requires-Dist: anthropic>=0.40; extra == 'llm'
Requires-Dist: httpx>=0.27; extra == 'llm'
Requires-Dist: openai>=1.0; extra == 'llm'
Provides-Extra: mcp
Requires-Dist: anthropic>=0.40; extra == 'mcp'
Requires-Dist: httpx>=0.27; extra == 'mcp'
Requires-Dist: mcp>=1.0; extra == 'mcp'
Requires-Dist: openai>=1.0; extra == 'mcp'
Description-Content-Type: text/markdown

# fsr_playbooks

A FortiSOAR **playbook authoring & compiler framework**:

- **Compiler** -- turn readable YAML into FortiSOAR playbook JSON (parser →
  resolver → validator → emitter), round-trip lossless with structured
  diagnostics.
- **Agent** -- LLM co-authoring helpers for building and triaging playbooks.
- **MCP server** -- tools that expose the compiler, connector/Jinja reference,
  and playbook authoring to MCP-compatible clients.

## Install

```bash
pip install fsr_playbooks            # base: compiler + agent
pip install "fsr_playbooks[llm]"     # + OpenAI / Anthropic providers
pip install "fsr_playbooks[mcp]"     # + MCP server (implies [llm])
```

Requires Python 3.10+.

## End-to-end: author → compile → deploy → run

### 1. Author a playbook in YAML

The compiler input is a readable collection of playbooks. A minimal one
(`start → set_variable → connector`):

```yaml
# hello_connector.yaml
collection: Compiler Demo
description: Smallest possible end-to-end -- start, set a variable, call a connector.
visible: true

playbooks:
  - name: Hello Connector
    description: Demonstrates start -> set_variable -> connector flow.
    steps:
      - name: Start
        type: start
        next: Prepare inputs

      - name: Prepare inputs
        type: set_variable
        next: Get organization
        vars:
          target_org: "Fortinet"

      - name: Get organization
        type: connector
        connector: fortinet-fortisiem
        operation: get_org_name_by_org_id
        config: ""
        params:
          domain_id: "{{ vars.target_org }}"
```

### 2. Compile it to FortiSOAR playbook JSON

```python
from pathlib import Path
from fsr_playbooks import compile_yaml

# The reference DB resolves connectors, operations, params, step types, and
# Jinja. It ships with the full framework repo (data/fsr_reference.db), NOT
# the PyPI wheel -- point this at your copy.
REFERENCE_DB = Path("data/fsr_reference.db")

text = Path("hello_connector.yaml").read_text()
result = compile_yaml(text, REFERENCE_DB)

if not result.ok:
    for err in result.errors:                       # structured, never raises
        print(f"[{err.severity}] {err.code}: {err.message}  ({err.path})")
    raise SystemExit("compile failed")

collection = result.fsr_json["data"][0]             # the FortiSOAR collection entity
```

`compile_yaml(text, db_path, lax_codes=None) -> CompileResult` returns a result
object with `.ok`, `.fsr_json` (`{"data": [collection]}`), `.errors`,
`.warnings`, and `.ir` (the parsed tree) -- it reports problems as structured
`CompileError`s rather than raising.

### 3. Deploy the collection to a FortiSOAR instance

Pushing and triggering talk to a live FortiSOAR REST API, so they use the
[`pyfsr`](https://pypi.org/project/pyfsr/) client (`pip install pyfsr`) -- this
package does the compiling, `pyfsr` does the transport.

```python
from pyfsr import FortiSOAR

client = FortiSOAR(
    base_url="https://your-fortisoar-host",
    auth="<api-key>",                  # or ("username", "password")
    verify_ssl=True,
)

# Push the compiled collection. The compiler-assigned uuid is preserved, so
# re-deploys can target it with client.workflow_collections.update(uuid, ...)
# / .delete(uuid).
client.workflow_collections.create(
    name=collection["name"],
    description=collection.get("description", ""),
    visible=collection.get("visible", True),
    uuid=collection["uuid"],
    workflows=collection["workflows"],     # full workflow objects (steps + routes)
    record_tags=collection.get("recordTags"),
)
```

### 4. Trigger the playbook and wait for it

```python
result = client.playbooks.run_and_wait("Hello Connector", inputs={})

print(result.status)          # 'finished' / 'failed' / 'terminated'
print(result.succeeded)        # True iff status == 'finished'
for step in result.steps:
    print(f"  {step.name:40} {step.status:10} {step.duration_ms or 0:6}ms")
if result.failure:
    print("failed at:", result.failure.failing_step, "-", result.failure.error_message)
```

> **What needs what:** step 2 (compile) is pure `fsr_playbooks` + the reference
> DB. Steps 3-4 (deploy/run) additionally need `pyfsr` and a reachable FortiSOAR
> instance. `run_and_wait` triggers, polls to terminal, and returns a typed
> `RunResult` with per-step timing and failure details in one call.

## Extras

| Extra    | Adds                              | Use for                          |
|----------|-----------------------------------|----------------------------------|
| (base)   | `pyyaml`, `ruamel.yaml`, `jinja2`, `pydantic` | YAML → FSR JSON compilation  |
| `[llm]`  | `openai`, `anthropic`, `httpx` | LLM-assisted authoring / triage  |
| `[mcp]`  | `mcp` (+ `[llm]`)             | running the MCP server tools      |

## License

MIT -- see [LICENSE](LICENSE).

## Links

- Source: https://github.com/ftnt-dspille/fsr-playbook-framework

> Note: the MCP server's live-execution / recipe tools depend on the reference
> store and probe helpers that ship with the full framework repo, not this
> package alone. The compiler, agent, and the rest of the MCP surface work
> standalone.
