Opinionated OTel compatible telemetry client SDK for Depths telemetry server.
Project description
Depths Python Client SDK
A small, opinionated Python client that sends OTLP JSON over HTTP to the Depths telemetry server. It gives you simple tracing, logging, and metrics with a friendly Python API and automatic context linking.
This library is the client for the Depths Python telemetry server. It speaks the same OTLP JSON that the server ingests at /v1/traces, /v1/logs, and /v1/metrics with the x-depths-project-id header.
Public entry point:
DepthsClient. CamelCase aliases are provided so folks moving between TypeScript and Python feel at home.
Features
- Traces with nested spans using
withandasync with - Logs that automatically carry
traceIdandspanIdwhen a span is active - Metrics: counter, gauge, and client-side histogram binning with explicit bounds and LRU capping
- Background flushing on a timer, plus synchronous
flush()andclose() - Context propagation helpers: adopt or inject W3C
traceparentheader - OTLP JSON envelopes on the wire and gzip for large payloads
Installation
Can be installed as a standalone package
pip install depths-client
and also along with the main package:
pip install "depths[client]"
If you want proto extras as well, then do:
pip install "depths[all]"
Quick start (sync)
from depths_client import DepthsClient
import time
depths = DepthsClient(
base_url="http://127.0.0.1:4318",
project_id="proj_local",
service_name="demo-sync",
flush_interval_s=1.0,
gzip=True,
)
orders = depths.metrics.counter("demo.orders")
queue = depths.metrics.gauge("demo.queue_length")
latency = depths.metrics.histogram("demo.latency_ms") # default 2-based bounds
with depths.with_trace("sync_flow") as trace:
with trace.span("work_unit"):
depths.log(level="INFO", body="starting work", attrs={"phase": "init"})
orders.add(1, {"region": "in"})
queue.record(3, {"shard": "a"})
latency.record(37, {"route": "/health"})
time.sleep(0.05)
depths.log(level="INFO", body={"status": "ok"}, attrs={"phase": "done"})
depths.flush()
depths.close()
DepthsClientrequiresbase_url,project_id, andservice_name. It builds OTLP resource attributes withservice.name,service.version,telemetry.sdk.nameandtelemetry.sdk.version.- Logs inside a span are auto linked to the active context.
- Metrics recorded inside a span carry
trace_idandspan_idin their attributes. flush()is synchronous and drains queues immediately.
Quick start (async)
import asyncio
from depths_client import DepthsClient
async def main():
depths = DepthsClient(
base_url="http://127.0.0.1:4318",
project_id="proj_local",
service_name="demo-async",
flush_interval_s=1.0,
gzip=True,
)
c = depths.metrics.counter("demo.orders")
g = depths.metrics.gauge("demo.queue_length")
h = depths.metrics.histogram("demo.latency_ms")
async with depths.trace("async_flow") as trace:
async with trace.span("awaited_work"):
depths.log(level="INFO", body="async start", attrs={"phase": "init"})
c.add(1, {"region": "in"})
g.record(2, {"shard": "b"})
h.record(12, {"route": "/ping"})
await asyncio.sleep(0.05)
depths.log(level="INFO", body={"status": "ok"}, attrs={"phase": "done"})
await depths.aflush()
await depths.aclose()
asyncio.run(main())
- Both sync and async context managers are supported for traces and spans.
aflush()andaclose()wrap synchronous operations so they can be awaited.
API overview
DepthsClient(...)
DepthsClient(
base_url: str,
project_id: str,
service_name: str,
service_version: str | None = None,
resource: dict | None = None,
flush_interval_s: float = 2.0,
max_queue: int = 200,
gzip: bool = True,
auto_instrument_httpx: bool = False
)
- Builds an OTLP Resource with service info plus any extra
resourceattributes you pass. - Starts a background flusher thread that wakes on
flush_interval_s. You can always callflush()to send data immediately. - Registers
atexitto callclose()as a safety net.
CamelCase aliases for familiarity with the TypeScript SDK: withTrace, withSpan, createTrace, adoptFromTraceparent, instrumentHttpx, flushAsync, closeAsync.
Tracing
Create a root trace and nested spans:
with depths.with_trace("checkout") as trace:
with trace.span("load-cart"):
...
with trace.span("payment") as span:
span.add_event("payment.intent.created", {"provider": "stripe"})
- Root and child spans are context managed. The active
trace_idandspan_idare set when a span enters and cleared on exit. SpanHandlesupportsadd_event,set_attributes,record_exception, andend. CamelCase aliases are also available.- Spans are exported as OTLP spans with attributes, events and status.
OKmaps to code 1 andERRORto 2.
You can also create a handle directly:
trace = depths.create_trace("sync-job", attrs={"job_id": "42"})
s1 = trace.start_span("phase-1"); ...; s1.end()
s2 = trace.start_span("phase-2"); ...; s2.end()
trace.end()
Logs
depths.log(level="INFO", body="message text", attrs={"key": "value"})
- If called inside an active span, the SDK includes the
traceIdandspanIdin the log record. - Logs are exported as OTLP
logRecordswith a string or structured body and attributes.
Metrics
# Counter (delta)
orders = depths.metrics.counter("orders.created")
orders.add(1, {"region": "eu"})
# Gauge (last value)
qlen = depths.metrics.gauge("queue.length")
qlen.record(5, {"shard": "a"})
# Histogram (client-side binning, delta)
latency = depths.metrics.histogram("http.server.latency_ms") # explicit bounds optional
latency.record(37, {"route": "/checkout"})
- Counters export as OTLP
Sumwith delta temporality and monotonic true. Gauges export as OTLPGauge. Histograms use explicit bounds and delta temporality. - Histogram bounds default to a 2-based sequence up to 65536, and you can override per instrument. Series are LRU capped per instrument by
max_series. - When a span is active, the client adds
trace_idandspan_idas metric attributes automatically.
Metrics are snapshotted and reset on each flush or close, then transported as a single batch.
Context propagation
Adopt an upstream trace:
depths.adopt_from_traceparent(request.headers.get("traceparent"))
Inject into outgoing httpx calls:
import httpx
client = httpx.Client()
depths.instrument_httpx(client)
resp = client.get("https://example.com/api") # traceparent header is set if a span is active
adopt_from_traceparentparses W3C headers and sets the active context.instrument_httpxregisters a request hook that writestraceparentfrom the current span.
Flushing and lifecycle
- The client keeps per-signal queues and a background thread that wakes on
flush_interval_s. flush()is synchronous and will drain and POST immediately.aflush()wraps this for async code.close()does a final flush and stops the thread.aclose()wraps this for async code.atexitcallsclose()as a safety net.
How data is sent to the server
- Endpoints:
POST {base_url}/v1/traces | /v1/logs | /v1/metricswithcontent-type: application/jsonandx-depths-project-idheader from your client config. - JSON is compact. The client will gzip the payload when large.
- On HTTP 413, the client splits a large batch once and retries.
This matches the Depths Python telemetry server’s ingestion expectations. The server reads the project id from the header and accepts OTLP JSON at those routes.
Defaults and limits
- Flush interval: 2.0 s, queue size: 200 per signal.
- Histogram bounds: 2-based defaults; override per instrument.
- Counter and gauge series LRU cap: 1024 entries per instrument (internal). Histogram LRU cap is configurable via
max_series. - Strings in attributes are truncated at a safe size during sanitization.
Troubleshooting
- Only some signals appear: make sure you call
flush()orclose()at the end of your flow. Flush is synchronous and will send spans, logs, and metric deltas in one go. - Trace context not linked: ensure logs and metrics are recorded while a span is active. They auto attach
trace_idandspan_idwhen called insidewith ... span. - No downstream correlation: call
instrument_httpx(client)to injecttraceparenton outgoing requests.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file depths_client-0.2.0.tar.gz.
File metadata
- Download URL: depths_client-0.2.0.tar.gz
- Upload date:
- Size: 4.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
541e952e1690b66d432e39a22193b6a648cd7f9ab998232217aadd812d034e4c
|
|
| MD5 |
9093e49b1d1a0f6e7797342effe135ea
|
|
| BLAKE2b-256 |
f03810480fa5470342f60802f9b1eaf76b5f4c63109d0a4e53632dbf1876f620
|
File details
Details for the file depths_client-0.2.0-py3-none-any.whl.
File metadata
- Download URL: depths_client-0.2.0-py3-none-any.whl
- Upload date:
- Size: 4.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.6.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20e901054e6624f1df3e4d4bc73ba6b2d603d71b70e937d3bcf6d636d4a42efc
|
|
| MD5 |
45b419afe8e9dbde3e4d3e8732968a9f
|
|
| BLAKE2b-256 |
542683967b016d7e5a84ab9c3be8e4f2699c6635b4ee854aab008b5499b9ffdd
|