Skip to main content

jstverify-tracing

Python distributed tracing SDK for JstVerify application mapping. Auto-instruments your backend to produce trace spans that connect with the JstVerify JavaScript SDK, giving you a full frontend-to-backend service map.

Installation

pip install jstverify-tracing

With framework extras:

pip install jstverify-tracing[flask]
pip install jstverify-tracing[django]
pip install jstverify-tracing[fastapi]

Quick Start

1. Initialize (once at startup)

import jstverify_tracing

jstverify_tracing.init(
    api_key="your-sdk-key",
    service_name="my-backend",
)

The endpoint defaults to the production ingestion URL (https://sdkapi.jstverify.com/v1/tracing/spans). Override for dev environments:

jstverify_tracing.init(
    api_key="your-sdk-key",
    endpoint="https://sdkapi.dev.jstverify.com/v1/tracing/spans",
    service_name="my-backend",
)

2. Add Framework Middleware

Flask:

from jstverify_tracing.integrations.flask import JstVerifyTracingMiddleware
JstVerifyTracingMiddleware(app)

Django (settings.py):

MIDDLEWARE = [
    "jstverify_tracing.integrations.django.JstVerifyTracingMiddleware",
    ...
]

FastAPI:

from jstverify_tracing.integrations.fastapi import JstVerifyTracingMiddleware
app.add_middleware(JstVerifyTracingMiddleware)

AWS Lambda (API Gateway):

from jstverify_tracing.integrations.awslambda import JstVerifyTracingMiddleware

@JstVerifyTracingMiddleware
def lambda_handler(event, context):
    return {"statusCode": 200, "body": "ok"}

Flask / Django on AWS Lambda (via apig_wsgi, Mangum, etc.):

When running a framework app on Lambda, use the framework middleware above for tracing — but you must also call jstverify_tracing.flush() at the end of each invocation. The framework middleware buffers spans for a background flush thread, but Lambda freezes the process between invocations so that thread never runs.

# handler.py (Flask + apig_wsgi example)
from apig_wsgi import make_lambda_handler
from app import app
import jstverify_tracing

_apig_handler = make_lambda_handler(app)

def handler(event, context):
    try:
        return _apig_handler(event, context)
    finally:
        jstverify_tracing.flush()
# handler.py (Django + Mangum example)
from mangum import Mangum
from myapp.asgi import application
import jstverify_tracing

_mangum_handler = Mangum(application, lifespan="off")

def handler(event, context):
    try:
        return _mangum_handler(event, context)
    finally:
        jstverify_tracing.flush()

Note: The @JstVerifyTracingMiddleware Lambda decorator (below) handles flushing automatically — this manual flush is only needed when using framework middleware on Lambda.

AWS AppSync Lambda Resolver:

from jstverify_tracing.integrations.appsync import JstVerifyAppSyncMiddleware

@JstVerifyAppSyncMiddleware
def handler(event, context):
    return [{"id": "1", "name": "Alice"}]

The AppSync middleware extracts trace context from event["request"]["headers"] and derives the operation name from event["info"]["parentTypeName"] and event["info"]["fieldName"] (e.g. Query.listUsers). Only direct transport mode is supported — relay mode is not available for AppSync since GraphQL responses cannot carry custom HTTP headers.

3. Manual Instrumentation (optional)

from jstverify_tracing import trace, trace_span

@trace("process-payment")
def process_payment(order_id):
    ...

def handle_order(order_id):
    with trace_span("validate-order") as span:
        ...
        span.set_status(200)
    with trace_span("charge-card") as span:
        ...
        span.set_http_metadata(method="POST", url="/payments/charge", status_code=201)

4. Custom Attributes

Attach custom key-value metadata to any span. Values are coerced to strings.

Via @trace decorator:

@trace("process-payment", attributes={"env": "prod", "retries": 3})
def process_payment(order_id):
    ...

Via SpanHandle.set_attribute():

with trace_span("validate-order") as span:
    span.set_attribute("orderId", order_id)
    span.set_attribute("itemCount", len(items))
    ...

When both options and handle set the same key, the handle value wins.

5. DynamoDB Tracing

The patch_requests=True option only patches the requests HTTP library. AWS SDK calls via boto3 use urllib3 directly, so DynamoDB, S3, and SQS operations are not auto-traced.

Use the trace_dynamodb() helper to wrap individual DynamoDB operations:

from jstverify_tracing import trace_dynamodb

# Instead of: table.get_item(Key={"UserID": "123"})
result = trace_dynamodb("GetItem", table, Key={"UserID": "123"})

# Works with any DynamoDB operation
result = trace_dynamodb("Query", table, KeyConditionExpression="pk = :pk",
                        ExpressionAttributeValues={":pk": org_id})
result = trace_dynamodb("PutItem", table, Item={"UserID": "456", "name": "Alice"})

Each call creates a child span with the operation name (e.g. DynamoDB.GetItem) and the table name in metadata.

6. Shutdown

jstverify_tracing.shutdown()

Shutdown is also registered via atexit automatically.

Configuration Options

Parameter Type Default Description
api_key str required Your JstVerify SDK API key
endpoint str production URL Span ingestion endpoint URL (defaults to https://sdkapi.jstverify.com/v1/tracing/spans)
service_name str required Service name shown in the service map
service_type str "http" Service type identifier
transport str "direct" "direct" sends spans via HTTP; "relay" encodes spans into response headers
flush_interval float 5.0 Seconds between background flushes
max_queue_size int 200 Max buffered spans (circular buffer)
max_batch_size int 50 Max spans per API request
debug bool False Enable debug logging
patch_requests bool True Auto-patch requests library for outgoing HTTP tracing

How It Works

Direct Mode (default)

  1. The middleware reads X-JstVerify-Trace-Id and X-JstVerify-Parent-Span-Id headers from incoming requests (injected by the JS SDK).
  2. A root span is created for each request, with nested child spans for @trace decorated functions and trace_span context managers.
  3. Outgoing requests library calls are automatically instrumented — trace headers are injected so downstream services can continue the trace.
  4. Spans are buffered in a thread-safe queue and flushed to the JstVerify API in batches by a background daemon thread.

Relay Mode

For backends without outbound internet access (private VPC, strict firewalls), relay mode encodes spans into the X-JstVerify-Spans response header. The JstVerify JS SDK reads this header and relays the spans to the ingestion API on behalf of the backend.

jstverify_tracing.init(
    api_key="your-sdk-key",
    service_name="my-backend",
    transport="relay",  # No endpoint needed
)

How it works:

  1. Each request collects spans in a per-request buffer (async-safe via contextvars).
  2. When the response is sent, all spans are base64url-encoded into the X-JstVerify-Spans header.
  3. The JS SDK decodes the header and merges the spans into its own flush queue.

Limitations:

  • ~20-30 spans per response max due to the 7500-byte header size limit.
  • Only works for request-response flows — async background jobs have no response to carry spans.
  • Cross-origin requests require the Access-Control-Expose-Headers header (set automatically by the middleware).

License

MIT

Metadata

Release files for jstverify-tracing 0.13.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jstverify-tracing 0.13.2
File Size Uploaded
jstverify_tracing-0.13.2.tar.gz 41.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jstverify-tracing 0.13.2
File Interpreter ABI Platform
jstverify_tracing-0.13.2-py3-none-any.whl Python 3 none any Details

Total release size: 79.3 kB

Release files / jstverify_tracing-0.13.2.tar.gz

Download URL jstverify_tracing-0.13.2.tar.gz
Size 41.5 kB
Tags Source
SHA-256 checksum
How to use checksums
79eb39ef43c6bc0b4c87021c493afd1d7a1bc359cc4cd2469e4065023acef44f
BLAKE2b-256 checksum
How to use checksums
6edae1c989ce1c7bc203b33006467b1ce69daf8bb74a41f0918a0028ffff8cef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release files / jstverify_tracing-0.13.2-py3-none-any.whl

Download URL jstverify_tracing-0.13.2-py3-none-any.whl
Size 37.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b02571b20707b732887715c6d743157bcd48790c5a9b6c2e32affcf829e3307
BLAKE2b-256 checksum
How to use checksums
097f39864ba7ea447a49ebc9723a8cd810f49382875f6f6564d693ddd750154e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.11

Release history Release notifications | RSS feed

This release

0.13.2 This release

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.7

2 release files

0.10.6

2 release files

0.10.5

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page