$npx -y skills add getsentry/sentry-for-ai --skill sentry-span-streaming-pythonMigrate Python SDK to Sentry span streaming (span-first trace lifecycle). Use when asked to "enable span streaming", "migrate to span streaming", "use trace_lifecycle stream", or switch from transaction-based to streamed span delivery in a Python project.
| 1 | > [All Skills](../../SKILL_TREE.md) > [Feature Setup](../sentry-feature-setup/SKILL.md) > Span Streaming (Python) |
| 2 | |
| 3 | # Sentry Span Streaming Migration (Python) |
| 4 | |
| 5 | Migrate from the default transaction-based trace lifecycle (`static`) to span streaming (`stream`), where spans are sent individually as they complete instead of being batched into a transaction at the end. |
| 6 | |
| 7 | This skill covers the Python SDK. For JavaScript, see [Span Streaming (JavaScript)](../sentry-span-streaming-js/SKILL.md). For Dart/Flutter, see [Span Streaming (Dart)](../sentry-span-streaming-dart/SKILL.md). |
| 8 | |
| 9 | ## Invoke This Skill When |
| 10 | |
| 11 | - User asks to "enable span streaming" or "migrate to span streaming" in a Python project |
| 12 | - User wants to switch from transaction-based to streamed span delivery |
| 13 | - User mentions `trace_lifecycle`, `sentry_sdk.traces`, or the new `start_span` API |
| 14 | - User wants lower latency span delivery or per-span processing |
| 15 | |
| 16 | --- |
| 17 | |
| 18 | ### Detect Environment |
| 19 | |
| 20 | ```bash |
| 21 | # Find sentry_sdk.init calls |
| 22 | grep -rn "sentry_sdk\.init\|sentry_sdk\.init(" --include="*.py" -l 2>/dev/null | head -20 |
| 23 | |
| 24 | # Find existing start_span / start_transaction / start_child usage |
| 25 | grep -rn "start_span\|start_transaction\|start_child" --include="*.py" -l 2>/dev/null | head -20 |
| 26 | |
| 27 | # Find trace decorator usage |
| 28 | grep -rn "@trace\|from sentry_sdk import trace\|from sentry_sdk.tracing import trace" --include="*.py" -l 2>/dev/null | head -20 |
| 29 | |
| 30 | # Find continue_trace usage |
| 31 | grep -rn "continue_trace" --include="*.py" -l 2>/dev/null | head -20 |
| 32 | |
| 33 | # Find before_send_transaction usage |
| 34 | grep -rn "before_send_transaction" --include="*.py" -l 2>/dev/null | head -20 |
| 35 | |
| 36 | # Find direct Span / Transaction class imports |
| 37 | grep -rn "from sentry_sdk.tracing import\|from sentry_sdk import.*Span\|from sentry_sdk import.*Transaction" --include="*.py" -l 2>/dev/null | head -20 |
| 38 | |
| 39 | # Find set_data / set_tag / set_context on spans |
| 40 | grep -rn "set_data\|set_tag\|set_context" --include="*.py" -l 2>/dev/null | head -20 |
| 41 | |
| 42 | # Find scope.span / scope.transaction / containing_transaction access |
| 43 | grep -rn "scope\.span\|scope\.transaction\|containing_transaction" --include="*.py" -l 2>/dev/null | head -20 |
| 44 | |
| 45 | # Find get_trace_context usage |
| 46 | grep -rn "get_trace_context" --include="*.py" -l 2>/dev/null | head -20 |
| 47 | ``` |
| 48 | |
| 49 | ### Parallelization |
| 50 | |
| 51 | After detecting the environment, assess how many files need changes. If the codebase has many files to migrate (e.g. dozens of files with `start_span`, `start_transaction`, `set_data`, etc.), launch subagents to handle independent migration tasks in parallel — for example, one subagent per migration category (span creation, span data, trace propagation) or per module/package. Each subagent should receive the relevant migration rules from this skill and operate on a distinct set of files. |
| 52 | |
| 53 | ### Enable Span Streaming |
| 54 | |
| 55 | **Prerequisites:** `sentry-sdk` `>=2.66.0` with tracing enabled (`traces_sample_rate` or `traces_sampler` configured). |
| 56 | |
| 57 | Add the top-level `trace_lifecycle` option in ALL occurences of `sentry_sdk.init()`: |
| 58 | |
| 59 | ```python |
| 60 | import sentry_sdk |
| 61 | |
| 62 | # Before |
| 63 | sentry_sdk.init( |
| 64 | dsn="...", |
| 65 | traces_sample_rate=1.0, |
| 66 | ) |
| 67 | |
| 68 | # After |
| 69 | sentry_sdk.init( |
| 70 | dsn="...", |
| 71 | traces_sample_rate=1.0, |
| 72 | trace_lifecycle="stream", |
| 73 | ) |
| 74 | ``` |
| 75 | |
| 76 | Span streaming requires using the new `sentry_sdk.traces.start_span` API. The legacy `sentry_sdk.start_span` and `sentry_sdk.start_transaction` APIs will not stream spans. |
| 77 | |
| 78 | ### Migrate Span Creation |
| 79 | |
| 80 | #### `start_span` |
| 81 | |
| 82 | Replace `sentry_sdk.start_span()` with `sentry_sdk.traces.start_span()`: |
| 83 | |
| 84 | ```python |
| 85 | import sentry_sdk |
| 86 | |
| 87 | # Before |
| 88 | with sentry_sdk.start_span(name="flow.checkout") as span: |
| 89 | ... |
| 90 | |
| 91 | # After |
| 92 | with sentry_sdk.traces.start_span(name="flow.checkout") as span: |
| 93 | ... |
| 94 | ``` |
| 95 | |
| 96 | Or change the import: |
| 97 | |
| 98 | ```python |
| 99 | # Before |
| 100 | from sentry_sdk import start_span |
| 101 | |
| 102 | # After |
| 103 | from sentry_sdk.traces import start_span |
| 104 | ``` |
| 105 | |
| 106 | The new API accepts: |
| 107 | - `name` (required) |
| 108 | - `attributes` — key-value pairs (see Migrate Span Data below) |
| 109 | - `parent_span` — explicit parent span; defaults to the currently active span |
| 110 | - `active` — defaults to `True`; if `False`, the span won't become other spans' parent automatically |
| 111 | |
| 112 | The `description` argument no longer exists — use `name` instead. The `op` argument is no longer supported — use the `sentry.op` attribute instead: |
| 113 | |
| 114 | ```python |
| 115 | # Before |
| 116 | with sentry_sdk.start_span(op="http.client", description="GET /api/users") as span: |
| 117 | ... |
| 118 | |
| 119 | # After |
| 120 | with sentry_sdk.traces.start_span( |
| 121 | name="GET /api/users", |
| 122 | attributes={"sentry.op": "http.client"}, |
| 123 | ) as span: |
| 124 | ... |
| 125 | ``` |
| 126 | |
| 127 | #### `start_transaction` |
| 128 | |
| 129 | Replace `sentry_sd |