Skip to main content

Overview

Facts are pyinfra’s mechanism for collecting information about target hosts. They enable idempotent operations by allowing you to check the current state before making changes. Every fact runs a command on the target host, processes the output, and returns structured data.
Facts are the foundation of idempotent infrastructure management. Always use facts to check state rather than assuming what exists on target hosts.

The FactBase Class

All facts inherit from the FactBase class (defined in src/pyinfra/api/facts.py):

Key Components

  1. command: Method that returns the shell command to execute
  2. process: Method that transforms command output into structured data
  3. default: Static method returning the default value on failure
  4. requires_command: Optional command dependency check

Creating Facts

Simple Fact Example

A basic fact that returns a single string:

Fact with Parameters

Facts can accept parameters to customize behavior:
Usage:

Complex Fact with Processing

Facts that parse structured output:

Fact with Dependencies

Facts that require specific commands to be available:

Using Facts

Getting Facts from Host

Facts are retrieved using host.get_fact():

Fact Return Values

Facts can return different types of values:

None (doesn’t exist)

False (exists but wrong type)

Data (exists)

In Operations

Facts are commonly used in operations for idempotency:

Fact Collection Process

The get_fact function (from src/pyinfra/api/facts.py:169-327) handles fact collection:

Fact Execution Flow

Built-in Facts

pyinfra includes comprehensive built-in facts:

Server Facts

File Facts

Package Facts

System Facts

Service Facts

Network Facts

ShortFacts

ShortFacts are convenience facts that wrap other facts:
Example ShortFact:

Fact Caching

Facts are automatically cached per host during execution:
Fact caching improves performance but means facts show state at collection time. Re-running the same fact with the same parameters returns cached data.

Fact Arguments

Facts can use connector arguments to modify execution:

Getting Facts for All Hosts

Collect facts from all hosts in parallel:

Custom Fact Examples

Parsing JSON Output

Parsing Structured Text

Parsing CSV Output

Conditional Fact

Fact Error Handling

Handling Missing Commands

Use requires_command to gracefully handle missing dependencies:

Handling Process Errors

Raise FactProcessError for processing failures:

Using _ignore_errors

Fact Execution Context

Facts respect the current operation context:

Performance Considerations

Fact Overhead

Each fact requires:
  • One SSH connection (if not connected)
  • One command execution
  • Output transfer over network
  • Processing on control machine

Optimization Strategies

Minimize Fact Calls

Cache fact results in variables rather than calling repeatedly.

Use Broad Facts

Prefer facts that return multiple values (e.g., File returns all metadata) over multiple narrow facts.

Parallel Collection

Use get_facts() to collect from all hosts in parallel.

Conditional Loading

Only load facts when needed, not preemptively.

Best Practices

Always Use Facts

Check current state with facts before making changes. Never assume state.

Type Hints

Use Generic[T] type hints for better IDE support and type checking.

Descriptive Names

Name facts clearly to indicate what they collect (e.g., NginxVersion not GetVersion).

Robust Processing

Handle empty output, malformed data, and edge cases in process() methods.

Sensible Defaults

Return appropriate defaults when facts can’t be collected (empty lists, None, etc.).

Document Parameters

Clearly document fact parameters and return types in docstrings.

Common Patterns

Existence Check

Version Comparison

State Validation

Testing Facts

Unit Testing

Integration Testing

Operations

Learn how to use facts for idempotent operations

Architecture

Understand when facts are collected in the two-phase model

Connectors

See how connectors execute fact commands

Facts API

Browse all built-in facts