Install & Compatibility
Where this runs
tested against v3.9.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
py 3.9
✕ build_error
✕ build_error
74MB installed
● package 74MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
apt.packages
✓ from pyinfra.operations import apt
Operations like `apt.packages`, `files.file`, `server.shell` are imported from the `pyinfra.operations` module.
host
✓ from pyinfra import host
The `host` object provides context about the current target host.
Hostname (fact)
✓ from pyinfra.facts.server import Hostname
Facts are imported from `pyinfra.facts` to gather information about target systems.
deploy (decorator)
✓ from pyinfra.api import deploy
✗ @deploy
As of pyinfra v3, the `deploy` decorator must be called as `@deploy()`.
This quickstart demonstrates how to define a simple pyinfra deploy to install and configure Nginx on a target. Save this code as `deploy.py`. To execute it, you would typically run `pyinfra <inventory> deploy.py` from your terminal. For local testing, use `pyinfra @local deploy.py`. To target a remote server via SSH, use `pyinfra my-server.net deploy.py --ssh-user <your_user>`. The `apt.update` and `apt.packages` operations ensure idempotency, meaning they only make changes if necessary.
import os
from pyinfra.operations import apt, files
# Define target hosts (using @local for a quick test)
# For remote SSH, change to: hosts = ['my-server.net']
# For Docker, change to: hosts = ['@docker/ubuntu:latest']
# Create a dummy inventory file if running with `pyinfra inventory.py deploy.py`
# In a real scenario, this would connect to actual hosts.
# If running directly, pyinfra will prompt or use @local if no inventory is specified.
# deploy.py
# Ensure apt packages are updated and Nginx is installed
apt.update(name="Update apt repositories", _sudo=True)
apt.packages(name="Install Nginx", packages=['nginx'], _sudo=True)
# Ensure Nginx service is running and enabled
files.file(
name="Ensure Nginx config is present",
path="/etc/nginx/sites-available/default",
contents="""
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
""",
_sudo=True
)
apt.update(
name="Run apt update (idempotent)",
_sudo=True
)
apt.packages(
name="Install Nginx (idempotent)",
packages=["nginx"],
_sudo=True
)
# To make this runnable directly as a Python script for illustration:
# This part is typically handled by the `pyinfra` CLI.
# We will simulate a direct execution for simplicity, but real use is via `pyinfra <inventory> <deploy>`.
# import sys
# from pyinfra.api.local import Local
# with Local(['@local']) as state:
# # In a real deploy.py, the operations would run directly.
# # For this quickstart, we just define them as above.
# print("Deploy operations defined. Run with: pyinfra @local deploy.py")
# print("Or via SSH: pyinfra my-host.net deploy.py")
# Example of how to execute from CLI:
# Create a file named 'deploy.py' with the above content.
# Then run: pyinfra @local deploy.py
# Or to a remote host: pyinfra my-server.net deploy.py --ssh-user <your_user> --ssh-password "$PYINFRA_SSH_PASSWORD"
pyinfra --version
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'pyinfra.operations.apt'
Attempting to import a specific operation directly from `pyinfra.operations` without specifying the operation module (e.g., `apt`).
fixImport operations from their respective sub-modules, such as `from pyinfra.operations import apt`, then call `apt.packages()`.
pyinfra.exceptions.ConnectError: SSH connection failed: Permission denied (publickey,password).
Incorrect SSH credentials, missing SSH keys, or issues with SSH agent forwarding when connecting to a remote host.
fixVerify your SSH configuration (`~/.ssh/config`), ensure your SSH agent is running and has the correct keys, or provide explicit `--ssh-user` and `--ssh-password` (or `--ssh-password-prompt`) arguments to the `pyinfra` CLI.
Operation doesn't execute or fails without error messages in pyinfra output.
The operation's `_if` or `_when` conditions were not met, causing it to be skipped, or an underlying command failed silently.
fixRun pyinfra with `--debug` and `--log-level debug` flags. Check the conditions on the operation. If it's a `server.shell` operation, inspect the `stdout` and `stderr` after execution for clues.
pyinfra reports 'no changes' but the desired state is not met, or 'changes' when no changes should occur.
The facts gathered by pyinfra do not accurately reflect the host's state, or the operation's logic for detecting changes is flawed.
fixDebug facts by inspecting `host.get_fact(FactName)` results directly. For operations, use the `--dry` flag to see what commands *would* be run, and review the operation's source or implement explicit state checks.
Upgrade
Version history
3.9.2latest on PyPI · released Jun 7, 2026
Audit
Dependencies
No dependency data recorded yet.