Repository navigation
Releases
Releases · appKODE/probirka
0.9.0
Added
HttpProbePolicy, a security policy for the HTTP probes, passed aspolicy=toHttpHttpxProbe,HttpHttpx2ProbeandHttpAiohttpProbe. Its fields:allowed_schemes(('http', 'https')by default),allowed_hosts(exact names or*.example.comwildcards),block_private_networks(loopback, private, link-local including169.254.169.254, carrier-grade NAT, multicast, unspecified and reserved ranges),blocked_networksandallowed_networks(CIDR lists, the latter wins),follow_redirectsandmax_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 asHttpProbePolicyViolation, aProbeFailure. The defaults accept anyhttp/httpsURL 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,POSTbecomesGETon301/302/303, request headers are not sent to a different origin, and more thanmax_redirectshops is a failure. The behaviour is the same for httpx, httpx2 and aiohttp (#14)
Changed
HttpAiohttpProbeno longer follows redirects by default; a3xxresponse is now'ProbeFailure: unexpected status 302'unless it is inexpected_statusor the policy hasfollow_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_urlis 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
Added
allow_failurefor 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-levelok, so HTTP integrations keep returningsuccess_code(#11)- Group-level override:
add_probes(..., groups='external', allow_failure=True)(orFalse) 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. Passingallow_failurewithoutgroupsraisesValueError(#11) ProbeResult.allow_failure(also into_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
Basiccredentials httpx and aiohttp derive fromuser:pass@) and the values of its request headers, andProbeResult.errorhas'***'wherever a client library echoed them.to_dict()additionally masks values ofinfounder sensitive-looking keys (password,api_key,Authorization, ...) and passwords in URLs and?token=-like query parameters in every string,errorincluded.ProbeBase._register_secrets()does the same for custom probes;probirka.mask_url(),probirka.redact_value()andprobirka.MASKare exported for your own handlers. See Secrets (#13)
Changed
ProbirkaResult.okisTruewhen every probe withoutallow_failurepassed; the overall timeout setsok=Falseonly if a probe withoutallow_failuredid not finish, whileerrorstill reports the timeout (#11)to_dict()masks secrets by default;to_dict(redact=False)returnsinfoanderrorexactly 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 usesfastapi.encoders.jsonable_encoder, which fell back tovars(obj)for arbitrary objects ininfoand thereby serialized their whole__dict__. Objects that are not JSON types are now written as theirstr()in every integration (#13)
0.7.0
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 othermake_*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 withuvicorn health:health_app(#10)MissingDependencyError(anImportError) 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 toProbeResult.error(#8)CallableProbeis exported from theprobirkapackage; 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_atis timezone-aware in the local zone of the host, soto_dict()and every HTTP integration now emit an ISO 8601 timestamp with a UTC offset (#9)elapsedand the TTL cache are measured withtime.monotonic()instead of the wall clock, so clock adjustments no longer distort durations or cache expiry (#9)CallableProbefalls back to the class name for callables without__name__(functools.partial, objects with__call__) instead of raisingAttributeError(#9)groupsandwith_groupsaccept anySequence[str], not justlist(#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_endpointandmake_django_vieware imported fromprobirkaas before, resolved lazily (#8) probirkastays dependency-free; client libraries and frameworks are installed separately (no extras) (#8)
Fixed
ProbeResult.elapsedno 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
Fixed
CallableProbeawaits awaitables returned by plain callables (e.g. objects withasync def __call__), which previously were reported as passed without running (#7)- Replaced deprecated
asyncio.iscoroutinefunctionwithinspect.iscoroutinefunction(removal scheduled for Python 3.16) (#7) - Per-probe
success_ttl=0/failed_ttl=0now 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
Added
make_django_view— Django (>= 4.2) async view integrationProbeResult.to_dict()andProbirkaResult.to_dict()— JSON-compatible representation shared by all integrations
Changed
- All integrations return the same JSON format:
started_atas ISO 8601,elapsedin seconds (float)
0.5.0
Added
ProbirkaResult.errorwith the reason when the overall timeout is hitProbe.nameproperty- Python 3.14 support
py.typedmarker
Fixed
Probirka.run()no longer raisesTimeoutErroron the overall timeout: unfinished probes are reported as failed, finished ones keep their results, and the response getsok=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 ProbeBaseis abstract: a subclass without_checkfails at instantiation instead of silently reporting a failed checkProbeResult.okis always abool- Unknown groups passed to
run()are ignored instead of being registered as empty groups