0
# Session Management
1
2
Profiling session data structures and persistence functionality for saving and loading profile results, combining multiple sessions, and accessing detailed timing and execution information.
3
4
## Capabilities
5
6
### Session Class
7
8
Container for profiling data with metadata about execution timing, call stack samples, and system information.
9
10
```python { .api }
11
class Session:
12
"""
13
Represents a profiling session containing collected performance data.
14
15
Attributes:
16
frame_records (list): Raw frame sampling data
17
start_time (float): Session start timestamp
18
duration (float): Total session duration in seconds
19
min_interval (float): Minimum sampling interval used
20
max_interval (float): Maximum sampling interval used
21
sample_count (int): Number of samples collected
22
start_call_stack (list[str]): Initial call stack when profiling began
23
target_description (str): Description of profiled target
24
cpu_time (float): Total CPU time consumed
25
sys_path (list[str]): Python sys.path at time of profiling
26
sys_prefixes (list[str]): Python sys.prefixes at time of profiling
27
"""
28
29
def __init__(
30
self,
31
frame_records: list[FrameRecordType],
32
start_time: float,
33
duration: float,
34
min_interval: float,
35
max_interval: float,
36
sample_count: int,
37
start_call_stack: list[str],
38
target_description: str,
39
cpu_time: float,
40
sys_path: list[str],
41
sys_prefixes: list[str]
42
):
43
"""
44
Initialize session with profiling data.
45
46
Args:
47
frame_records: List of captured frame samples
48
start_time: Unix timestamp when profiling started
49
duration: Total profiling duration in seconds
50
min_interval: Minimum sampling interval used
51
max_interval: Maximum sampling interval used
52
sample_count: Total number of samples collected
53
start_call_stack: Initial call stack when profiling began
54
target_description: Human-readable description of profiled code
55
cpu_time: Total CPU time consumed during profiling
56
sys_path: Python module search path during profiling
57
sys_prefixes: Python installation prefixes during profiling
58
"""
59
60
def save(self, filename: PathOrStr) -> None:
61
"""
62
Save session data to disk in JSON format.
63
64
Args:
65
filename: Path to save session data (.pyisession extension recommended)
66
"""
67
68
@staticmethod
69
def load(filename: PathOrStr) -> Session:
70
"""
71
Load previously saved session from disk.
72
73
Args:
74
filename: Path to saved session file
75
76
Returns:
77
Session object with loaded profiling data
78
79
Raises:
80
FileNotFoundError: If session file doesn't exist
81
JSONDecodeError: If session file is corrupted
82
"""
83
84
def to_json(self, include_frame_records: bool = True) -> dict[str, Any]:
85
"""
86
Convert session to JSON-serializable dictionary.
87
88
Args:
89
include_frame_records: Whether to include raw frame data
90
91
Returns:
92
Dictionary representation suitable for JSON serialization
93
"""
94
95
@staticmethod
96
def from_json(json_dict: dict[str, Any]) -> Session:
97
"""
98
Create session from JSON dictionary.
99
100
Args:
101
json_dict: Dictionary with session data (from to_json())
102
103
Returns:
104
Reconstructed Session object
105
"""
106
107
@staticmethod
108
def combine(session1: Session, session2: Session) -> Session:
109
"""
110
Combine two profiling sessions into one.
111
112
Args:
113
session1: First session to combine
114
session2: Second session to combine
115
116
Returns:
117
New session containing combined data
118
"""
119
120
@staticmethod
121
def current_sys_prefixes() -> list[str]:
122
"""
123
Get current Python sys.prefixes.
124
125
Returns:
126
List of current Python installation prefixes
127
"""
128
```
129
130
### Frame Data Access
131
132
Methods for accessing and working with the collected frame data within a session.
133
134
```python { .api }
135
def root_frame(self, trim_stem: bool = True) -> Frame | None:
136
"""
137
Get the root frame of the call tree.
138
139
Parses the internal frame records and returns a tree of Frame objects
140
that can be rendered using a Renderer object.
141
142
Args:
143
trim_stem: Whether to trim the root stem frames before branches
144
145
Returns:
146
Root Frame object representing the call hierarchy, or None if session is empty
147
"""
148
149
def shorten_path(self, path: str) -> str:
150
"""
151
Shorten a file path to a more readable form, relative to sys_path.
152
153
Used by Frame.short_file_path for display purposes.
154
155
Args:
156
path: Full file path to shorten
157
158
Returns:
159
Shortened, more readable path string
160
"""
161
```
162
163
## Usage Examples
164
165
### Saving and Loading Sessions
166
167
```python
168
from pyinstrument import Profiler
169
170
# Create and run profiling session
171
with Profiler() as profiler:
172
expensive_operation()
173
174
session = profiler.last_session
175
176
# Save session to disk
177
session.save('profile_data.pyisession')
178
179
# Later, load the session
180
from pyinstrument.session import Session
181
loaded_session = Session.load('profile_data.pyisession')
182
183
# Use loaded session with any renderer
184
from pyinstrument.renderers import HTMLRenderer
185
renderer = HTMLRenderer()
186
html_output = renderer.render(loaded_session)
187
```
188
189
### Combining Multiple Sessions
190
191
```python
192
from pyinstrument import Profiler
193
from pyinstrument.session import Session
194
195
# Profile different parts of application
196
profiler = Profiler()
197
198
# First operation
199
profiler.start()
200
operation_a()
201
profiler.stop()
202
session_a = profiler.last_session
203
204
# Second operation
205
profiler.start()
206
operation_b()
207
profiler.stop()
208
session_b = profiler.last_session
209
210
# Combine sessions for comprehensive view
211
combined_session = Session.combine(session_a, session_b)
212
213
# Analyze combined results
214
profiler._last_session = combined_session
215
profiler.print()
216
```
217
218
### JSON Export and Import
219
220
```python
221
from pyinstrument import Profiler
222
from pyinstrument.session import Session
223
import json
224
225
with Profiler() as profiler:
226
process_data()
227
228
session = profiler.last_session
229
230
# Export to JSON
231
json_data = session.to_json()
232
with open('session.json', 'w') as f:
233
json.dump(json_data, f, indent=2)
234
235
# Import from JSON
236
with open('session.json', 'r') as f:
237
loaded_data = json.load(f)
238
239
restored_session = Session.from_json(loaded_data)
240
```
241
242
### Accessing Session Metadata
243
244
```python
245
from pyinstrument import Profiler
246
247
with Profiler() as profiler:
248
analyze_performance()
249
250
session = profiler.last_session
251
252
# Access session information
253
print(f"Duration: {session.duration:.3f} seconds")
254
print(f"CPU time: {session.cpu_time:.3f} seconds")
255
print(f"Samples: {session.sample_count}")
256
print(f"Target: {session.target_description}")
257
print(f"Start time: {session.start_time}")
258
259
# Access frame data
260
root = session.root_frame()
261
print(f"Root frame: {root.function} in {root.file_path}")
262
```
263
264
### Working with Frame Records
265
266
```python
267
from pyinstrument import Profiler
268
269
with Profiler() as profiler:
270
computation_task()
271
272
session = profiler.last_session
273
274
# Access raw frame sampling data
275
for call_stack, time_delta in session.frame_records:
276
print(f"Time: {time_delta:.6f}s")
277
for frame_info in call_stack:
278
print(f" {frame_info}")
279
print()
280
```
281
282
## Types
283
284
```python { .api }
285
PathOrStr = str | os.PathLike[str]
286
FrameRecordType = tuple[list[str], float]
287
ProcessorType = Callable[..., Frame | None]
288
289
class Frame:
290
"""Represents a single frame in the call stack."""
291
identifier: str
292
time: float
293
children: list[Frame]
294
parent: Frame | None
295
file_path: str | None
296
function: str | None
297
line_no: int | None
298
absorbed_time: float
299
attributes: dict[str, float]
300
```