{"id":8463,"library":"py-zipkin","title":"py-zipkin","description":"py-zipkin is a Python library that provides utilities, including a context manager and decorator, to facilitate the usage of Zipkin for distributed tracing in Python applications. It enables instrumenting code to send trace data to a Zipkin collector. The library is actively maintained with irregular releases, the latest being v1.2.8 released in early 2023.","status":"active","version":"1.2.8","language":"en","source_language":"en","source_url":"https://github.com/Yelp/py_zipkin","tags":["tracing","zipkin","distributed-tracing","observability","microservices"],"install":[{"cmd":"pip install py-zipkin","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for running the library.","package":"python","version":">=3.7"},{"reason":"Commonly used for HTTP-based transport handlers to send spans to a Zipkin collector.","package":"requests","optional":true}],"imports":[{"symbol":"zipkin_span","correct":"from py_zipkin.zipkin import zipkin_span"},{"symbol":"create_http_headers_for_new_span","correct":"from py_zipkin.zipkin import create_http_headers_for_new_span"},{"symbol":"ZipkinAttrs","correct":"from py_zipkin.zipkin import ZipkinAttrs"},{"symbol":"Kind","correct":"from py_zipkin.zipkin import Kind"},{"symbol":"BaseTransportHandler","correct":"from py_zipkin.transport import BaseTransportHandler"},{"note":"The `py_zipkin.thread_local` module is deprecated. Use `py_zipkin.storage.ThreadLocalStack` instead, especially in cooperative multitasking environments.","wrong":"from py_zipkin.thread_local import ThreadLocalStack","symbol":"ThreadLocalStack","correct":"from py_zipkin.storage import ThreadLocalStack"},{"symbol":"Stack","correct":"from py_zipkin.storage import Stack"},{"symbol":"SpanStorage","correct":"from py_zipkin.storage import SpanStorage"}],"quickstart":{"code":"import requests\nimport os\nfrom py_zipkin.zipkin import zipkin_span\nfrom py_zipkin.transport import BaseTransportHandler\n\n# Configure your Zipkin collector endpoint (e.g., http://localhost:9411/api/v2/spans)\nZIPKIN_COLLECTOR_ENDPOINT = os.environ.get('ZIPKIN_COLLECTOR_ENDPOINT', 'http://localhost:9411/api/v2/spans')\n\n# A simple HTTP transport handler for demonstration\nclass HTTPTransportHandler(BaseTransportHandler):\n    def send(self, encoded_span):\n        # The collector expects a thrift-encoded list of spans.\n        try:\n            requests.post(\n                ZIPKIN_COLLECTOR_ENDPOINT,\n                data=encoded_span,\n                headers={'Content-Type': 'application/x-thrift'},\n                timeout=5\n            )\n        except requests.exceptions.RequestException as e:\n            print(f\"Failed to send span to Zipkin: {e}\")\n\n    def get_max_payload_bytes(self):\n        return None # No explicit limit for this example\n\n\ndef do_stuff(a, b):\n    print(f\"Doing stuff with {a} and {b}\")\n    return a + b\n\n# Instantiate the transport handler\nmy_transport_handler = HTTPTransportHandler()\n\n# Usage as a context manager\ndef my_function(x, y):\n    with zipkin_span(\n        service_name='my_python_service',\n        span_name='my_function_span',\n        transport_handler=my_transport_handler,\n        port=8000, # Optional: Port of the service\n        sample_rate=100.0 # Sample all traces for demonstration (0.0 - 100.0)\n    ) as zipkin_context:\n        result = do_stuff(x, y)\n        zipkin_context.update_binary_annotations({'input_x': x, 'input_y': y, 'result': result})\n        print(f\"Trace for my_function completed with result: {result}\")\n        return result\n\n# Usage as a decorator\n@zipkin_span(\n    service_name='my_python_service',\n    span_name='decorated_function',\n    transport_handler=my_transport_handler,\n    sample_rate=50.0\n)\ndef another_function(data):\n    print(f\"Processing data: {data}\")\n    return data.upper()\n\nif __name__ == \"__main__\":\n    print(\"--- Running context manager example ---\")\n    my_function(10, 20)\n\n    print(\"\\n--- Running decorator example ---\")\n    another_function(\"hello world\")\n    print(\"Check your Zipkin UI (e.g., http://localhost:9411/zipkin) for traces.\")","lang":"python","description":"This quickstart demonstrates how to use `py_zipkin` with a custom HTTP transport handler to send traces to a Zipkin collector. It shows `zipkin_span` used both as a context manager and a decorator to instrument functions and add binary annotations. A Zipkin server (e.g., `openzipkin/zipkin`) should be running and accessible at `ZIPKIN_COLLECTOR_ENDPOINT` (defaulting to `http://localhost:9411/api/v2/spans`)."},"warnings":[{"fix":"Migrate to `py_zipkin.storage.ThreadLocalStack` for thread-local storage or explicitly pass `Stack` and `SpanStorage` instances in cooperative multitasking environments like `asyncio`.","message":"The `py_zipkin.thread_local` module and its functionalities are deprecated. Direct usage should be replaced.","severity":"deprecated","affected_versions":"<1.2.0"},{"fix":"Implement your transport handler by subclassing `py_zipkin.transport.BaseTransportHandler` and implementing the `send` and `get_max_payload_bytes` methods.","message":"Older transport handler implementations that were simple functions taking a single `encoded_span` argument are deprecated.","severity":"deprecated","affected_versions":"<1.0.0"},{"fix":"The V2 span format only supports a single 'remoteEndpoint' (represented by the 'sa' annotation). Ensure you add 'sa' binary annotations only once per span.","message":"Using `add_sa_binary_annotation` multiple times for the same span in Zipkin V2 span format (which `py-zipkin` predominantly uses) will raise a `ValueError`.","severity":"gotcha","affected_versions":"All versions supporting V2 span format."},{"fix":"Avoid relying on 'Firehose mode' for critical production workflows due to its experimental status and potential for breaking changes or removal.","message":"The 'Firehose mode' feature is explicitly marked as experimental and may be removed without prior warning.","severity":"gotcha","affected_versions":"All versions where 'Firehose mode' is available."}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the Zipkin collector is running and its HTTP API endpoint is correctly configured and reachable from your application. Check firewall rules or container network settings if applicable. Example: `docker run -p 9411:9411 openzipkin/zipkin`","cause":"The Zipkin collector is not running or is not accessible at the specified endpoint (e.g., `http://localhost:9411/api/v2/spans`).","error":"requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionRefusedError(111, 'Connection refused'))"},{"fix":"Refactor your transport handler to subclass `py_zipkin.transport.BaseTransportHandler` and implement `send(self, encoded_span)` and `get_max_payload_bytes(self)`.","cause":"Your custom transport handler is implemented as a function with one argument (`encoded_span`) but `py-zipkin` is calling it expecting a method of a class (which implicitly includes `self` as the first argument). This typically happens if you haven't correctly subclassed `BaseTransportHandler` for your transport.","error":"TypeError: send() takes 2 positional arguments but 3 were given"},{"fix":"For cooperative multitasking, explicitly pass instances of `py_zipkin.storage.Stack` as `context_stack` and `py_zipkin.storage.SpanStorage` as `span_storage` to `zipkin_span` and `create_http_headers_for_new_span`.","cause":"By default, `py_zipkin` uses thread-local storage for trace attributes, which is not suitable for cooperative multitasking (e.g., `asyncio`) or complex multithreading without explicit context management.","error":"Error in thread_local context or unexpected trace breakage in asynchronous/multithreaded environments."}]}