### Setup HTML Renderer Development Source: https://github.com/joerick/pyinstrument/blob/main/README.md Commands to set up the development environment for the HTML renderer's Vue.js application, including installing dependencies and starting a development server. ```bash cd html_renderer npm ci npm run serve ``` -------------------------------- ### Setup Development Environment Source: https://github.com/joerick/pyinstrument/blob/main/README.md Commands to set up a local development environment for Pyinstrument, including virtual environment creation, dependency installation, and pre-commit hook setup. ```bash virtualenv --python=python3 env . env/bin/activate pip install --upgrade pip pip install -r requirements-dev.txt pre-commit install --install-hooks ``` -------------------------------- ### aiohttp.web Development and Deployment Configuration Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Example configurations for aiohttp.web applications, distinguishing between a development setup with profiling enabled and a standard deployment setup. ```python ... def dev_app(argv): app = web.Application(middlewares=(profiler_middleware,)) app.add_routes(routes) return app # for development if __name__ == '__main__': app = web.Application() app.add_routes(routes) web.run_app(...) ``` -------------------------------- ### Get Pyinstrument Help Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Use this command to view available options and usage instructions for Pyinstrument from the command line. ```bash python -m pyinstrument --help ``` -------------------------------- ### Install Pyinstrument Source: https://github.com/joerick/pyinstrument/blob/main/README.md Install pyinstrument using pip. This command is used to add the profiler to your Python environment. ```bash pip install pyinstrument ``` -------------------------------- ### Profile Installed Python CLI Command Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Use the --from-path flag with Pyinstrument to profile an installed Python script via its console script entry point. ```bash pyinstrument --from-path cli-script ``` -------------------------------- ### cProfile Output Example Source: https://github.com/joerick/pyinstrument/blob/main/docs/how-it-works.md This output from cProfile shows function calls ordered by cumulative time. It can be difficult to relate to your own code. ```text 151940 function calls (147672 primitive calls) in 1.696 seconds Ordered by: cumulative time ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 1.696 1.696 profile:0( at 0x1053d6a30, file "./manage.py", line 2>) 1 0.001 0.001 1.693 1.693 manage.py:2() 1 0.000 0.000 1.586 1.586 __init__.py:394(execute_from_command_line) 1 0.000 0.000 1.586 1.586 __init__.py:350(execute) 1 0.000 0.000 1.142 1.142 __init__.py:254(fetch_command) 43 0.013 0.000 1.124 0.026 __init__.py:1() 388 0.008 0.000 1.062 0.003 re.py:226(_compile) 158 0.005 0.000 1.048 0.007 sre_compile.py:496(compile) 1 0.001 0.001 1.042 1.042 __init__.py:78(get_commands) 153 0.001 0.000 1.036 0.007 re.py:188(compile) 106/102 0.001 0.000 1.030 0.010 __init__.py:52(__getattr__) 1 0.000 0.000 1.029 1.029 __init__.py:31(_setup) 1 0.000 0.000 1.021 1.021 __init__.py:57(_configure_logging) 2 0.002 0.001 1.011 0.505 log.py:1() ``` -------------------------------- ### Configure Pyinstrument Profiler Options Source: https://context7.com/joerick/pyinstrument/llms.txt Demonstrates various Pyinstrument profiler configurations including interval for detail vs. overhead, async mode settings, and using a timing thread for systems with slow gettimeofday. Shows how to start with a custom description, check profiler state, and reset the profiler. ```python from pyinstrument import Profiler import time # Default configuration (1ms sampling) profiler = Profiler() # High-resolution profiling for short code # Smaller interval = more detail but more overhead profiler_detailed = Profiler(interval=0.0001) # 0.1ms # Lower overhead for long-running profiles # Larger interval = less memory usage profiler_lightweight = Profiler(interval=0.01) # 10ms # Async mode configurations profiler_async = Profiler( async_mode="enabled" # Track awaits (default for Profiler) ) profiler_async_strict = Profiler( async_mode="strict" # Only profile current async context ) profiler_async_disabled = Profiler( async_mode="disabled" # Don't track async, may interleave tasks ) # Use timing thread for systems with slow gettimeofday # Useful in Docker containers or VMs profiler_timing_thread = Profiler(use_timing_thread=True) # Example with custom configuration profiler = Profiler( interval=0.001, async_mode="enabled", use_timing_thread=False ) # Start with custom target description profiler.start(target_description="Database query profiling") time.sleep(0.1) profiler.stop() profiler.print() # Check profiler state print(f"Is running: {profiler.is_running}") print(f"Has session: {profiler.last_session is not None}") print(f"Interval: {profiler.interval}s") print(f"Async mode: {profiler.async_mode}") # Reset profiler for reuse profiler.reset() ``` -------------------------------- ### Pyinstrument Full-Stack Recording Example Source: https://github.com/joerick/pyinstrument/blob/main/docs/how-it-works.md Pyinstrument's output displays the full call stack, making it easier to understand the context of expensive calls. Library frames are hidden by default to focus on your application code. ```text _ ._ __/__ _ _ _ _ _/_ Recorded: 14:53:35 Samples: 131 /_//_/// /_ / _/ v3.0.0b3 Program: examples/django_example/manage.py runserver --nothreading --noreload 3.131 manage.py:2 └─ 3.118 execute_from_command_line django/core/management/__init__.py:378 [473 frames hidden] django, socketserver, selectors, wsgi... 2.836 select selectors.py:365 0.126 _get_response django/core/handlers/base.py:96 └─ 0.126 hello_world django_example/views.py:4 ``` -------------------------------- ### Profile Python Script with Pyinstrument Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Run your Python script using Pyinstrument to get a performance summary. This is useful for identifying time-consuming parts of your script. ```bash pyinstrument script.py ``` -------------------------------- ### Profile Flask Requests Source: https://context7.com/joerick/pyinstrument/llms.txt Add before/after request hooks to conditionally enable profiling based on query parameters. Ensure Flask and Pyinstrument are installed. ```python from flask import Flask, g, make_response, request from pyinstrument import Profiler import time app = Flask(__name__) @app.before_request def before_request(): """Start profiler if ?profile is in the request.""" if "profile" in request.args: g.profiler = Profiler() g.profiler.start() @app.after_request def after_request(response): """Stop profiler and return HTML output instead of response.""" if not hasattr(g, "profiler"): return response g.profiler.stop() output_html = g.profiler.output_html() return make_response(output_html) @app.route("/") def index(): return "Hello, World!" @app.route("/slow") def slow_endpoint(): time.sleep(0.2) data = [i ** 2 for i in range(100000)] return f"Computed {len(data)} values" @app.route("/api/data") def api_data(): # Simulate database query time.sleep(0.05) return {"items": list(range(100))} if __name__ == "__main__": app.run(debug=True) # Visit http://localhost:5000/slow?profile to see the profile ``` -------------------------------- ### Generate HTML Reports with Pyinstrument Source: https://context7.com/joerick/pyinstrument/llms.txt Use `output_html()` to get HTML content as a string, `write_html()` to save to a file, or `open_in_browser()` to view directly. Options like `timeline` and `show_all` can customize the report. ```python from pyinstrument import Profiler from pathlib import Path def fibonacci(n): if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2) profiler = Profiler() profiler.start() result = fibonacci(30) profiler.stop() # Get HTML as string html_content = profiler.output_html() # Write HTML to file profiler.write_html("profile_output.html") # Write with options profiler.write_html( path="detailed_profile.html", timeline=True, # Show timeline view show_all=True # Include library frames ) # Open HTML directly in default browser profiler.open_in_browser(timeline=True) # Save to Path object output_path = Path("profiles") / "fib_profile.html" output_path.parent.mkdir(exist_ok=True) profiler.write_html(output_path) ``` -------------------------------- ### Profiler Class Basic Usage Source: https://context7.com/joerick/pyinstrument/llms.txt Instantiate the `Profiler` class to manually control profiling sessions. Use `start()` and `stop()` methods, then render output using `print()` or `output_text()`. ```python from pyinstrument import Profiler import time def slow_function(): time.sleep(0.1) return sum(i ** 2 for i in range(100000)) # Create and use profiler profiler = Profiler() profiler.start() # Code to profile result = slow_function() for _ in range(3): slow_function() profiler.stop() # Print to console profiler.print() # Get text output with options text_output = profiler.output_text( unicode=True, # Use unicode box-drawing characters color=True, # Enable ANSI colors show_all=False, # Hide library code timeline=False, # Aggregate repeated calls flat=False # Show call tree (not flat list) ) print(text_output) ``` -------------------------------- ### Profile Litestar Web Request with Middleware Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Create a Litestar middleware that wraps the ASGI app to profile requests. It intercepts response start messages to capture the profiling report and modifies headers to serve the HTML output. ```python from __future__ import annotations from asyncio import sleep from litestar import Litestar, get from litestar.middleware import MiddlewareProtocol from litestar.types import ASGIApp, Message, Receive, Scope, Send from pyinstrument import Profiler class ProfilingMiddleware(MiddlewareProtocol): def __init__(self, app: ASGIApp) -> None: super().__init__(app) # type: ignore self.app = app async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: profiler = Profiler(interval=0.001, async_mode="enabled") profiler.start() profile_html: str | None = None async def send_wrapper(message: Message) -> None: if message["type"] == "http.response.start": profiler.stop() nonlocal profile_html profile_html = profiler.output_html() message["headers"] = [ (b"content-type", b"text/html; charset=utf-8"), (b"content-length", str(len(profile_html)).encode()), ] elif message["type"] == "http.response.body": assert profile_html is not None message["body"] = profile_html.encode() await send(message) await self.app(scope, receive, send_wrapper) @get("/") async def index() -> str: await sleep(1) return "Hello, world!" app = Litestar( route_handlers=[index], middleware=[ProfilingMiddleware], ) ``` -------------------------------- ### Profile Falcon Web Request with Middleware Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Implement a Falcon middleware to profile requests. Start the profiler in `process_request` and stop/display it in `process_response`. Ensure profiling is conditionally enabled via a setting. ```python from pyinstrument import Profiler import falcon class ProfilerMiddleware: def __init__(self, interval=0.01): self.profiler = Profiler(interval=interval) def process_request(self, req, resp): self.profiler.start() def process_response(self, req, resp, resource, req_succeeded): self.profiler.stop() self.profiler.open_in_browser() PROFILING = True # Set this from a settings model app = falcon.App() if PROFILING: app.add_middleware(ProfilerMiddleware()) ``` -------------------------------- ### Profile Code with Pyinstrument Profiler API Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Utilize the lower-level Profiler API for more flexible profiling. Start, stop, and print the profiling results manually. This offers greater control over the profiling process. ```python from pyinstrument import Profiler profiler = Profiler() profiler.start() # code you want to profile profiler.stop() profiler.print() ``` -------------------------------- ### Profiler as Context Manager Source: https://context7.com/joerick/pyinstrument/llms.txt Utilize the `Profiler` class as a context manager for automatic start and stop of profiling. This provides convenient access to all output methods after the profiled block completes. ```python from pyinstrument import Profiler import time def process_data(items): time.sleep(0.05) return [item * 2 for item in items] def aggregate_results(results): time.sleep(0.03) return sum(results) # Use as context manager with Profiler() as profiler: data = list(range(100000)) processed = process_data(data) total = aggregate_results(processed) print(f"Total: {total}") # Access results after the with block profiler.print() ``` -------------------------------- ### Profile FastAPI Endpoints Source: https://context7.com/joerick/pyinstrument/llms.txt Use async middleware to profile FastAPI endpoints. Note that only async route handlers are profiled; sync handlers run in a thread pool and won't be captured. Ensure FastAPI and Pyinstrument are installed. ```python from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from pyinstrument import Profiler import asyncio app = FastAPI() PROFILING_ENABLED = True # Control via settings/environment if PROFILING_ENABLED: @app.middleware("http") async def profile_request(request: Request, call_next): """Profile requests when ?profile=1 is present.""" if request.query_params.get("profile"): profiler = Profiler(async_mode="enabled") profiler.start() await call_next(request) profiler.stop() return HTMLResponse(profiler.output_html()) return await call_next(request) @app.get("/") async def root(): return {"message": "Hello World"} @app.get("/slow") async def slow_endpoint(): """Async endpoint that will be profiled.""" await asyncio.sleep(0.1) data = [i ** 2 for i in range(50000)] return {"count": len(data), "sum": sum(data)} @app.get("/fetch") async def fetch_data(): """Simulate multiple async operations.""" async def fetch_item(id): await asyncio.sleep(0.02) return {"id": id, "value": id * 10} results = await asyncio.gather(*[fetch_item(i) for i in range(5)]) return {"items": results} # Run with: uvicorn main:app --reload # Profile with: http://localhost:8000/slow?profile=1 ``` -------------------------------- ### Flask Request Profiling Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Profile Flask requests by checking for a 'profile' query parameter. If present, a Profiler is started before the request and stopped after, returning the HTML output instead of the response. ```python from flask import Flask, g, make_response, request from pyinstrument import Profiler app = Flask(__name__) @app.before_request def before_request(): if "profile" in request.args: g.profiler = Profiler() g.profiler.start() @app.after_request def after_request(response): if not hasattr(g, "profiler"): return response g.profiler.stop() output_html = g.profiler.output_html() return make_response(output_html) ``` -------------------------------- ### Auto-Profile Pytest Tests with Fixture Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Create a Pytest fixture in `conftest.py` to automatically profile each test. The fixture starts the profiler before the test runs and stops it afterwards, saving the HTML report to a `.profiles` directory. ```python from pathlib import Path import pytest from pyinstrument import Profiler TESTS_ROOT = Path.cwd() @pytest.fixture(autouse=True) def auto_profile(request): PROFILE_ROOT = (TESTS_ROOT / ".profiles") # Turn profiling on profiler = Profiler() profiler.start() yield # Run test profiler.stop() PROFILE_ROOT.mkdir(exist_ok=True) results_file = PROFILE_ROOT / f"{request.node.name}.html" profiler.write_html(results_file) ``` -------------------------------- ### Automatic Output Format Inference Source: https://github.com/joerick/pyinstrument/blob/main/README.md Pyinstrument infers the output format from the file extension provided with the `-o` flag. For example, `-o profile.html` automatically uses the HTML renderer, and `-o profile.pyisession` saves a raw session object. ```bash pyinstrument -o profile.html myscript.py ``` ```bash pyinstrument -o profile.pyisession myscript.py ``` -------------------------------- ### FastAPI Request Profiling Middleware Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Profile FastAPI requests using an HTTP middleware. This middleware checks for a 'profile' query parameter and, if found, starts and stops the Profiler, returning the HTML output. Note: Only async path operation functions are profiled. ```python from fastapi import Request from fastapi.responses import HTMLResponse from pyinstrument import Profiler PROFILING = True # Set this from a settings model if PROFILING: @app.middleware("http") async def profile_request(request: Request, call_next): profiling = request.query_params.get("profile", False) if profiling: profiler = Profiler() profiler.start() await call_next(request) profiler.stop() return HTMLResponse(profiler.output_html()) else: return await call_next(request) ``` -------------------------------- ### Pyinstrument v3.4.2 Command Line Options Source: https://github.com/joerick/pyinstrument/blob/main/README.md Illustrates the usage of command-line options like --show, --show-regex, and --show-all in Pyinstrument. These options help in filtering the output to specific modules or files. ```bash pyinstrument --show '*/sympy/*' script.py ``` -------------------------------- ### Async Profiling with Pyinstrument Source: https://github.com/joerick/pyinstrument/blob/main/README.md Demonstrates how to use Pyinstrument for profiling asynchronous Python code. Ensure async_mode is set appropriately for accurate results. ```python import asyncio from pyinstrument import Profiler async def main(): p = Profiler(async_mode='disabled') with p: print('Hello ...') await asyncio.sleep(1) print('... World!') p.print() asyncio.run(main()) ``` -------------------------------- ### Help Output for Render Option Source: https://github.com/joerick/pyinstrument/blob/main/README.md The help output for the `--render-option` flag details its usage for passing renderer options, including setting flags, option values, and processor options using dot-syntax. ```text -p RENDER_OPTION, --render-option=RENDER_OPTION options to pass to the renderer, in the format 'flag_name' or 'option_name=option_value'. For example, to set the option 'time', pass '-p time=percent_of_total'. To pass multiple options, use the -p option multiple times. You can set processor options using dot-syntax, like '-p processor_options.filter_threshold=0'. option_value is parsed as a JSON value or a string. ``` -------------------------------- ### Run script with Pyinstrument CLI Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Use `pyinstrument` followed by your script name or module to profile execution. The report is printed to the console upon script completion or interruption. ```bash pyinstrument script.py ``` ```bash pyinstrument -m my_module ``` ```bash pyinstrument --help ``` -------------------------------- ### Save and Load Pyinstrument Sessions Source: https://context7.com/joerick/pyinstrument/llms.txt Profile code, save the session to a file, and then load it later for rendering with different output formats like HTML or console. Also demonstrates combining multiple sessions. ```python from pyinstrument import Profiler from pyinstrument.session import Session from pyinstrument.renderers import HTMLRenderer, ConsoleRenderer import time def workload(): time.sleep(0.1) return [i ** 2 for i in range(100000)] # Profile and save session profiler = Profiler() profiler.start() workload() profiler.stop() # Get the session object session = profiler.last_session # Save session to file session.save("profile_session.pyisession") # Load session later loaded_session = Session.load("profile_session.pyisession") # Render with different options html_renderer = HTMLRenderer(timeline=True) print(html_renderer.render(loaded_session)) console_renderer = ConsoleRenderer( unicode=True, color=True, time="percent_of_total" ) print(console_renderer.render(loaded_session)) # Combine multiple sessions profiler2 = Profiler() profiler2.start() workload() profiler2.stop() combined = Session.combine(session, profiler2.last_session) print(f"Combined duration: {combined.duration}s") print(f"Combined samples: {combined.sample_count}") ``` -------------------------------- ### Profile Code Block with Context Manager Source: https://context7.com/joerick/pyinstrument/llms.txt Use the `pyinstrument.profile()` context manager to profile specific blocks of synchronous code. A summary is automatically printed to stderr upon completion. ```python import pyinstrument import time # Profile a code block with context manager with pyinstrument.profile(): # Simulate some work time.sleep(0.1) data = [i ** 2 for i in range(100000)] result = sum(data) # Output automatically printed to stderr: # pyinstrument ........................................ # . # . Block at script.py:5 # . # . 0.150 script.py:1 # . +- 0.100 sleep # . +- 0.050 script.py:7 # . # ..................................................... ``` -------------------------------- ### Build HTML Renderer JS Bundle Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to compile the JavaScript application for the HTML renderer and bundle it back into the Pyinstrument Python tool. The --force flag can be used to overwrite existing bundles. ```bash bin/build_js_bundle.py [--force] ``` -------------------------------- ### Django Custom Show Callback Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Implement a callback function to conditionally display the pyinstrument profiling page. This function receives the request object and should return True to show the profiler or False otherwise. ```python def custom_show_pyinstrument(request): return request.user.is_superuser PYINSTRUMENT_SHOW_CALLBACK = "%s.custom_show_pyinstrument" % __name__ ``` -------------------------------- ### Run Specific Pre-commit Check (isort/black) Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to run specific pre-commit checks, such as 'isort' or 'black', to format source code. ```bash pre-commit run --all-files isort ``` ```bash pre-commit run --all-files black ``` -------------------------------- ### Profile code block with `profile` context manager Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Use the `pyinstrument.profile()` context manager to profile a specific block of code. Ensure `time.sleep` is imported if used. ```python import pyinstrument import time with pyinstrument.profile(): time.sleep(1) ``` -------------------------------- ### Run All Pre-commit Checks Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to run all pre-commit checks locally. Some checks may auto-fix issues, so running the command twice might be necessary. ```bash pre-commit run --all-files ``` -------------------------------- ### Render timeline with -t Source: https://github.com/joerick/pyinstrument/blob/main/README.md Use the -t or --timeline flag to render profiling output as a timeline, preserving order and not condensing repeated calls. ```bash -t, --timeline render as a timeline - preserve ordering and don't condense repeated calls ``` -------------------------------- ### Set Render Option via Command Line Source: https://github.com/joerick/pyinstrument/blob/main/README.md Use the `-p` or `--render-option` flag to pass arbitrary options to the renderer. This allows setting flags like `filter_threshold` from the command line. Multiple options can be passed by repeating the flag. ```bash pyinstrument -p processor_options.filter_threshold=0 ``` -------------------------------- ### Django Middleware Integration with Pyinstrument Source: https://context7.com/joerick/pyinstrument/llms.txt Integrate Pyinstrument into Django projects via `ProfilerMiddleware` in `settings.py`. Profile requests by appending `?profile` to URLs. Configure output directory, filename format, and custom callbacks for showing profiles or determining filenames. ```python # settings.py MIDDLEWARE = [ # ... other middleware ... 'pyinstrument.middleware.ProfilerMiddleware', ] # Profile individual requests by adding ?profile to URL # e.g., http://localhost:8000/api/users/?profile # Save all profiles to a directory PYINSTRUMENT_PROFILE_DIR = 'profiles' # Custom filename format PYINSTRUMENT_FILENAME = "{total_time:.3f}s {path} {timestamp:.0f}.{ext}" # Or use a callback for full control def get_profile_filename(request, session, renderer): path = request.get_full_path().replace("/", "_")[:100] return f"{request.method}_{session.duration:.3f}s_{path}.{renderer.output_file_extension}" PYINSTRUMENT_FILENAME_CALLBACK = get_profile_filename # Control when profiling is shown def should_show_profile(request): return request.user.is_superuser PYINSTRUMENT_SHOW_CALLBACK = f"{__name__}.should_show_profile" # Use a different renderer (default: HTMLRenderer) PYINSTRUMENT_PROFILE_DIR_RENDERER = 'pyinstrument.renderers.JSONRenderer' # Set custom sampling interval PYINSTRUMENT_INTERVAL = 0.001 # 1ms (default) ``` -------------------------------- ### Save and Load Pyinstrument Sessions Source: https://github.com/joerick/pyinstrument/blob/main/README.md Save the raw session data using the `-r session` flag and `-o session.pyisession`. Load a saved session using the `--load` option. ```bash pyinstrument -r session -o session.pyisession myscript.py ``` ```bash pyinstrument --load session.pyisession ``` -------------------------------- ### Load Pyinstrument IPython Extension Source: https://github.com/joerick/pyinstrument/blob/main/README.md To use Pyinstrument within an IPython notebook, first load the extension with `%load_ext pyinstrument`, then use `%%pyinstrument` in the cell you wish to profile. ```python %%pyinstrument ``` -------------------------------- ### Run Pyinstrument Tests Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to execute the test suite for Pyinstrument using pytest. ```bash pytest ``` -------------------------------- ### Profile code within a 'with' block Source: https://github.com/joerick/pyinstrument/blob/main/README.md Use pyinstrument within a 'with' block for convenient profiling of specific code sections. Instantiate Profiler, use it in a with statement, and then print the output. ```python profiler = pyinstrument.Profiler() with profiler: # do some work here... print(profiler.output_text()) ``` -------------------------------- ### Configure Django Middleware Renderer Source: https://github.com/joerick/pyinstrument/blob/main/README.md Configure renderers for Django middleware file output using the `PYINSTRUMENT_PROFILE_DIR_RENDERER` environment variable or option. ```bash PYINSTRUMENT_PROFILE_DIR_RENDERER ``` -------------------------------- ### Run modules with -m flag Source: https://github.com/joerick/pyinstrument/blob/main/README.md Execute modules using pyinstrument by prefixing the module name with the -m flag. ```bash pyinstrument -m module_name ``` -------------------------------- ### Load Pyinstrument IPython Magic Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Load the Pyinstrument extension in IPython or Jupyter notebooks to enable magic commands for profiling. ```python %load_ext pyinstrument ``` -------------------------------- ### Run Pyinstrument on a Script Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to profile a Python script using Pyinstrument from the shell. This is equivalent to running 'python -m pyinstrument'. ```bash pyinstrument examples/demo_scripts/wikipedia_article_word_count.py ``` -------------------------------- ### JSON output with --renderer=json Source: https://github.com/joerick/pyinstrument/blob/main/README.md Enable JSON output by specifying --renderer=json when running pyinstrument from the command line. ```bash pyinstrument --renderer=json scriptfile.py ``` -------------------------------- ### Run Pytest with Pyinstrument from Command Line Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Invoke Pytest using Pyinstrument from the command line to generate a consolidated profiling report for the entire test suite. Pass any necessary pytest arguments after the ellipsis. ```bash pyinstrument -m pytest [pytest-args...] ``` -------------------------------- ### Bump Version and Push Source: https://github.com/joerick/pyinstrument/blob/main/MAINTAINERS.md Execute the version bumping script and push changes to Git. This is part of the release process. ```shell bin/bump_version.py git push && git push --tags ``` -------------------------------- ### Profile aiohttp.web Request with Middleware Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Use a simple aiohttp.web middleware to profile requests. The middleware context-manages the profiler and returns its HTML output as the response. ```python from aiohttp import web from pyinstrument import Profiler @web.middleware async def profiler_middleware(request, handler): with Profiler() as p: await handler(request) return web.Response(text=p.output_html(), content_type="text/html") app = web.Application(middlewares=(profiler_middleware,)) ``` -------------------------------- ### Custom Renderer Output with Pyinstrument Source: https://context7.com/joerick/pyinstrument/llms.txt Utilize different renderers like `ConsoleRenderer`, `JSONRenderer`, or `SpeedscopeRenderer` for various output formats. `JSONRenderer` is useful for programmatic access, while `SpeedscopeRenderer` generates flame chart data. ```python from pyinstrument import Profiler from pyinstrument.renderers import ( ConsoleRenderer, HTMLRenderer, JSONRenderer, SpeedscopeRenderer ) import json def work(): return sum(i ** 2 for i in range(100000)) profiler = Profiler() profiler.start() work() profiler.stop() # Console renderer with custom options console_output = profiler.output( renderer=ConsoleRenderer( unicode=True, color=True, show_all=False, timeline=False, time="percent_of_total", # Show percentages instead of seconds flat=False ) ) print(console_output) # JSON renderer for programmatic access json_output = profiler.output(renderer=JSONRenderer()) profile_data = json.loads(json_output) print(f"Duration: {profile_data['duration']}s") # Speedscope format for flame charts speedscope_output = profiler.output(renderer=SpeedscopeRenderer()) with open("profile.speedscope.json", "w") as f: f.write(speedscope_output) # Upload to https://www.speedscope.app/ for visualization ``` -------------------------------- ### IPython/Jupyter Magic Commands Source: https://context7.com/joerick/pyinstrument/llms.txt Profile code cells in Jupyter notebooks or IPython using the `%%pyinstrument` magic command. Load the extension first with `%load_ext pyinstrument`. ```python # Load the pyinstrument extension %load_ext pyinstrument # Profile a cell %%pyinstrument import time def slow_function(): time.sleep(0.1) return sum(i ** 2 for i in range(100000)) result = slow_function() print(f"Result: {result}") # Profile with options %%pyinstrument --timeline --show-all import numpy as np data = np.random.rand(1000000) sorted_data = np.sort(data) mean = np.mean(sorted_data) # Profile async code in Jupyter %%pyinstrument --async_mode=enabled import asyncio async def fetch(): await asyncio.sleep(0.1) return "data" await fetch() # View available options %%pyinstrument?? ``` -------------------------------- ### Profile Function with Decorator Source: https://context7.com/joerick/pyinstrument/llms.txt Apply the `@pyinstrument.profile()` decorator to a function to automatically profile its execution each time it is called. Custom profiling options can be passed to the decorator. ```python import pyinstrument import time @pyinstrument.profile() def expensive_computation(): """Function that will be profiled on each call.""" time.sleep(0.05) result = 0 for i in range(100000): result += i ** 2 return result # Profile is printed after each call result = expensive_computation() print(f"Result: {result}") # Custom profiling options @pyinstrument.profile(interval=0.0001, async_mode="enabled") def another_function(): time.sleep(0.01) return [x * 2 for x in range(50000)] ``` -------------------------------- ### Profile Pytest Suite Source: https://context7.com/joerick/pyinstrument/llms.txt Profile entire test suites or individual tests using pyinstrument. For full suite profiling, run `pyinstrument -m pytest tests/`. For individual tests, use the `profile` fixture. ```python # conftest.py - Auto-profile each test from pathlib import Path import pytest from pyinstrument import Profiler TESTS_ROOT = Path(__file__).parent PROFILE_DIR = TESTS_ROOT / ".profiles" @pytest.fixture(autouse=True) def auto_profile(request): """Profile each test and save HTML output.""" profiler = Profiler() profiler.start() yield # Run the test profiler.stop() PROFILE_DIR.mkdir(exist_ok=True) # Create safe filename from test name test_name = request.node.name.replace("/", "_").replace("::", "_") results_file = PROFILE_DIR / f"{test_name}.html" profiler.write_html(results_file) # Or profile only specific tests with a marker @pytest.fixture def profile(): """Fixture for explicit profiling.""" profiler = Profiler() profiler.start() yield profiler profiler.stop() # test_example.py def test_slow_operation(profile): """Test that will be profiled.""" import time time.sleep(0.1) result = sum(i ** 2 for i in range(100000)) assert result > 0 # Access profiler after test print(profile.output_text(color=True)) ``` -------------------------------- ### Async Profiling with Pyinstrument Source: https://context7.com/joerick/pyinstrument/llms.txt Profile asynchronous code using `Profiler(async_mode='enabled')`. This tracks time spent in `await` expressions, distinguishing between coroutine execution and waiting time. `async_mode` can be 'enabled', 'disabled', or 'strict'. ```python import asyncio from pyinstrument import Profiler async def fetch_data(delay): """Simulate an async network call.""" await asyncio.sleep(delay) return {"data": "result"} async def process_item(item): """Process a single item.""" await asyncio.sleep(0.01) return item * 2 async def main(): # Fetch multiple resources concurrently results = await asyncio.gather( fetch_data(0.1), fetch_data(0.15), fetch_data(0.12) ) # Process items items = list(range(10)) processed = [] for item in items: result = await process_item(item) processed.append(result) return processed # Profile async code profiler = Profiler(async_mode="enabled") # enabled, disabled, or strict profiler.start() asyncio.run(main()) profiler.stop() profiler.print() # async_mode options: # - "enabled": Track awaits, show time in awaiting coroutine # - "disabled": Don't track async context (interleaves coroutines) # - "strict": Only profile current async context, ignore others ``` -------------------------------- ### Profile Code Chunk with Pyinstrument Context Manager Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Use the pyinstrument.profile() context manager to profile a specific block of Python code. Ensure pyinstrument is imported. ```python import pyinstrument with pyinstrument.profile(): # code you want to profile ``` -------------------------------- ### View Console Output as Percentages Source: https://github.com/joerick/pyinstrument/blob/main/README.md To display times in the console output as percentages instead of absolute values, use the `time='percent_of_total'` option with the ConsoleRenderer or the `-p time=percent_of_total` command-line flag. ```bash pyinstrument -p time=percent_of_total ``` -------------------------------- ### Profile IPython/Jupyter Cell with %%pyinstrument Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Use the %%pyinstrument cell magic to profile the entire content of a Jupyter or IPython cell. This is ideal for profiling blocks of code within an interactive session. ```python %%pyinstrument import time def a(): b() c() def b(): d() def c(): d() def d(): e() def e(): time.sleep(1) a() ``` -------------------------------- ### Profile function with `profile` decorator Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Apply the `@pyinstrument.profile()` decorator to a function to automatically profile its execution. Ensure `time.sleep` is imported if used. ```python import pyinstrument import time @pyinstrument.profile() def my_function(): time.sleep(1) ``` -------------------------------- ### Django Custom Filename Callback Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Define a callback function to dynamically generate filenames for pyinstrument profiles. This function takes the request, session, and renderer as arguments and returns a string representing the desired filename. ```python def get_pyinstrument_filename(request, session, renderer): path = request.get_full_path().replace("/", "_")[:100] ext = renderer.output_file_extension filename = f"{request.method}_{session.duration}{path}.{ext}" return filename PYINSTRUMENT_FILENAME_CALLBACK = get_pyinstrument_filename ``` -------------------------------- ### Command Line Profiling Options Source: https://context7.com/joerick/pyinstrument/llms.txt Profile Python scripts, modules, or inline code using various command-line arguments for different output formats and configurations. ```bash pyinstrument script.py ``` ```bash pyinstrument -r html -o profile.html script.py ``` ```bash pyinstrument -m pytest tests/ ``` ```bash pyinstrument -c "import time; time.sleep(0.5)" ``` ```bash pyinstrument -t script.py ``` ```bash pyinstrument --show-all script.py ``` ```bash pyinstrument --interval 0.01 long_running_script.py ``` ```bash pyinstrument -r json -o profile.json script.py ``` ```bash pyinstrument -r speedscope -o profile.speedscope.json script.py ``` ```bash pyinstrument --load session.pyisession ``` ```bash pyinstrument -r session -o profile.pyisession script.py ``` -------------------------------- ### Profile with Speedscope Renderer Source: https://github.com/joerick/pyinstrument/blob/main/README.md To generate output compatible with Speedscope, use the `-r speedscope` flag. Upload the generated file to the Speedscope web application for interactive flamechart visualization. ```bash pyinstrument -r speedscope ``` -------------------------------- ### Diagnose Pyright Check Failures Source: https://github.com/joerick/pyinstrument/blob/main/README.md Command to diagnose why 'pyright' checks are failing within the pre-commit framework. ```bash pre-commit run --all-files pyright ``` -------------------------------- ### Session Object Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Reference for the `Session` class, used for managing profiling data. ```APIDOC ## Session Object ### Description The `Session` class is responsible for managing the collected profiling data, including building the call tree and applying processors. ### Class `pyinstrument.session.Session` ### Methods - **__init__(self)**: Initializes a new Session. - **add_frame(frame_info)**: Adds raw frame information to the session. - **get_call_tree()**: Returns the processed call tree. - **get_total_seconds()**: Returns the total profiled time. - **save(filename)**: Saves the session data to a file. - **load(filename)**: Loads session data from a file. ### Usage Example ```python from pyinstrument import Profiler from pyinstrument.session import Session profiler = Profiler() profiler.start() # Code to profile profiler.stop() session = Session() session.load_from_profiler(profiler) print(session.get_call_tree()) ``` ``` -------------------------------- ### Hide library frames with --hide Source: https://github.com/joerick/pyinstrument/blob/main/README.md Use --hide with a glob-style pattern to exclude frames from specific file paths. Defaults to hiding frames in '*/lib/*'. ```bash --hide=EXPR glob-style pattern matching the file paths whose frames to hide. Defaults to '*/lib/*'. ``` -------------------------------- ### Adjust Pyinstrument Profiling Interval Source: https://github.com/joerick/pyinstrument/blob/main/docs/guide.md Modify the profiling interval for Pyinstrument if code executes very quickly (under 1ms). Smaller intervals can capture finer-grained performance data but may increase overhead. Use with caution. ```python pyinstrument.profile(interval=0.0001) # or, profiler = Profiler(interval=0.0001) ``` -------------------------------- ### Renderers Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Information about different renderer classes used to format profiling output. ```APIDOC ## Renderers ### Description Renderers transform the collected profiling data (a tree of `Frame` objects) into various output formats. They consist of a preprocessing step and a final rendering step. ### Base Class `pyinstrument.renderers.FrameRenderer` ### Available Renderers - **ConsoleRenderer**: Renders the output to the console. It uses `ConsoleRenderer(short_mode=True)` by default. - **Usage**: `from pyinstrument.renderers import ConsoleRenderer` - **Example**: `print(ConsoleRenderer().render(frame_tree))` - **HTMLRenderer**: Renders the output as an HTML file. - **Properties**: `preprocessors`, `preprocessor_options` - **Usage**: `from pyinstrument.renderers import HTMLRenderer` - **Example**: `html_renderer = HTMLRenderer(options={'line_numbers': True}) print(html_renderer.render(frame_tree))` - **JSONRenderer**: Renders the output in JSON format. - **Usage**: `from pyinstrument.renderers import JSONRenderer` - **Example**: `print(JSONRenderer().render(frame_tree))` - **SpeedscopeRenderer**: Renders the output in a format compatible with Speedscope. - **Usage**: `from pyinstrument.renderers import SpeedscopeRenderer` - **Example**: `print(SpeedscopeRenderer().render(frame_tree))` ### Processors Renderers apply processors to the frame tree before rendering. Key processors include `aggregate_repeated_calls` for summarizing calls and others for filtering irrelevant frames. ``` -------------------------------- ### Python API - profile function Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md The `profile` function can be used as a context manager or a decorator to profile code blocks or functions. ```APIDOC ## Python API - profile function ### Description Use the `profile` function as a context manager or a decorator to profile code execution and print the results to the console. ### Method Context Manager or Decorator ### Parameters #### Context Manager Parameters - **interval** (float) - Optional - The profiling interval in seconds. Defaults to 0.001. - **async_mode** (str) - Optional - Controls asynchronous profiling. Defaults to "disabled". - **use_timing_thread** (bool) - Optional - Whether to use a timing thread. Defaults to None. - **renderer** (object) - Optional - A renderer object to customize output. Defaults to ConsoleRenderer. - **target_description** (str) - Optional - A description for the profiling target. #### Decorator Parameters Same as context manager parameters. ### Request Example (Context Manager) ```python import pyinstrument import time with pyinstrument.profile(): time.sleep(1) ``` ### Request Example (Decorator) ```python import pyinstrument import time @pyinstrument.profile() def my_function(): time.sleep(1) my_function() ``` ### Response Example (Console Output) ``` pyinstrument ........................................ . . Block at testfile.py:2 . . 1.000 testfile.py:1 . └─ 1.000 sleep . ..................................................... ``` ``` -------------------------------- ### Hide library frames with --hide-regex Source: https://github.com/joerick/pyinstrument/blob/main/README.md Use --hide-regex with a regular expression for more control over hiding frames based on file paths. ```bash --hide-regex=REGEX regex matching the file paths whose frames to hide. Useful if --hide doesn't give enough control. ``` -------------------------------- ### Processors Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Overview of the processors module, which transforms the call tree before rendering. ```APIDOC ## Processors ### Description The `pyinstrument.processors` module contains functions that transform the call tree data before it is rendered. These processors help in cleaning up, aggregating, and filtering the profiling information. ### Module `pyinstrument.processors` ### Key Processors - **aggregate_repeated_calls**: Combines multiple calls to the same function into a single frame entry, summarizing the total time spent. - **remove_uninstrumented_code**: Removes frames that are not relevant to the user's code. - **show_all_frames**: Ensures all frames are included in the output, even if they might typically be hidden. ### Usage Processors are typically applied automatically by renderers, but can be manually configured by modifying the `processors` property of a renderer instance. ``` -------------------------------- ### Profiler Object Source: https://github.com/joerick/pyinstrument/blob/main/docs/reference.md Reference for the `Profiler` class, which is the core component for profiling code. ```APIDOC ## Profiler Object ### Description The `Profiler` class is the central object for performing code profiling. It records frame stacks during execution. ### Class `pyinstrument.Profiler` ### Methods - **__init__(self, *, interval=0.001, async_mode='disabled', use_timing_thread=None, renderer=None, target_description=None)**: Initializes the Profiler with various configuration options. - **start()**: Starts the profiler. - **stop()**: Stops the profiler. - **reset()**: Resets the profiler's recorded data. - **add_frame(frame_info)**: Adds a frame to the profiler's recorded data. - **get_total_seconds()**: Returns the total time profiled in seconds. ### Special Members - **__enter__()**: Enables the profiler to be used as a context manager. - **__exit__(exc_type, exc_val, exc_tb)**: Stops the profiler when exiting a context. ### Usage Example (as context manager) ```python from pyinstrument import Profiler profiler = Profiler() with profiler: # Code to profile pass print(profiler.output_text()) ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.