or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfig.mdindex.mdrust-api.md

index.mddocs/

0

# py-spy

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: py-spy

7

- **Package Type**: pypi

8

- **Language**: Rust (command-line tool)

9

- **Installation**: `pip install py-spy`

10

- **Platforms**: Linux, macOS, Windows, FreeBSD

11

- **Python Support**: 2.3-2.7, 3.3-3.13

12

13

## Core Imports

14

15

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:

16

17

```rust

18

use py_spy::{Config, PythonSpy, StackTrace, Frame, Pid};

19

use py_spy::sampler::Sampler;

20

use anyhow::Error;

21

```

22

23

## Basic Usage

24

25

### Command Line Interface

26

27

```bash

28

# Profile existing process (record to flamegraph)

29

py-spy record -o profile.svg --pid 12345

30

31

# Profile new Python program

32

py-spy record -o profile.svg -- python myprogram.py

33

34

# Live console view (like top)

35

py-spy top --pid 12345

36

37

# Single stack trace snapshot

38

py-spy dump --pid 12345

39

```

40

41

### Rust Library API

42

43

```rust

44

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

45

use anyhow::Error;

46

47

fn profile_python_process(pid: Pid) -> Result<(), Error> {

48

// Create configuration with defaults

49

let config = Config::default();

50

51

// Create profiler instance

52

let mut spy = PythonSpy::new(pid, &config)?;

53

54

// Get current stack traces

55

let traces = spy.get_stack_traces()?;

56

57

// Process each thread's stack trace

58

for trace in traces {

59

println!("Thread {:#X} ({})", trace.thread_id, trace.status_str());

60

for frame in &trace.frames {

61

println!(" {} ({}:{})", frame.name, frame.filename, frame.line);

62

}

63

}

64

65

Ok(())

66

}

67

```

68

69

## Architecture

70

71

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

72

73

- **Process Memory Access**: Platform-specific memory reading (process_vm_readv on Linux, vm_read on macOS, ReadProcessMemory on Windows)

74

- **Python Interpreter Analysis**: Version-specific bindings for Python 2.3-3.13 to parse interpreter state

75

- **Stack Trace Collection**: Traverses PyFrameObject chains to reconstruct call stacks

76

- **Native Extension Support**: Optional libunwind integration for C/C++/Cython profiling

77

- **Output Generation**: Multiple format support (flamegraph, speedscope, Chrome trace, raw data)

78

79

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

80

81

## Capabilities

82

83

### Command Line Interface

84

85

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

86

87

```bash { .api }

88

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

89

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

90

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

91

```

92

93

[Command Line Interface](./cli.md)

94

95

### Rust Library API

96

97

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

98

99

```rust { .api }

100

struct PythonSpy;

101

impl PythonSpy {

102

fn new(pid: Pid, config: &Config) -> Result<PythonSpy, Error>;

103

fn get_stack_traces(&mut self) -> Result<Vec<StackTrace>, Error>;

104

}

105

106

struct Sampler;

107

impl Sampler {

108

fn new(pid: Pid, config: &Config) -> Result<Sampler, Error>;

109

}

110

impl Iterator for Sampler {

111

type Item = Sample;

112

}

113

```

114

115

[Rust Library API](./rust-api.md)

116

117

### Configuration and Output Formats

118

119

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

120

121

```rust { .api }

122

struct Config {

123

blocking: LockingStrategy,

124

native: bool,

125

sampling_rate: u64,

126

format: Option<FileFormat>,

127

// ... additional fields

128

}

129

130

enum FileFormat {

131

flamegraph, // SVG flamegraph

132

speedscope, // JSON for speedscope.app

133

chrometrace, // Chrome trace format

134

raw, // Raw flamegraph data

135

}

136

```

137

138

[Configuration and Output](./config.md)

139

140

## Core Types

141

142

### Stack Trace Representation

143

144

```rust { .api }

145

struct StackTrace {

146

pid: Pid,

147

thread_id: u64,

148

thread_name: Option<String>,

149

os_thread_id: Option<u64>,

150

active: bool,

151

owns_gil: bool,

152

frames: Vec<Frame>,

153

process_info: Option<Arc<ProcessInfo>>,

154

}

155

156

impl StackTrace {

157

fn status_str(&self) -> &str;

158

fn format_threadid(&self) -> String;

159

}

160

```

161

162

### Frame Information

163

164

```rust { .api }

165

struct Frame {

166

name: String,

167

filename: String,

168

module: Option<String>,

169

short_filename: Option<String>,

170

line: i32,

171

locals: Option<Vec<LocalVariable>>,

172

is_entry: bool,

173

is_shim_entry: bool,

174

}

175

```

176

177

### Process Identification

178

179

```rust { .api }

180

type Pid = remoteprocess::Pid;

181

```

182

183

### Configuration Enums

184

185

```rust { .api }

186

enum LockingStrategy {

187

Lock, // Standard blocking mode

188

NonBlocking, // Minimal performance impact

189

AlreadyLocked, // Process already locked

190

}

191

192

enum RecordDuration {

193

Unlimited,

194

Seconds(u64),

195

}

196

197

enum LineNo {

198

NoLine,

199

First,

200

LastInstruction,

201

}

202

```