Skip to content

Releases

0.9.0

Choose a tag to compare

@shpaker shpaker released this 13 Sep 13:01

Added

  • HttpProbePolicy, a security policy for the HTTP probes, passed as policy= to HttpHttpxProbe, HttpHttpx2Probe and HttpAiohttpProbe. Its fields: allowed_schemes (('http', 'https') by default), allowed_hosts (exact names or *.example.com wildcards), block_private_networks (loopback, private, link-local including 169.254.169.254, carrier-grade NAT, multicast, unspecified and reserved ranges), blocked_networks and allowed_networks (CIDR lists, the latter wins), follow_redirects and max_redirects. The URL is checked at construction (ValueError) and before every request; when a network rule is set the host name is resolved first and refused if any address is blocked. Violations are reported as HttpProbePolicyViolation, a ProbeFailure. The defaults accept any http/https URL and do not follow redirects. See Security policy (#14)
  • Redirects are followed by the probe itself when follow_redirects=True: every target is checked against the policy before it is requested, POST becomes GET on 301/302/303, request headers are not sent to a different origin, and more than max_redirects hops is a failure. The behaviour is the same for httpx, httpx2 and aiohttp (#14)

Changed

  • HttpAiohttpProbe no longer follows redirects by default; a 3xx response is now 'ProbeFailure: unexpected status 302' unless it is in expected_status or the policy has follow_redirects=True. All HTTP probes send their requests with the client library's automatic following disabled (#14)
  • The URL of an HTTP probe must be absolute with an allowed scheme and is validated in the constructor. A relative URL paired with a client configured with base_url is no longer accepted (#14)
  • HttpProbeBase._request_status(client) is replaced by _request(client, method, url, headers) returning (status, location), for subclasses that adapt another client library (#14)

0.8.0

Choose a tag to compare

@shpaker shpaker released this 13 Sep 10:16

Added

  • allow_failure for non-critical probes, named after the GitLab CI option: ProbeBase(allow_failure=True), @probirka.add(allow_failure=True) and the same keyword on every ready-made probe. Such a probe runs and is reported as usual, but its failure or timeout does not affect the top-level ok, so HTTP integrations keep returning success_code (#11)
  • Group-level override: add_probes(..., groups='external', allow_failure=True) (or False) applies to every probe of the group, replacing the probes' own setting; None (default) keeps it. A probe run through several sources (the required list, several groups) is allowed to fail only if every source allows it. Passing allow_failure without groups raises ValueError (#11)
  • ProbeResult.allow_failure (also in to_dict() and the HTTP JSON) with the effective value for the run (#11)
  • Secrets are masked in health check output. Every ready-made probe registers the password of its connection string (as written, URL-decoded and as the Basic credentials httpx and aiohttp derive from user:pass@) and the values of its request headers, and ProbeResult.error has '***' wherever a client library echoed them. to_dict() additionally masks values of info under sensitive-looking keys (password, api_key, Authorization, ...) and passwords in URLs and ?token=-like query parameters in every string, error included. ProbeBase._register_secrets() does the same for custom probes; probirka.mask_url(), probirka.redact_value() and probirka.MASK are exported for your own handlers. See Secrets (#13)

Changed

  • ProbirkaResult.ok is True when every probe without allow_failure passed; the overall timeout sets ok=False only if a probe without allow_failure did not finish, while error still reports the timeout (#11)
  • to_dict() masks secrets by default; to_dict(redact=False) returns info and error exactly as produced. The HTTP integrations always return masked output (#13)
  • All HTTP integrations render the body through the same json.dumps(..., default=...) call; the FastAPI adapter no longer uses fastapi.encoders.jsonable_encoder, which fell back to vars(obj) for arbitrary objects in info and thereby serialized their whole __dict__. Objects that are not JSON types are now written as their str() in every integration (#13)

0.7.0

Choose a tag to compare

@shpaker shpaker released this 12 Sep 17:02

Added

  • Ready-made probes, importable from probirka: TcpProbe (no dependencies), PostgresAsyncpgProbe, RedisProbe, HttpHttpxProbe, HttpHttpx2Probe, HttpAiohttpProbe, KafkaAiokafkaProbe, RabbitmqAiopikaProbe, MongoPymongoProbe, MongoMotorProbe. Each accepts an existing client (or a zero-argument function returning one) or a connection string (#8)
  • make_asgi_app — a generic ASGI 3 application serving the same JSON body and the same options as the framework adapters. It needs no third-party package at all, so unlike the other make_* names it is always importable: register it as a route (Route('/health', app, methods=['GET', 'HEAD']) in Starlette), mount it (app.mount(...) in FastAPI, asgi('/health', is_mount=True) in Litestar), or serve it on its own port with uvicorn health:health_app (#10)
  • MissingDependencyError (an ImportError) raised on access to a probe or adapter whose client library is not installed; a library that is installed but too old keeps its original error (#8)
  • ProbeFailure — exception for "the service answered, but not in a healthy way"; its message goes to ProbeResult.error (#8)
  • CallableProbe is exported from the probirka package; names that need a third-party package are resolved lazily and listed in __all__ only when their package is installed (#8)

Changed

  • Minimum supported Python is 3.11; the test matrix covers 3.11 through 3.15 (#9)
  • started_at is timezone-aware in the local zone of the host, so to_dict() and every HTTP integration now emit an ISO 8601 timestamp with a UTC offset (#9)
  • elapsed and the TTL cache are measured with time.monotonic() instead of the wall clock, so clock adjustments no longer distort durations or cache expiry (#9)
  • CallableProbe falls back to the class name for callables without __name__ (functools.partial, objects with __call__) instead of raising AttributeError (#9)
  • groups and with_groups accept any Sequence[str], not just list (#9)
  • Type checking moved from mypy to ty; annotations use PEP 585/604 syntax throughout (#9)
  • Framework adapter modules are private now (probirka._ext.*); make_fastapi_endpoint, make_aiohttp_endpoint and make_django_view are imported from probirka as before, resolved lazily (#8)
  • probirka stays dependency-free; client libraries and frameworks are installed separately (no extras) (#8)

Fixed

  • ProbeResult.elapsed no longer includes the time spent looking up the TTL cache (#9)

Full changelog: https://github.com/appKODE/probirka/blob/main/CHANGELOG.md

0.6.1

Choose a tag to compare

@shpaker shpaker released this 11 Sep 10:16

Fixed

  • CallableProbe awaits awaitables returned by plain callables (e.g. objects with async def __call__), which previously were reported as passed without running (#7)
  • Replaced deprecated asyncio.iscoroutinefunction with inspect.iscoroutinefunction (removal scheduled for Python 3.16) (#7)
  • Per-probe success_ttl=0 / failed_ttl=0 now disables caching instead of falling back to the global TTL (#6)

Full changelog: https://github.com/appKODE/probirka/blob/main/CHANGELOG.md

0.6.0

Choose a tag to compare

@shpaker shpaker released this 11 Sep 09:35
9d89279

Added

  • make_django_view — Django (>= 4.2) async view integration
  • ProbeResult.to_dict() and ProbirkaResult.to_dict() — JSON-compatible representation shared by all integrations

Changed

  • All integrations return the same JSON format: started_at as ISO 8601, elapsed in seconds (float)

0.5.0

Choose a tag to compare

@shpaker shpaker released this 11 Sep 08:46
61969d4

Added

  • ProbirkaResult.error with the reason when the overall timeout is hit
  • Probe.name property
  • Python 3.14 support
  • py.typed marker

Fixed

  • Probirka.run() no longer raises TimeoutError on the overall timeout: unfinished probes are reported as failed, finished ones keep their results, and the response gets ok=False
  • Probe errors include the exception type; timeouts are reported explicitly instead of an empty string
  • Synchronous probes run in the default executor, so they do not block the event loop and respect timeout
  • ProbeBase is abstract: a subclass without _check fails at instantiation instead of silently reporting a failed check
  • ProbeResult.ok is always a bool
  • Unknown groups passed to run() are ignored instead of being registered as empty groups

0.4.1

Choose a tag to compare

@shpaker shpaker released this 02 Apr 06:33
  • Fix incorrect cache status reporting
  • Fix empty info dict initialization
  • Fix cache expiration behavior
  • Rename HealthCheckResult to ProbirkaResult for consistency

0.4.0

Choose a tag to compare

@shpaker shpaker released this 01 Apr 15:16
  • Cache support for probe results with configurable TTL
  • Info field support for storing probe metadata
  • Comprehensive integration tests for FastAPI and aiohttp

0.3.2

Choose a tag to compare

@shpaker shpaker released this 02 Jan 09:20
feat: extend health checks

0.3.1

Choose a tag to compare

@shpaker shpaker released this 01 Jan 17:42
  • add docstrings and data in README.md generated with co-pilot