Skip to main content

juniper-observability

PyPI Python 3.12+ License: MIT

Shared observability primitives for the Juniper platform — health models, structured logging, middleware, and crash-safe Prometheus collector registration.

juniper-observability is the single place every Juniper service gets its cross-cutting observability wiring, so each service doesn't re-implement it: Pydantic health-response models for the /v1/health/ready endpoint, structured-JSON logging with request_id propagation, the Starlette RequestIdMiddleware and PrometheusMiddleware, idempotent prometheus_client collector helpers, the matching pytest reset fixture, and Sentry initialisation.

The collector helpers are the headline. Registering a Counter / Gauge / Histogram / … twice — across a module reload or a pytest-fixture reset — normally raises Duplicated timeseries in CollectorRegistry. register_or_reuse adopts the existing collector instead, so registration is safe to repeat.

Part of the Juniper platform. juniper-observability is the shared observability layer of Juniper — a multi-package ML research platform built around constructive (Cascade-Correlation) and recurrent neural networks. It's a small infrastructure library; you don't need the rest of the platform to use it.

Install

pip install juniper-observability                 # core
pip install "juniper-observability[prometheus]"   # + Prometheus middleware/utilities
pip install "juniper-observability[sentry]"       # + Sentry init
pip install "juniper-observability[all]"          # everything

It is also pulled in by the meta-package's juniper-ml[tools] and juniper-ml[all] extras.

Quick start

from prometheus_client import CollectorRegistry, Counter
from juniper_observability import register_or_reuse

registry = CollectorRegistry()
c1 = register_or_reuse(Counter, "demo_total", "demo counter", registry=registry)
c2 = register_or_reuse(Counter, "demo_total", "demo counter", registry=registry)
assert c1 is c2   # the second call adopts the existing collector — no exception

For tests that touch collector state, use the canonical reset fixture:

from juniper_observability.testing import reset_prometheus_registry  # pytest fixture

What's in the box

Surface What it gives you
register_or_reuse / register_fresh / register_info_or_update / lazy_register_or_reuse Idempotent prometheus_client collector registration (adopt-existing is the default).
testing.reset_prometheus_registry Pytest fixture that resets collector state between tests.
RequestIdMiddleware, PrometheusMiddleware Starlette middlewares applied across the service fleet.
Health-response models Pydantic models for the /v1/health/ready endpoint.
Structured-JSON logging Logging configuration with request_id propagation.
Sentry init configure_sentry passes include_local_variables=False (no switch to turn locals back on) and the SEC-10 before_send hook always runs. The hook also deletes frame vars.

configure_sentry never captures frame locals. Sentry's EventScrubber redacts locals by name, and the local that held the configured API key during the comparison in the juniper-canopy#683 finding is not on that list. The before_send hook deletes vars as well, because the opt-in PureEvalIntegration (sentry-sdk 2.58.0) writes them without consulting include_local_variables. Releases up to and including 0.4.0 use the SDK default (True). There is no parameter to turn locals back on.

Operator notes: juniper-ml REFERENCE.

Per-service metrics stay in each repo. This package exposes only cross-cutting infrastructure; service-specific metric definitions (training-loop counters, dataset-gen histograms, websocket gauges) live in their owning repo and register via register_or_reuse against prometheus_client.REGISTRY.

Consumers

The service repos — juniper-data, juniper-cascor, juniper-canopy — import the middlewares, health models, and collector helpers (pin >=0.2.0). The client libraries (juniper-data-client, juniper-cascor-client) pull it in via their [observability] extra for X-Request-ID propagation and Prometheus counters.

Status

Live on PyPI, published independently of the meta-package on juniper-observability-v* tags. The current version is shown by the badge above; see CHANGELOG.md. Consumers pin juniper-observability>=0.2.0.

Compatibility policy — pinning, not deprecation cycles

This package ships no deprecation machinery: no DeprecationWarning, no PendingDeprecationWarning, no legacy aliases. That is deliberate, not an oversight (defect-register APD-ECO-007).

While pre-1.0, compatibility is managed by external pinning — consumers pin a floor and a ceiling, so each 0.x is a compatibility boundary and a breaking change is absorbed by a ceiling raise the consumer performs deliberately. That holds while the consumer set is a known, enumerable handful of first-party repositories.

What would change this: a third-party dependant, or 1.0 — at which point the consumer set stops being enumerable and a census stops being a sufficient substitute for a deprecation cycle. When that happens, reuse the implementations this ecosystem already has rather than writing a third: juniper_config_tools.env_with_legacy_alias for env-var renames, and the juniper-data-client alias pattern (a DeprecationWarning with a correct stacklevel and a dated removal window) for API renames. Re-derivation is exactly how the env-var lookup drifted across three services before it was consolidated.

Design

Part of the Juniper ML research platform. Rationale and history:

License

MIT — see LICENSE.

Metadata

Release files for juniper-observability 0.4.1

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

Source distribution (sdist)

Source distribution for juniper-observability 0.4.1
File Size Uploaded
juniper_observability-0.4.1.tar.gz 47.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for juniper-observability 0.4.1
File Interpreter ABI Platform
juniper_observability-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 77.5 kB

Release files / juniper_observability-0.4.1.tar.gz

Download URL juniper_observability-0.4.1.tar.gz
Size 47.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e60245ce9c9ba78009e4eacc2157de73c4a9eb02d9dfb0ec90fdc2990b564e37
BLAKE2b-256 checksum
How to use checksums
08f518d8b664153180a0cd564ec032ca0b5af391601a8e896463c34236fb0fda
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release files / juniper_observability-0.4.1-py3-none-any.whl

Download URL juniper_observability-0.4.1-py3-none-any.whl
Size 29.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
85ca34d908b0dbcb30ddece4d9384ec767ea8f72c7559e89c06bb3a28223ee40
BLAKE2b-256 checksum
How to use checksums
438911611a646b80947940c5c774aef7e15a86ad41b7db5418a702c01bb1169e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

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