Skip to main content

Record function calls with composable logs and Maybe results (cronista: a Python port of chronicler)

Project description

cronista

A Python port of the R package chronicler: decorate functions to return an enhanced "chronicle" that contains the computed value, detailed logs, optional inspectors, and diffs. It composes across steps, so you can trace entire pipelines. Values are wrapped in Maybe using talvez, allowing safe propagation of failures (Nothing) without exceptions.

Installation

pip install -e .

Quick start

import math
from cronista import record, unveil, read_log

r_sqrt = record(math.sqrt)
a = r_sqrt(16)

print(unveil(a, "value"))  # 4.0

# Pretty log (default style), includes Total line and inline messages on failures
print("\n".join(read_log(a, style="pretty")))

Chaining decorated functions

from numpy import sqrt, exp, sum
from cronista import record, unveil

r_sqrt = record(sqrt)
r_exp = record(exp)
r_mean = record(lambda xs: sum(xs) / len(xs))

b = r_sqrt([1.0, 2.0, 3.0]).bind_record(r_exp).bind_record(r_mean)
print(unveil(b, "value"))

Logging styles

  • read_log(.c, style="pretty"): short, human-friendly lines like OK \sqrt` at ... (0.000s), and failures include their message. Appends Total: ... secs`.
  • read_log(.c, style="table"): returns {"rows": [...], "total_runtime_secs": float} with columns ops_number, status, function, start_time, end_time, run_time_secs, message.
  • read_log(.c, style="errors-only"): if all steps succeeded, returns a single string summarising success; otherwise returns only the failed steps with their messages.
from cronista import record, read_log

def boom(_):
    raise RuntimeError("kapow")

r_ok = record(lambda x: x + 1)
r_boom = record(boom, strict=1)

out = r_ok(1).bind_record(r_boom)

print(read_log(out, style="pretty"))      # human lines + Total
print(read_log(out, style="table"))       # dict with rows + total
print(read_log(out, style="errors-only")) # only the failing steps

Error handling

If a step fails, Nothing propagates and subsequent steps are logged as NOK without being executed:

r_inv = record(lambda x: 1 / x, strict=1)
bad = r_inv(0).bind_record(r_sqrt)
print(bad)           # NOK
print(read_log(bad)) # NOK lines, with short-circuit info

Condition handling (strict)

  • strict=1: only exceptions fail the step (warnings/messages are ignored).
  • strict=2: warnings also fail the step.
  • strict=3: warnings and printed messages (stdout) fail the step.

This mirrors chronicler’s “errors / warnings / messages” behavior using Python’s warnings and captured stdout.

Advanced logging

  • Inspector g: record a function of the output (e.g., size/shape).
from cronista import record, check_g

r_len = record(lambda s: s.strip(), g=len)
out = r_len("  hello  ")
print(check_g(out))  # [{'ops_number': 1, 'function': '<lambda>', 'g': 5}]
  • Diffs: compare input snapshot vs output snapshot.
from cronista import record, check_diff

r_upper = record(lambda s: s.upper(), diff="summary")
out = r_upper("Hello")
print(check_diff(out))  # summary of insertions/deletions/matches

r_upper_full = record(lambda s: s.upper(), diff="full")
print(check_diff(r_upper_full("Hello"))[0]["diff_obj"])  # unified diff lines
  • Access detailed log rows:
from cronista import unveil
rows = unveil(out, "log_df")
for row in rows:
    print(row["ops_number"], row["outcome"], row["function"], row["run_time"])

Notes

  • Values are wrapped using talvez: success → Just(value), failure → Nothing().
  • bind_record mirrors chronicler’s bind_record(): composes recorded functions and their logs, short-circuiting on Nothing.
  • The implementation mirrors chronicler’s vignettes and README; see the original docs for conceptual background on monads and the Maybe pattern.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cronista-0.0.9.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cronista-0.0.9-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file cronista-0.0.9.tar.gz.

File metadata

  • Download URL: cronista-0.0.9.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cronista-0.0.9.tar.gz
Algorithm Hash digest
SHA256 ad5c60bd2d81f9a7d83d2dbf4d8a8fed9ffffd3292ecf3547ba2488ae4cd7d09
MD5 89ef4294bc3dafb0e526aff60edf3cf0
BLAKE2b-256 5d5da9b791c91cc64c28067d9d2d07751b50629263ec7c3b63848328e23ab14f

See more details on using hashes here.

Provenance

The following attestation bundles were made for cronista-0.0.9.tar.gz:

Publisher: publish_pypi.yaml on b-rodrigues/cronista

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cronista-0.0.9-py3-none-any.whl.

File metadata

  • Download URL: cronista-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 7.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cronista-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 a47fe269a9b6209af20a484ede96f5aad46e4eb1a1e486cf847661ee8546bae0
MD5 9536c18130d555a58adbec3ad64724ce
BLAKE2b-256 a3c66ce9921f46a2bbeb8d3f904a90fd6e3cc540ce7dbd860899e2c63331f7e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for cronista-0.0.9-py3-none-any.whl:

Publisher: publish_pypi.yaml on b-rodrigues/cronista

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page