Skip to main content

A framework for safety-critical operations with audit trails, locking, and approval workflows

Project description

Safeline

A Python framework for building safety-critical operations with arbitrary stage pipelines, audit trails, locking, and approval workflows.

Why Safeline?

When building tools that perform critical operations (deployments, data migrations, infrastructure changes), you need:

  • Structured workflows - Break complex operations into reviewable stages
  • Audit trails - Know who did what, when, and why
  • Approval gates - Require sign-off before dangerous actions
  • Rollback support - Undo operations when things go wrong
  • Environment awareness - Different rules for prod vs dev

Safeline provides the infrastructure so you can focus on your domain logic.

Installation

pip install sfln

# With optional dependencies
pip install sfln[cli]      # CLI support (click)
pip install sfln[yaml]     # YAML config (pyyaml)
pip install sfln[all]      # All optional deps

Quick Example

Safeline recommends a standard stage pattern for safety-critical operations:

plan -> validate -> stage -> apply -> verify
  • plan - Analyze what will be done, calculate risk
  • validate - Check preconditions, ensure operation is safe to proceed
  • stage - Prepare resources, create backups (reversible)
  • apply - Execute the actual change (requires approval in production)
  • verify - Confirm the operation succeeded
from sfln import Operation, Stage, StageResult, Context, Safeline, MemoryStore

class DeployOperation(Operation):
    name = "deploy"
    stages = [
        Stage("plan"),
        Stage("validate"),
        Stage("stage", reversible=True),
        Stage("apply", needs_approval=True, reversible=True),
        Stage("verify"),
    ]

    def plan(self, context: Context) -> StageResult:
        # Analyze what will be deployed
        return StageResult(data={"targets": context.targets, "version": "2.0.0"})

    def validate(self, context: Context) -> StageResult:
        # Check preconditions
        return StageResult(data={"valid": True})

    def stage(self, context: Context) -> StageResult:
        # Create backup before changes
        backup_id = create_backup()
        return StageResult(
            data={"backup_id": backup_id},
            rollback_data={"backup_id": backup_id}
        )

    def apply(self, context: Context) -> StageResult:
        # Execute the deployment
        version = context.get_stage_result("plan")["version"]
        return StageResult(data={"deployed": version})

    def verify(self, context: Context) -> StageResult:
        # Confirm deployment succeeded
        return StageResult(data={"healthy": True})

    def rollback_stage(self, context: Context) -> StageResult:
        return StageResult(data={"cleaned": True})

    def rollback_apply(self, context: Context) -> StageResult:
        backup_id = context.get_stage_result("stage")["backup_id"]
        restore_from_backup(backup_id)
        return StageResult(data={"restored": True})

# Run it
sl = Safeline(store=MemoryStore())
result = sl.run(DeployOperation(targets=["app-server-1"]))
print(f"Success: {result.success}")

Custom Stages

The standard stages are a recommendation, not a requirement. Define whatever stages make sense for your operation:

# Database migration with custom stages
stages = [
    Stage("analyze"),
    Stage("backup_schema"),
    Stage("migrate", needs_approval=True),
    Stage("verify_data"),
    Stage("cleanup"),
]

# Simple file operation
stages = [
    Stage("scan"),
    Stage("execute"),
]

Key Features

Standard Stage Pattern

The recommended pattern for safety-critical operations:

stages = [
    Stage("plan"),                                    # Analyze
    Stage("validate"),                                # Check preconditions
    Stage("stage", reversible=True),                  # Prepare/backup
    Stage("apply", needs_approval=True, reversible=True),  # Execute
    Stage("verify"),                                  # Confirm success
]

Per-Stage Controls

Each stage can have its own requirements:

Stage(
    name="apply",
    required=True,           # Operation fails if this fails
    needs_approval=True,     # Must be approved first
    needs_lock=True,         # Exclusive lock during execution
    reversible=True,         # Can be rolled back
    timeout_seconds=300,     # Max execution time
)

Audit Trail

All operations automatically emit events:

sl = Safeline(
    store=MemoryStore(),
    auditor=AuditStoreClient(url="http://audit-store:8080"),
)

Events: operation_created, stage_started, stage_completed, approval_granted, lock_acquired, etc.

Environment-Aware Protection

from sfln import get_protection_level

level = get_protection_level("production")
# level.require_approval = True
# level.require_backup = True
# level.allow_force = False

Development

# Setup
make quickstart
source .venv/bin/activate

# Test
make test

# Code quality
make check
make format

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sfln-0.1.14.tar.gz (84.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sfln-0.1.14-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

File details

Details for the file sfln-0.1.14.tar.gz.

File metadata

  • Download URL: sfln-0.1.14.tar.gz
  • Upload date:
  • Size: 84.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for sfln-0.1.14.tar.gz
Algorithm Hash digest
SHA256 8b2d6ea0eb87516d14a22c2ef027e9b0635d2ffbf0f2e328935b0b67bb6f1736
MD5 825427dde5cf6cf464ba0e556433f145
BLAKE2b-256 73694433c844fdaa72fe13d44c5ada28c88d2e976e0fc00bf4970bc27624ddbe

See more details on using hashes here.

File details

Details for the file sfln-0.1.14-py3-none-any.whl.

File metadata

  • Download URL: sfln-0.1.14-py3-none-any.whl
  • Upload date:
  • Size: 72.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for sfln-0.1.14-py3-none-any.whl
Algorithm Hash digest
SHA256 f499550e80931bb5112c213b90edc6088bb7494c8536a82ff99115c8f9c09f3f
MD5 27e7309d372d86e4a438e8f5752aa687
BLAKE2b-256 06b7248ee6d76d7461559fb945f0cbb709109dc2c00d79812b352ac51a0760db

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page