### Install Pre-commit Hook Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Install the pre-commit hook to automate code checks before commits. Ensure pre-commit is installed on your system. ```bash pre-commit install ``` -------------------------------- ### Install Scout APM for Celery Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Call `scout_apm.celery.install()` before starting your Celery worker. Optionally pass the Celery app instance to copy `scout_*` config from Celery's conf. Each task execution is tracked as `Job/`. ```python # tasks.py from celery import Celery import scout_apm.api as scout from scout_apm.celery import install as scout_celery_install app = Celery("tasks", broker="redis://localhost:6379/0") app.conf.update( scout_key="abc123def456ghi7", scout_name="My Celery Worker", scout_monitor=True, ) # Pass the Celery app so Scout reads scout_* keys from its conf scout_celery_install(app=app) @app.task def process_order(order_id: int): # Tracked as Job/tasks.process_order print(f"Processing order {order_id}") return {"order_id": order_id, "status": "processed"} # Run worker: celery -A tasks worker --loglevel=info ``` -------------------------------- ### Start MongoDB with Docker Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Launch a MongoDB instance in a detached Docker container. This is required for running tests that depend on MongoDB. ```bash docker run --detach --name mongo --publish 27017:27017 mongo:4.0 ``` -------------------------------- ### Install Tox for Testing Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Install the tox testing tool using pip. Tox is used to manage and run tests across different Python environments. ```bash python -m pip install tox ``` -------------------------------- ### Run Test Application with Waitress Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Serve the Scout APM test application using Waitress, a production-quality pure-Python WSGI server. Ensure Waitress is installed. ```bash pip install waitress waitress-serve tests.integration.app:app ``` -------------------------------- ### Install `importlib_metadata` for Older Python Source: https://github.com/scoutapp/scout_apm_python/blob/master/CHANGELOG.md When using Python versions older than 3.8, install the `importlib_metadata` backport package to use `importlib.metadata.distributions()` for determining package versions. ```bash pip install importlib-metadata ``` -------------------------------- ### Start Redis with Docker Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Launch a Redis instance in a detached Docker container. This is required for running tests that depend on Redis. ```bash docker run --detach --name redis --publish 6379:6379 redis:6 ``` -------------------------------- ### Start Elasticsearch with Docker Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Launch an Elasticsearch instance in a detached Docker container. This is required for running tests that depend on Elasticsearch. ```bash docker run --detach --name elasticsearch --publish 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" elasticsearch:8.7.0 ``` -------------------------------- ### Install Scout APM in Editable Mode Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Install the Scout APM Python agent in editable mode within an application's virtual environment. This allows direct editing and testing of the agent code. ```bash pip install -e path/to/scout_apm_python ``` -------------------------------- ### Run Test Application with Gunicorn Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Serve the Scout APM test application using Gunicorn, a Python WSGI HTTP Server. Ensure Gunicorn is installed. ```bash pip install gunicorn gunicorn tests.integration.app:app ``` -------------------------------- ### Install Scout APM for Celery Source: https://github.com/scoutapp/scout_apm_python/blob/master/CHANGELOG.md Use this to integrate Scout APM with your Celery application, allowing configuration to be shared between Django and Celery. ```python scout_apm.celery.install(app=app) ``` -------------------------------- ### Manual Web Transaction with Scout APM Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Manually demarcate a web transaction using `WebTransaction` as a context manager or by calling `start`/`stop` explicitly. Useful for frameworks without automatic integration. ```python from scout_apm.api import WebTransaction, Context, instrument import scout_apm.core scout_apm.core.install(config={ "key": "abc123def456ghi7", "name": "Custom WSGI App", "monitor": True, }) def my_wsgi_app(environ, start_response): with WebTransaction(name="MyController.action"): Context.add("user_ip", environ.get("REMOTE_ADDR", "")) Context.add("path", environ.get("PATH_INFO", "")) with instrument("db_query", kind="SQL"): # simulate DB work data = {"result": "hello"} start_response("200 OK", [("Content-Type", "application/json")]) return [b'{"result": "hello"}'] ``` -------------------------------- ### Run Pytest with PDB on Failure via Tox Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Run tox tests and pass arguments to Pytest to start the Python Debugger (PDB) on test failure. This helps in debugging failing tests. ```bash tox -e py39-django31 -- --pdb ``` -------------------------------- ### Manually Capture and Report an Exception Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Use `Error.capture()` to manually report an exception to Scout's error monitoring. This function can include request details, session data, and custom parameters for richer error context. Ensure Scout APM is installed. ```python from scout_apm.api import Error, Context import scout_apm.core scout_apm.core.install({ "key": "abc123def456ghi7", "name": "My App", "monitor": True, }) def process_payment(order_id: int, amount: float, user_session: dict): try: if amount <= 0: raise ValueError(f"Invalid payment amount: {amount}") # ... payment processing logic ... return {"status": "success"} except Exception as exc: # Report the exception with full context Error.capture( exc, request_path=f"/payments/{order_id}", request_params={"order_id": order_id}, session=user_session, custom_controller="PaymentController.process", custom_params={"amount": amount, "currency": "USD"}, ) return {"status": "error", "message": str(exc)} result = process_payment( order_id=99, amount=-5.0, user_session={"user_id": 42, "plan": "pro"}, ) # Error appears in Scout with full traceback, path, params, and session context ``` -------------------------------- ### Run All Pre-commit Checks Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Execute all configured pre-commit checks across all files in the repository. This is useful for verifying code quality and style. ```bash pre-commit run --all-files ``` -------------------------------- ### Add Scout APM Middleware to FastMCP Server Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Add `ScoutMiddleware` to a FastMCP server to trace tool invocations as `Controller/`. Tool description, tags, and behavioral annotations are automatically tagged on the request. ```python from fastmcp import FastMCP import scout_apm.api as scout from scout_apm.fastmcp import ScoutMiddleware scout.Config.set(key="abc123def456ghi7", name="My MCP Server", monitor=True) mcp = FastMCP("MyServer") mcp.add_middleware(ScoutMiddleware()) @mcp.tool(description="Search documents by keyword", tags={"search", "read"}) async def search_documents(query: str, limit: int = 10) -> list[dict]: # Tracked as Controller/search_documents return [{"id": 1, "title": "Result", "snippet": f"...{query}..."}] if __name__ == "__main__": mcp.run() ``` -------------------------------- ### Configure Scout APM Agent Programmatically or via Environment Variables Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Set Scout APM configuration using `ScoutConfig.set()` or environment variables. Programmatic configuration has lower priority than environment variables. Ensure `monitor` is `True` for activation. Inspect resolved values using `scout_config.value()`. ```python import scout_apm.api as scout # Programmatic configuration (lower priority than env vars) scout.Config.set( key="abc123def456ghi7", # Your Scout APM key name="My Python App", monitor=True, log_level="info", # Ignore health-check endpoints entirely ignore_endpoints=["health", "ping"], # Sample only 50% of all transactions globally sample_rate=0.5, # Per-endpoint sampling: 10% for /metrics, 100% for /checkout sample_endpoints={"metrics": 0.10, "checkout": 1.0}, # Per-job sampling sample_jobs={"send_email": 0.25}, shutdown_timeout_seconds=2.0, ) # Or purely via environment variables (no code change needed): # export SCOUT_KEY=abc123def456ghi7 # export SCOUT_NAME="My Python App" # export SCOUT_MONITOR=true # export SCOUT_IGNORE_ENDPOINTS=health,ping # export SCOUT_SAMPLE_RATE=0.5 # Inspect the resolved value for any key from scout_apm.core.config import scout_config print(scout_config.value("name")) # "My Python App" print(scout_config.value("monitor")) # True print(scout_config.value("sample_rate")) # 0.5 ``` -------------------------------- ### Starlette / ASGI Integration with Scout APM Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Add `ScoutMiddleware` to your Starlette or other ASGI application. Background tasks created via `starlette.background.BackgroundTask` are automatically tracked as jobs. ```python from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.responses import JSONResponse from starlette.routing import Route from starlette.background import BackgroundTask import scout_apm.api as scout from scout_apm.async_.starlette import ScoutMiddleware scout.Config.set(key="abc123def456ghi7", name="My Starlette App", monitor=True) async def send_welcome_email(email: str): # Tracked automatically as Job/views.send_welcome_email print(f"Sending to {email}") async def homepage(request): task = BackgroundTask(send_welcome_email, email="user@example.com") return JSONResponse({"status": "ok"}, background=task) app = Starlette( routes=[Route("/", homepage)], middleware=[Middleware(ScoutMiddleware)], ) ``` -------------------------------- ### Run Specific Test File via Tox Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Execute tests for a specific file using tox. This is useful for focusing on a particular set of tests. ```bash tox -e py39-django31 -- tests/integration/test_django.py ``` -------------------------------- ### Manual Instrumentation with Scout APM Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Wrap synchronous or asynchronous code blocks with `scout.instrument` to create named spans. Works as a context manager or decorator (sync/async). ```python import scout_apm.api as scout # --- As a context manager --- def fetch_recommendations(user_id: int): with scout.instrument("fetch_recommendations", kind="External") as span: span.tag("user_id", user_id) # ... perform HTTP call or heavy computation ... results = [{"id": 1}, {"id": 2}] return results # --- As a sync decorator --- @scout.instrument("build_feed", kind="Custom") def build_user_feed(user_id: int): return fetch_recommendations(user_id) # --- As an async decorator --- @scout.instrument.async_("send_push_notification", kind="Job") async def notify_user(user_id: int, payload: dict): # awaited coroutine body ... pass # Calling the instrumented functions: result = build_user_feed(42) # Scout trace will show: Custom/build_feed > External/fetch_recommendations ``` -------------------------------- ### Run Scout APM Test Application Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Execute the Scout APM Python test application. This command assumes the virtual environment is activated and PYTHONPATH is set. ```bash PYTHONPATH=. tests/integration/app.py ``` -------------------------------- ### Integrate Scout APM with RQ Worker Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Replace the standard RQ `Worker` class with Scout's drop-in replacement. Each job execution is traced as `Job/` with queue time and task ID tags. ```python # worker.py import scout_apm.api as scout from scout_apm.rq import Worker # drop-in for rq.Worker from redis import Redis from rq import Queue scout.Config.set(key="abc123def456ghi7", name="My RQ Worker", monitor=True) redis_conn = Redis() def send_notification(user_id: int, message: str): # Tracked as Job/worker.send_notification print(f"Notifying user {user_id}: {message}") if __name__ == "__main__": q = Queue(connection=redis_conn) q.enqueue(send_notification, 42, "Hello!") # Use Scout's Worker instead of rq.Worker w = Worker([q], connection=redis_conn) w.work() ``` -------------------------------- ### Run Tox Tests for Specific Environment Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Execute tests using tox for a specific Python and Django version environment. Replace 'py39-django31' with your desired environment. ```bash python -m tox -e py39-django31 ``` -------------------------------- ### Flask Integration with Scout APM Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Wrap your Flask application instance with `ScoutApm`. Configuration is automatically read from Flask app config keys prefixed with `SCOUT_`. ```python from flask import Flask from scout_apm.flask import ScoutApm app = Flask(__name__) app.config["SCOUT_KEY"] = "abc123def456ghi7" app.config["SCOUT_NAME"] = "My Flask App" app.config["SCOUT_MONITOR"] = True ScoutApm(app) @app.route("/users/") def get_user(user_id): # This request is automatically traced as Controller/views.get_user return {"user_id": user_id} if __name__ == "__main__": app.run() ``` -------------------------------- ### Set Scout APM Environment Variables Source: https://github.com/scoutapp/scout_apm_python/blob/master/DEVELOPMENT.md Set environment variables required to run the Scout APM test application. Ensure you replace '' with your actual key. ```bash export SCOUT_MONITOR="True" export SCOUT_KEY="" export SCOUT_NAME="Python test" ``` -------------------------------- ### Context.add() Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Attaches arbitrary key-value metadata to the currently active tracked request or job. Tags appear in Scout's UI for filtering and searching traces. ```APIDOC ## Custom Context — `Context.add()` Attach arbitrary key-value metadata to the currently active tracked request. Tags appear in Scout's UI for filtering and searching traces. ```python from flask import Flask, g, request as flask_request from scout_apm.flask import ScoutApm from scout_apm.api import Context app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.before_request def tag_request(): # Attach user and plan info to every request trace user_id = flask_request.headers.get("X-User-Id") plan = flask_request.headers.get("X-Plan", "free") if user_id: Context.add("user_id", user_id) Context.add("plan", plan) Context.add("api_version", flask_request.headers.get("Accept-Version", "v1")) @app.route("/dashboard") def dashboard(): Context.add("widget_count", 42) # add per-view tags too return {"status": "ok"} ``` ``` -------------------------------- ### Django Integration for Scout APM Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Add `scout_apm` to `INSTALLED_APPS` in your Django settings. Scout automatically integrates middleware, instruments SQL queries and template rendering, and connects to signals for error capture. All `SCOUT_*` Django settings are read automatically. ```python # settings.py INSTALLED_APPS = [ "scout_apm", # must be first "django.contrib.admin", # ... your apps ] SCOUT_KEY = "abc123def456ghi7" SCOUT_NAME = "My Django App" SCOUT_MONITOR = True SCOUT_LOG_LEVEL = "warn" SCOUT_IGNORE_ENDPOINTS = ["healthz", "readyz"] # Optional: disable specific auto-instruments SCOUT_DISABLED_INSTRUMENTS = ["jinja2"] # Django middleware is inserted automatically — no manual MIDDLEWARE changes needed. # Scout adds MiddlewareTimingMiddleware at position 0 and ViewTimingMiddleware at end. ``` -------------------------------- ### Attach Custom Key-Value Metadata to Request Traces Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Use `Context.add()` to attach arbitrary metadata to the current request trace. This metadata can be used for filtering and searching traces in Scout's UI. Ensure Scout APM is initialized with your Flask app. ```python from flask import Flask, g, request as flask_request from scout_apm.flask import ScoutApm from scout_apm.api import Context app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.before_request def tag_request(): # Attach user and plan info to every request trace user_id = flask_request.headers.get("X-User-Id") plan = flask_request.headers.get("X-Plan", "free") if user_id: Context.add("user_id", user_id) Context.add("plan", plan) Context.add("api_version", flask_request.headers.get("Accept-Version", "v1")) @app.route("/dashboard") def dashboard(): Context.add("widget_count", 42) # add per-view tags too return {"status": "ok"} ``` -------------------------------- ### Mark Code Block as Background Job Transaction Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Use `BackgroundTransaction` to instrument custom task runners or scheduled jobs. Ensure `scout_apm.core.install` is called with your configuration. ```python from scout_apm.api import BackgroundTransaction, Context, instrument import scout_apm.core scout_apm.core.install({ "key": "abc123def456ghi7", "name": "My Scheduler", "monitor": True, }) def run_nightly_report(report_type: str): with BackgroundTransaction(name="nightly_report"): Context.add("report_type", report_type) with instrument("fetch_data", kind="SQL"): rows = [] # DB rows would go here with instrument("render_report", kind="Template"): output = f"Report: {report_type}, rows: {len(rows)}" print(output) return output run_nightly_report("revenue") # Scout trace: Job/nightly_report > SQL/fetch_data > Template/render_report ``` -------------------------------- ### Configure Scout APM Shutdown Timeout Source: https://github.com/scoutapp/scout_apm_python/blob/master/CHANGELOG.md Set a custom timeout for flushing queued commands to the core agent at shutdown. Defaults to 2 seconds. ```python shutdown_timeout_seconds=5 ``` -------------------------------- ### Error.capture() Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Manually captures and reports an exception to Scout's error monitoring service. Automatically included in integrations but can be called directly for custom error handling. ```APIDOC ## Error Monitoring — `Error.capture()` Manually capture and report an exception to Scout's error monitoring service. Automatically included in Django/Flask/Starlette/Celery integrations, but can also be called directly for custom error handling. ```python from scout_apm.api import Error, Context import scout_apm.core scout_apm.core.install(config={ "key": "abc123def456ghi7", "name": "My App", "monitor": True, }) def process_payment(order_id: int, amount: float, user_session: dict): try: if amount <= 0: raise ValueError(f"Invalid payment amount: {amount}") # ... payment processing logic ... return {"status": "success"} except Exception as exc: # Report the exception with full context Error.capture( exc, request_path=f"/payments/{order_id}", request_params={"order_id": order_id}, session=user_session, custom_controller="PaymentController.process", custom_params={"amount": amount, "currency": "USD"}, ) return {"status": "error", "message": str(exc)} result = process_payment( order_id=99, amount=-5.0, user_session={"user_id": 42, "plan": "pro"}, ) # Error appears in Scout with full traceback, path, params, and session context ``` ``` -------------------------------- ### BackgroundTransaction Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Marks a code block as a background job transaction. Useful for custom task runners or scheduled jobs outside of common frameworks. ```APIDOC ## Background Transactions — `BackgroundTransaction` Mark a code block as a background job transaction. Useful for custom task runners or scheduled jobs outside of Celery/RQ/Huey. ```python from scout_apm.api import BackgroundTransaction, Context, instrument import scout_apm.core scout_apm.core.install(config={ "key": "abc123def456ghi7", "name": "My Scheduler", "monitor": True, }) def run_nightly_report(report_type: str): with BackgroundTransaction(name="nightly_report"): Context.add("report_type", report_type) with instrument("fetch_data", kind="SQL"): rows = [] # DB rows would go here with instrument("render_report", kind="Template"): output = f"Report: {report_type}, rows: {len(rows)}" print(output) return output run_nightly_report("revenue") # Scout trace: Job/nightly_report > SQL/fetch_data > Template/render_report ``` ``` -------------------------------- ### Configure Scout APM Shutdown Message Source: https://github.com/scoutapp/scout_apm_python/blob/master/CHANGELOG.md Disable the Scout APM shutdown message by setting `shutdown_message_enabled` to false in your configuration. ```python SCOUT_SHUTDOWN_MESSAGE_ENABLED=false ``` -------------------------------- ### ignore_transaction() Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Excludes the current request or job from being reported to Scout entirely. Useful for health-check endpoints, internal pings, or noise you don't want polluting traces. ```APIDOC ## Ignoring Transactions — `ignore_transaction()` Exclude the current request or job from being reported to Scout entirely. Useful for health-check endpoints, internal pings, or noise you don't want polluting traces. ```python from flask import Flask from scout_apm.flask import ScoutApm from scout_apm.api import ignore_transaction app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.route("/healthz") def health_check(): ignore_transaction() # this request will NOT appear in Scout return {"status": "healthy"} @app.route("/metrics") def metrics(): ignore_transaction() # also excluded return {"uptime": 9999} @app.route("/orders") def orders(): # Normal — will be traced return {"orders": []} ``` ``` -------------------------------- ### Override Auto-Detected Transaction Name Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Use `rename_transaction()` to provide a custom name for the current transaction. This is useful when a single route handler performs logically distinct operations, allowing for more granular monitoring in Scout. ```python from flask import Flask, request as flask_request from scout_apm.flask import ScoutApm from scout_apm.api import rename_transaction app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.route("/api/actions", methods=["POST"]) def api_dispatch(): action = flask_request.json.get("action", "unknown") # Instead of "Controller/views.api_dispatch" for everything, # give each logical action its own name in Scout. rename_transaction(f"api/{action}") if action == "create_user": return {"created": True} elif action == "send_email": return {"queued": True} else: return {"error": "unknown action"}, 400 ``` -------------------------------- ### rename_transaction() Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Overrides the auto-detected transaction name with a custom string. Useful when a single route handler serves logically different operations. ```APIDOC ## Transaction Renaming — `rename_transaction()` Override the auto-detected transaction name with a custom string. Useful when a single route handler serves logically different operations. ```python from flask import Flask, request as flask_request from scout_apm.flask import ScoutApm from scout_apm.api import rename_transaction app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.route("/api/actions", methods=["POST"]) def api_dispatch(): action = flask_request.json.get("action", "unknown") # Instead of "Controller/views.api_dispatch" for everything, # give each logical action its own name in Scout. rename_transaction(f"api/{action}") if action == "create_user": return {"created": True} elif action == "send_email": return {"queued": True} else: return {"error": "unknown action"}, 400 ``` ``` -------------------------------- ### Exclude Current Request/Job from Scout Reporting Source: https://context7.com/scoutapp/scout_apm_python/llms.txt Call `ignore_transaction()` to prevent the current request or job from being reported to Scout. This is useful for health checks or endpoints that generate excessive noise. ```python from flask import Flask from scout_apm.flask import ScoutApm from scout_apm.api import ignore_transaction app = Flask(__name__) app.config.update(SCOUT_KEY="abc123def456ghi7", SCOUT_NAME="App", SCOUT_MONITOR=True) ScoutApm(app) @app.route("/healthz") def health_check(): ignore_transaction() # this request will NOT appear in Scout return {"status": "healthy"} @app.route("/metrics") def metrics(): ignore_transaction() # also excluded return {"uptime": 9999} @app.route("/orders") def orders(): # Normal — will be traced return {"orders": []} ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.