or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli.mdconfig.mdindex.mdrust-api.md
tile.json

tessl/pypi-py-spy

Sampling profiler for Python programs written in Rust with extremely low overhead

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/py-spy@0.4.x

To install, run

npx @tessl/cli install tessl/pypi-py-spy@0.4.0

index.mddocs/

py-spy

A sampling profiler for Python programs written in Rust that allows developers to visualize what their Python programs are spending time on without restarting the program or modifying code. py-spy operates outside the profiled Python process with extremely low overhead, making it safe for production use.

Package Information

  • Package Name: py-spy
  • Package Type: pypi
  • Language: Rust (command-line tool)
  • Installation: pip install py-spy
  • Platforms: Linux, macOS, Windows, FreeBSD
  • Python Support: 2.3-2.7, 3.3-3.13

Core Imports

py-spy is primarily used as a command-line tool installed via pip. For advanced users who want to embed py-spy functionality in Rust applications:

use py_spy::{Config, PythonSpy, StackTrace, Frame, Pid};
use py_spy::sampler::Sampler;
use anyhow::Error;

Basic Usage

Command Line Interface

# Profile existing process (record to flamegraph)
py-spy record -o profile.svg --pid 12345

# Profile new Python program
py-spy record -o profile.svg -- python myprogram.py

# Live console view (like top)
py-spy top --pid 12345

# Single stack trace snapshot
py-spy dump --pid 12345

Rust Library API

use py_spy::{Config, PythonSpy, Pid};
use anyhow::Error;

fn profile_python_process(pid: Pid) -> Result<(), Error> {
    // Create configuration with defaults
    let config = Config::default();
    
    // Create profiler instance
    let mut spy = PythonSpy::new(pid, &config)?;
    
    // Get current stack traces
    let traces = spy.get_stack_traces()?;
    
    // Process each thread's stack trace
    for trace in traces {
        println!("Thread {:#X} ({})", trace.thread_id, trace.status_str());
        for frame in &trace.frames {
            println!("  {} ({}:{})", frame.name, frame.filename, frame.line);
        }
    }
    
    Ok(())
}

Architecture

py-spy uses a multi-layered architecture for safe, cross-platform Python process profiling:

  • Process Memory Access: Platform-specific memory reading (process_vm_readv on Linux, vm_read on macOS, ReadProcessMemory on Windows)
  • Python Interpreter Analysis: Version-specific bindings for Python 2.3-3.13 to parse interpreter state
  • Stack Trace Collection: Traverses PyFrameObject chains to reconstruct call stacks
  • Native Extension Support: Optional libunwind integration for C/C++/Cython profiling
  • Output Generation: Multiple format support (flamegraph, speedscope, Chrome trace, raw data)

This design enables py-spy to profile Python processes safely without code modification or significant performance impact.

Capabilities

Command Line Interface

Complete command-line profiling tool with three main subcommands and extensive configuration options for production and development use.

py-spy record [OPTIONS] [--pid PID | -- PYTHON_PROGRAM...]
py-spy top [OPTIONS] [--pid PID | -- PYTHON_PROGRAM...]
py-spy dump [OPTIONS] [--pid PID | -- PYTHON_PROGRAM...]

Command Line Interface

Rust Library API

Programmatic profiling interface for integrating py-spy functionality into Rust applications and custom profiling tools.

struct PythonSpy;
impl PythonSpy {
    fn new(pid: Pid, config: &Config) -> Result<PythonSpy, Error>;
    fn get_stack_traces(&mut self) -> Result<Vec<StackTrace>, Error>;
}

struct Sampler;
impl Sampler {
    fn new(pid: Pid, config: &Config) -> Result<Sampler, Error>;
}
impl Iterator for Sampler {
    type Item = Sample;
}

Rust Library API

Configuration and Output Formats

Comprehensive configuration system supporting multiple profiling modes, output formats, and platform-specific options.

struct Config {
    blocking: LockingStrategy,
    native: bool,
    sampling_rate: u64,
    format: Option<FileFormat>,
    // ... additional fields
}

enum FileFormat {
    flamegraph,    // SVG flamegraph
    speedscope,    // JSON for speedscope.app
    chrometrace,   // Chrome trace format
    raw,          // Raw flamegraph data
}

Configuration and Output

Core Types

Stack Trace Representation

struct StackTrace {
    pid: Pid,
    thread_id: u64,
    thread_name: Option<String>,
    os_thread_id: Option<u64>,
    active: bool,
    owns_gil: bool,
    frames: Vec<Frame>,
    process_info: Option<Arc<ProcessInfo>>,
}

impl StackTrace {
    fn status_str(&self) -> &str;
    fn format_threadid(&self) -> String;
}

Frame Information

struct Frame {
    name: String,
    filename: String,
    module: Option<String>,
    short_filename: Option<String>,
    line: i32,
    locals: Option<Vec<LocalVariable>>,
    is_entry: bool,
    is_shim_entry: bool,
}

Process Identification

type Pid = remoteprocess::Pid;

Configuration Enums

enum LockingStrategy {
    Lock,         // Standard blocking mode
    NonBlocking,  // Minimal performance impact
    AlreadyLocked, // Process already locked
}

enum RecordDuration {
    Unlimited,
    Seconds(u64),
}

enum LineNo {
    NoLine,
    First,
    LastInstruction,
}