Skip to main content
Operations are the core of pyinfra. The @operation decorator intercepts function calls and generates commands to execute on remote servers, rather than executing directly.

@operation Decorator

The @operation decorator converts a Python function into a pyinfra operation that generates commands.

Parameters

bool
default:true
Whether the operation is idempotent (can be run multiple times safely).
str
Custom message to display about idempotency.
bool
default:false
Mark the operation as deprecated.
str
Suggest an alternative operation to use instead.

Operation Functions

Operation functions are generators that yield commands:

Command Types

Operations can yield several types of commands:

String Commands

StringCommand Objects

File Operations

Python Functions

OperationMeta Class

When you call an operation, it returns an OperationMeta object that tracks the operation’s state:

Properties

bool
Whether the operation has executed and ran commands.
bool
Whether the operation will make changes (checked during prepare phase).
list[str]
List of stdout lines from executed commands.
list[str]
List of stderr lines from executed commands.
str
Combined stdout from all commands.
str
Combined stderr from all commands.
int
Number of retry attempts made.
bool
Whether the operation was retried.

Methods

bool
Returns True if the operation completed successfully.
bool
Returns True if the operation made changes.
bool
Returns True if the operation did not make changes.
bool
Returns True if the operation failed.
dict
Returns dictionary with retry information.

add_op Function

add_op() programmatically adds an operation to the state. This should only be used in API mode.

Example

Conditional Operations

Use facts to make operations conditional:

Complete Example

Here’s a complete custom operation:

Source Reference

Location: src/pyinfra/api/operation.py:240

Key Classes & Functions

  • operation() - Decorator to create operations (line 240)
  • OperationMeta - Tracks operation state (line 43)
  • add_op() - Add operation to state (line 206)
  • _wrap_operation() - Internal operation wrapper (line 263)