Skip to content

5.12.0 — 2026-10-14

← 5.12.1 | 5.11.0 → | ↑ 5.x series

Added

Configs - OpenTelemetry

  • OTEL.INSTRUMENTATION_SKIP_DEP_CHECK - Libraries that are instrumented even when the installed version is newer than the range the instrumentor declares (default ["sqlalchemy"]). opentelemetry-instrumentation-sqlalchemy still declares sqlalchemy<2.1.0, while ArchiPy requires SQLAlchemy 2.1, so SQLAlchemy produced no spans before.
    • ArchiPy logs one warning naming the mismatch when it applies the bypass
    • Set the option to [] to turn the bypass off, and remove a key once its instrumentor supports the version

Configs - Temporal

  • TEMPORAL.METRICS_PULL_PORT - Port of the Temporal SDK /metrics scrape endpoint (default 8201). With OTEL.METRICS_EXPORTER=pull the SDK serves its own endpoint on OTEL.METRICS_PULL_HOST and this port. The port must differ from OTEL.METRICS_PULL_PORT.

Adapters - Email

  • email.send span - EmailAdapter.send_email records a client span with server.address, server.port, network.protocol.name, email.tls_mode, email.recipient_count and email.attachment_count. Credentials, addresses, subject and body never reach a span. No OpenTelemetry instrumentor exists for smtplib.

Changed

Adapters - MinIO

  • Folders in non-recursive list_objects - A non-recursive listing now also returns one entry per "folder" directly below the prefix (object_name ends with /, size is 0). Every entry carries is_prefix.
    • Callers that expect only objects should skip entries where is_prefix is true

Adapters - Temporal

  • Pushgateway exporter - The Temporal SDK cannot push to a Pushgateway. With OTEL.METRICS_EXPORTER=pushgateway its metrics still go over OTLP to OTEL.OTLP_ENDPOINT, and a warning says so.

Helpers - Utils

  • Instrumentor version conflicts are visible - An instrumentor that refuses an installed library version was logged at debug level, so the service ran without spans and without a message. It is now a warning that names the library and says no spans will be emitted. A library that is not installed at all is still skipped at debug level.

Fixed

Adapters - SQLAlchemy

  • Sync engines are traced - The session manager bound create_engine at import time, before OpenTelemetry replaced it, so sync engines never emitted query spans. It is now looked up when the engine is created.

Adapters - Kafka

  • Producers and consumers are traced - Producer and Consumer were bound at import time and bypassed the OpenTelemetry instrumentor. They are now looked up when the client is created, which also covers the async adapters.

Adapters - Redis

  • Search with OpenTelemetry enabled - opentelemetry-instrumentation-redis reads the FT.SEARCH reply as a list, but RESP3, the default, returns a dict, so it raised KeyError inside the caller's search. The instrumentor helper is now guarded so an unreadable reply never reaches the application.

Adapters - Keycloak

  • Denied UMA permissions - When every requested permission is denied, Keycloak answers 403 not_authorized. check_permissions_batch raised InternalError for it, so fastapi_auth answered 500. It now returns an empty set and the request is rejected with PERMISSION_DENIED.

Adapters - Temporal

  • Tracing interceptor - TracingInterceptor used the first global tracer provider, so spans were lost after OpenTelemetry was re-initialized. It now uses the tracer ArchiPy currently owns.

Tests

  • Real containers for telemetry - New OpenTelemetry Collector and Pushgateway test containers replace in-memory exporters, stub gateways and mocked Temporal clients in otel.feature.
  • Adapter spans - Spans are verified through the collector for Redis (sync and async), Kafka (sync and async), MinIO, ScyllaDB (sync and async), Postgres, MySQL, SQLite and StarRocks (sync and async), Keycloak, Elasticsearch, Vault, Email and Temporal, plus Temporal worker and client metrics.
  • No mocks for Keycloak and gRPC - The Keycloak utils, gRPC rate limit and app_utils scenarios run against the real Keycloak container, real gRPC servers and the Redis container.
  • MinIO - New scenarios cover stat_object, listing by prefix, presigned PUT uploads, error mapping and caches.
  • HTTP clients - Test code uses httpx2 instead of requests and urllib.

Chore

  • Instrumentor compatibility check - make check-instrumentor-compat and a weekly workflow resolve each instrumentor's instruments extra together with ArchiPy's own bound with uv. The workflow fails once upstream supports the required version, the signal to drop the bypass.