Add your description here
Project description
🧪: PROBIRKA
Async health checks for monitoring purposes
Installation
pip install probirka
Basic usage
from asyncio import sleep, run
from dataclasses import asdict
from pprint import pprint
from probirka import Probirka, make_fastapi_endpoint
checks = Probirka()
checks.add_info("project", "example")
checks.add_info("version", "0.1.0")
@checks.add()
def ok_check():
5 / 1
@checks.add()
def error_check():
5 / 0
@checks.add()
async def async_check():
await sleep(1)
async def main():
results = await checks.run()
pprint(asdict(results))
if __name__ == "__main__":
run(main())
# {'elapsed': datetime.timedelta(seconds=1, microseconds=1506),
# 'extra': {'project': 'example', 'version': '0.1.0'},
# 'ok': False,
# 'results': [{'elapsed': datetime.timedelta(microseconds=7),
# 'error': None,
# 'name': 'ok_check',
# 'ok': True,
# 'started_at': datetime.datetime(2024, 6, 4, 23, 1, 53, 471363)},
# {'elapsed': datetime.timedelta(microseconds=4),
# 'error': 'division by zero',
# 'name': 'error_check',
# 'ok': False,
# 'started_at': datetime.datetime(2024, 6, 4, 23, 1, 53, 471376)},
# {'elapsed': datetime.timedelta(seconds=1, microseconds=1259),
# 'error': None,
# 'name': 'async_check',
# 'ok': True,
# 'started_at': datetime.datetime(2024, 6, 4, 23, 1, 53, 471383)}],
# 'started_at': datetime.datetime(2024, 6, 4, 23, 1, 53, 471324)}
Custom probes
from asyncio import run
import os
from typing import Optional
import asyncpg
from probirka import ProbeBase, Probirka
class PGCheck(
ProbeBase,
):
def __init__(
self,
dsn: str,
name: Optional[str] = None,
timeout: Optional[int] = None,
is_optional: bool = False,
) -> None:
self._dsn = dsn
super().__init__(
name=name,
timeout=timeout,
is_optional=is_optional,
)
async def _check(
self,
) -> Optional[bool]:
conn = None
try:
conn = await asyncpg.connect(dsn=self._dsn)
await conn.fetch("SELECT 1")
finally:
if conn:
await conn.close()
return True
checks = Probirka()
async def main():
checks.add_probe(
PGCheck(dsn=os.environ['PG_DSN']),
)
results = await checks.run()
assert results.ok
if __name__ == "__main__":
run(main())
Mask your secrets
from asyncio import run
from dataclasses import asdict
from pprint import pprint
from probirka import Probirka, JsonRegularTypes
def mask_sensitive_data(
name: str,
value: JsonRegularTypes,
) -> JsonRegularTypes:
if "secret" in name or "secret" in value:
return "***"
return value
checks = Probirka(
mask_sensitive_info_data_cb=mask_sensitive_data,
)
checks.add_info("project", "example")
checks.add_info("version", "0.1.0")
checks.add_info("top_secret_one", "wow")
checks.add_info(
"settings",
{
"top_secret_two": 123456,
"foo": "bar",
"baz": ["top@secret", "something"],
},
)
async def main():
results = await checks.run()
pprint(asdict(results))
if __name__ == "__main__":
run(main())
# {'checks': [],
# 'info': {'project': 'example',
# 'settings': {'baz': ['***', 'something'],
# 'foo': 'bar',
# 'top_secret_two': '***'},
# 'top_secret_one': '***',
# 'version': '0.1.0'},
# 'ok': True,
# 'started_at': datetime.datetime(2024, 6, 5, 10, 56, 20, 736558),
# 'total_elapsed': datetime.timedelta(microseconds=10)}
FastAPI endpoint
from fastapi import FastAPI
from uvicorn import run
from probirka import Probirka, make_fastapi_endpoint
app = FastAPI()
checks = Probirka()
checks.add_info("project", "fastapi example")
checks.add_info("version", "0.1.0")
@checks.add()
def empty_check():
pass
if __name__ == "__main__":
app.add_api_route(
"/health",
endpoint=make_fastapi_endpoint(checks, return_results=False),
)
app.add_api_route(
"/self-check",
endpoint=make_fastapi_endpoint(checks, with_optional=True),
)
run(app)
AIOHTTP endpoint
from aiohttp import web
from probirka import Probirka, make_aiohttp_endpoint
app = web.Application()
checks = Probirka()
checks.add_info("project", "fastapi example")
checks.add_info("version", "0.1.0")
@checks.add()
def empty_check():
pass
if __name__ == "__main__":
app.router.add_get(
"/health",
handler=make_aiohttp_endpoint(checks, return_results=False),
)
app.router.add_get(
"/self-check",
handler=make_aiohttp_endpoint(checks, with_optional=True),
)
web.run_app(app)
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
probirka-0.3.0a1.tar.gz
(118.8 kB
view details)
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 probirka-0.3.0a1.tar.gz.
File metadata
- Download URL: probirka-0.3.0a1.tar.gz
- Upload date:
- Size: 118.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e47124fc03bd8e3784255d1cf0c830d5ca309e88ba6ed25fcecf00efbca5a6f8
|
|
| MD5 |
3b9be225e49c7f4fc0d91115fedc0a19
|
|
| BLAKE2b-256 |
c475f84a99d621660759e2ffe8302d9f12cd7e169a4d283ff2e74d418bb380be
|
File details
Details for the file probirka-0.3.0a1-py3-none-any.whl.
File metadata
- Download URL: probirka-0.3.0a1-py3-none-any.whl
- Upload date:
- Size: 6.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a29b8df505d8aaeeff4f125c536939421ff86ff62c491a17d1473db5727e13c
|
|
| MD5 |
cd37d70a6221aaa1f6b9bccd1eaba8ba
|
|
| BLAKE2b-256 |
943e87859e77c0961632e8e0e3be322fe9485c90794f0dde85b25057581fdc2d
|