Skip to main content

structguru

A native structured logging library with a loguru-style API.

Combines a loguru-style API — brace formatting, bind, contextualize, opt, sink management — with a native Rust renderer for maximum performance. Since v1.0, the Rust extension is the default (and only) rendering path; structlog and orjson are no longer dependencies.

Features

  • Loguru-style APIlogger.info("User {id} logged in", id=123)
  • Structured JSON output in production (rendered natively in Rust for speed)
  • Pretty colored console output in development
  • Context managementbind() for persistent context, contextualize() for request-scoped context
  • Sentry integration — redacted breadcrumbs/events with raw exceptions preserved for capture
  • stdlib interoplogger.add() sinks can also receive third-party logging records
  • RFC 5424 severity codes included in every log record
  • Native Rust runtime — rendering and output run through the bundled abi3 extension
  • Fully typed — PEP 561 compliant with strict mypy

Native processing:

  • Redaction — mask sensitive fields (passwords, tokens) by key name or regex
  • Sampling — probabilistic and rate-limited log suppression
  • Metrics — extract counters/histograms from log events via callbacks
  • Exception formatting — render exc_info as text or a structured frame dictionary
  • Off-thread logging — native Rust writer with a bounded queue and backpressure
  • OpenTelemetry — automatic trace_id/span_id injection from current span

Framework integrations (optional dependencies):

  • ASGI (FastAPI, Starlette) — request ID, timing, context binding middleware
  • Celery — task context binding and cross-worker context propagation via headers
  • Flask — before/after request hooks with request ID tracking
  • Django — logging dict config builder and request middleware
  • SQLAlchemy — slow query detection and logging
  • gRPC — server interceptor with per-RPC context binding
  • Sentry — forward log events as breadcrumbs/events with configurable severity

Installation

pip install structguru

With optional integrations:

pip install structguru[celery,flask,sentry]  # pick what you need
pip install structguru[all]                   # everything

Available extras: otel, celery, flask, django, sqlalchemy, grpc, sentry, httpx, requests, all.

Quick start

from structguru import Logger, configure, logger

# Configure once at startup
configure(service="myapp", level="DEBUG", format="json")

# Use anywhere
logger.info("Hello {name}", name="world")
# → {"logger":"...","level":"INFO","severity":6,"timestamp":"...","service":"myapp","message":"Hello world"}

# Or choose an explicit module name
log = Logger(name=__name__)

Configuration

Call configure() once at startup. Each call replaces the previous configuration: explicit keywords override environment values, which override built-in defaults. Use update() to retain existing options while changing selected ones:

from structguru import Settings, configure, get_config, update

configure(service="checkout", sensitive_patterns=[r"token=\w+"])
update(otel=True, structured_exceptions=True)  # retains service and redaction
current = get_config()  # Settings, or None after shutdown()

# Applications can load a mapping themselves; no files are read automatically.
settings = Settings.from_mapping({"service": "checkout", "level": "DEBUG"})
configure(settings)  # uses this object instead of environment values

Settings.from_env() resolves environment values without applying them; pass a mapping instead of using the process environment when testing. Settings validates Python values and freezes collections. Native regex compilation and file access are checked when configuring; failure leaves the previous runtime active. Explicit keywords, including None and built-in default values, win over the selected base.

update() never rereads the environment and requires an active runtime. An empty update does nothing. Level-only updates and set_level() preserve queues and rate-limit state; other updates rebuild writers and reset filter state. Snapshots describe configured options, not buffered records, counters, stdlib bridge state, or logger.add() sinks. Those registered sinks survive reconfiguration. Streams and callbacks retain their identity.

Levels accept case-insensitive names (including NOTSET) or non-negative integer thresholds. Unknown names, booleans and negative integers raise ValueError.

Environment configuration

Variable Default Compatibility fallback
STRUCTGURU_SERVICE app
STRUCTGURU_LEVEL INFO LOG_LEVEL
STRUCTGURU_TARGET stdout STRUCTGURU_NATIVE_TARGET
STRUCTGURU_FORMAT json
STRUCTGURU_SAMPLE_RATE 1.0 STRUCTGURU_NATIVE_SAMPLE_RATE
STRUCTGURU_RATE_LIMIT disabled; period defaults to 60 seconds STRUCTGURU_NATIVE_RATE_LIMIT
STRUCTGURU_AUTOCONFIGURE enabled inverse of STRUCTGURU_LEGACY

New names win over their fallbacks; old names remain supported without warnings. Rate limits use MAX or MAX/PERIOD, with integer counts and seconds for the period. Autoconfiguration accepts 1/0, true/false, yes/no, or on/off and controls import only. Set it to 0 before import to configure explicitly later. Invalid selected values fail validation; an invalid import-time value must be corrected or autoconfiguration disabled before the application can call configure().

File output, redaction, exceptions and other settings currently use Python configuration. The stdlib bridge retains its separate STRUCTGURU_STDLIB_* options and explicit installer.

Usage

Log levels

logger.debug("Debug message")
logger.info("Info message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")

# Aliases
logger.trace("Maps to DEBUG")
logger.success("Maps to INFO")
logger.warn("Alias for warning")
logger.fatal("Alias for critical")

Brace formatting

Arguments used in str.format placeholders are consumed by formatting (matching loguru behaviour). Extra kwargs that are not in any placeholder are forwarded as structured fields:

logger.info("User {user_id} logged in", user_id=42, ip="10.0.0.1")
# message: "User 42 logged in"
# ip: "10.0.0.1"  (extra kwarg kept as structured field)
# user_id is consumed by formatting and not duplicated

Bound context

log = logger.bind(request_id="abc-123", user="alice")
log.info("Processing request")  # includes request_id and user
log.info("Request complete")  # same context carried through

Request-scoped context

with logger.contextualize(request_id="abc-123"):
    logger.info("Handling request")  # includes request_id
    do_work()  # any logging inside also gets request_id
# request_id removed automatically

Exception logging

try:
    risky_operation()
except Exception:
    logger.exception("Operation failed")  # logs with exc_info at ERROR level

# Or with opt():
logger.opt(exception=True).error("Something went wrong")

Sink management

# Add a file sink
handler_id = logger.add("/var/log/app.log", level="ERROR")

# Add a callable sink
logger.add(lambda msg: send_to_monitoring(msg), level="CRITICAL")

# Remove a specific sink
logger.remove(handler_id)

# Remove all added sinks
logger.remove()

On Unix, new files created by either logger.add(path) or the native rotating file sink are owner-only (0600). Existing files retain their permissions.

All sink forms receive structguru records. They are also registered with the stdlib root logger for third-party records, which arrive raw (unrendered) on that path. Install the stdlib bridge to receive them rendered and redacted instead — while it is installed the raw delivery is suspended, so a sink never sees the same record twice.

Logs emitted inside a sink callback, whether it received a native record or a raw stdlib one, reach the native writer but skip callable and logger.add() sinks, preventing recursive delivery and worker deadlocks. Outside callbacks, logger.remove() waits for producers that already selected the removed sink and for raw stdlib deliveries in progress. Lifecycle calls inside a callback, including a stdlib handler's emit() on the raw path, cannot wait for the worker; previously selected deliveries finish as that worker drains. For native file/stdout mirroring, writer_metrics()["sink_errors"] includes failed destinations even when another destination successfully writes the record.

Native delivery uses the bounded callable queue and is drained on reconfiguration, shutdown(), fork, and interpreter exit. Call structguru.flush() when you need to block until buffered records have actually been written:

import structguru

logger.info("checkpoint")
structguru.flush()  # returns once the line has reached its sink

Console vs JSON output

format= selects the renderer: "json" (default, production) or "console" (colored, human-readable development output).

# JSON (production)
update(service="myapp", format="json")
# → {"logger":"...","level":"INFO","severity":6,"timestamp":"...","service":"myapp","message":"..."}

# Console (development) — colored, human-readable
update(service="myapp", format="console")
# → 2026-01-15T12:00:00.123456Z [INFO    ] Hello world

Native processing

Redaction

Mask sensitive fields automatically:

from structguru import update

update(
    sensitive_keys=["password", "token", "ssn"],
    sensitive_patterns=[r"\b\d{3}-\d{2}-\d{4}\b"],
    pattern_replacement="***",
)

Patterns run on Rust's linear-time regex engine (no ReDoS), which rejects look-around and backreferences at update() time. Most look-behinds rewrite as capture groups — (?<=password=)\S+ becomes (password=)\S+ with pattern_replacement="$1[REDACTED]", so the prefix is re-emitted and the secret is replaced (password=hunter2password=[REDACTED]). Put the capture group around the part you want to keep, never around the secret. For patterns that can't be rewritten, allow_backtracking_patterns=True opts them into a bounded backtracking engine: look-around and backreferences then work as written, at the cost of the linear-time guarantee for those patterns. If a value ever exceeds the backtrack limit, it is redacted entirely (fail-closed) rather than emitted unchecked.

update(
    sensitive_patterns=[r"(?<=password=)\S+"],
    allow_backtracking_patterns=True,
)

Sampling & rate limiting

Suppress noisy logs:

from structguru import update

update(sample_rate=0.1, rate_limit_max=5, rate_limit_period=60)

Metric extraction

Derive metrics from log events:

from structguru import MetricProcessor, update

metrics = MetricProcessor()
metrics.counter("user.login", lambda ed: login_counter.inc())
metrics.histogram("db.query", "duration_ms", lambda v, ed: query_hist.observe(v))

update(metric_processor=metrics)

Exception formatting

Render exceptions as JSON-serializable dictionaries:

from structguru import update

update(structured_exceptions=True, exception_max_frames=20)

exception_max_frames=0 omits traceback frames entirely. Negative frame and local-representation limits are rejected during configuration.

Formatted tracebacks (the default) carry CPython's per-frame position markers, the ~~~^^^ lines, and on Python 3.11+ computing them is most of the cost of logger.exception(). exception_carets=False omits them, which formats a traceback about five times faster and matches what CPython prints under PYTHONNODEBUGRANGES=1:

update(exception_carets=False)

OpenTelemetry correlation

Inject trace context into every log event:

from structguru import update

update(otel=True)  # no-op injection when opentelemetry-api is absent

Non-blocking logging

Since v1.0, log I/O is offloaded to a background thread by default. The native Rust writer uses a bounded 8192-record queue and waits for space while it is open. Set overflow="drop" to favor caller latency, or explicitly pass maxsize=0 only when an unbounded queue is acceptable.

Native runtime

structguru ships a required Rust extension that renders and enqueues logging natively, off-thread. It is auto-enabled at import time, and importing the package without the extension raises RuntimeError. The runtime does not depend on orjson; exotic values (datetime, UUID, Enum, dataclasses) are converted natively in Rust.

A field value the renderer cannot represent never fails the record. It is replaced by a marker so the message, level, remaining fields, and exception traceback still ship:

  • <unsupported: WSGIRequest> for any other object (Decimal, bytes, set, Path, request objects, ...). The marker names the type only: structguru never calls str()/repr() on an arbitrary object or reads its attributes, so nothing it holds can leak into a log line.
  • <cycle: dict> for a container that refers back to itself.
  • <max depth exceeded> beyond 64 levels of nesting.

Integers outside the 64-bit range are written as JSON numbers, non-string mapping keys are rendered as strings ({200: 3} becomes {"200": 3}), and unpaired surrogates in text become U+FFFD. Markers are redacted like any other string. The policy applies to native logger fields and to extra= fields bridged from the standard library alike.

import structguru

# Native mode is already on. Logger calls route through the Rust renderer.
structguru.logger.info("order {id} accepted", id=987)
# → JSON line written to stdout by a background writer thread

No configuration is required for the default JSON-to-stdout behavior. Call configure(...) to customize the renderer, filtering, or sinks.

import structguru

structguru.configure(service="myapp", level="INFO", file_path="/var/log/app.log")
structguru.logger.bind(request_id="abc").info("order {id} accepted", id=987)
# → JSON line written to /var/log/app.log by a background writer thread

Import-time configuration and configure() without a Settings object honor environment variables:

STRUCTGURU_LEVEL=INFO STRUCTGURU_SERVICE=myapp python -m myapp

Invalid native environment values fail import with an actionable exception. This prevents a deployment from starting while the native-only logging path is disabled.

Public API:

Symbol Purpose
configure(...) Replace rendering, filtering, redaction, and output settings.
Settings Validate reusable options; construct from Python values, a mapping, or the environment.
get_config() Return configured options, or None when shut down.
update(...) Change selected active options without rereading the environment.
shutdown() Stop the writer; logging is disabled until configure() is called.
set_level(level) Adjust the level threshold at runtime.
writer_metrics() Current writer counters (enqueued/written/dropped/depth/...) plus filter counters when active; None after shutdown.
lifecycle_metrics() Cumulative native deliveries rejected by closed writers; available after shutdown and across reconfiguration.
is_available() Compatibility helper; always True once the package has imported, because a missing extension fails import.

Behavior notes:

  • Overflow: the default maxsize=8192 uses overflow="block" to wait for queue space. Use overflow="drop" for drop-newest behavior with metrics and rate-limited warnings. maxsize=0 explicitly opts into an unbounded queue.
  • Redaction, level filtering, exceptions, and OpenTelemetry injection are supported natively; redaction covers the message and all structured string values before rendering or Sentry export. sensitive_keys overrides the default redaction keys. Rust's linear-time regex engine rejects backreferences and look-around with ValueError at configuration time.
  • Sampling & rate limiting (sample_rate, rate_limit_max, rate_limit_period) are applied as native pre-render filters — dropped records cost zero rendering. sampled and rate_limited counters are distinct from the transport dropped counter. sample_max_level restricts sampling to records at or below that level; more severe records always pass.
  • Metric hooks (metric_processor=...) invoke a structlog-style processor (e.g. MetricProcessor) for every kept record on the caller's thread, with (None, method, {"event": message, **fields}). Dropped records (level/sampling/rate-limit) never reach it; hook errors are swallowed.
  • Fork/shutdown safe — the writer is flushed on exit and respawned in forked children (gunicorn/celery prefork). Rotating-file writers sharing a path coordinate through an owner-only .lock sidecar; distributed hosts should still prefer stdout and an external collector.
  • Structured exceptions (structured_exceptions=True) render type, message, module, and frames as a dictionary, with optional redacted/truncated locals controlled by the exception_* options. Exception groups include nested members under exceptions, with the same frame limits and redaction. Traversal stops at ten nesting levels or 100 exception nodes; exceptions_truncated counts omitted direct children. Failed message conversions produce a marker instead of interrupting logging.
  • stack_info is supported natively: the stack is captured in Python and rendered in the same position as StackInfoRenderer (stack between service and message). Unlike the standard path, the stack ends at the user's calling frame (structguru-internal frames are skipped, the way structlog skips its own).
  • Console mode (format="console"): renders colored, human-readable lines instead of JSON — structguru's own stable dev format (<timestamp> [<LEVEL>] <message> k=v), with ANSI colors by default on a TTY. Override with colors=True/False.
  • File sinks (file_path=...): write to a rotating file natively. Defaults mirror RotatingFileHandler (50 MB, 5 backups); configure via file_max_bytes/file_backup_count. Set also_stdout=True to mirror output to both file and stdout (e.g. container + persistent log).
  • Callable sinks (callable_sinks=[fn, ...]): use a bounded queue (callable_queue_maxsize=1024). overflow="block" provides lossless backpressure; overflow="drop" reports callable_dropped metrics. Flush and lifecycle operations drain queued calls.
  • Sentry integration (sentry_processor=SentryProcessor(...)): receives the already-redacted event and raw exc_info only for exception capture.
  • Scope: the native renderer covers JSON and console rendering, file/stdout/callable sinks, redaction, sampling/rate limiting, metrics, exceptions, and stack information. logger.add() sinks receive native and stdlib records.

Shutdown and reconfiguration drain records already accepted by the native queue. Calls still formatting or waiting for space may be rejected when their writer closes, even in block mode. lifecycle_metrics()["rejected"] counts these native deliveries without queue-full warnings and survives shutdown and configuration changes; forked children start at zero. Another destination, such as a synchronous stream, may already have received the event. Calls begun while logging is disabled are no-ops and are not counted. See the lifecycle contract for details.

Framework integrations

ASGI (FastAPI / Starlette)

from structguru.integrations.asgi import StructguruMiddleware

app = FastAPI()
app.add_middleware(StructguruMiddleware, request_id_header="X-Request-ID")

Granian

Route Granian's server logs through StructguruHandler using --log-config, and use StructguruMiddleware for ASGI request IDs and structured summaries. The Granian integration guide includes a complete logging dictionary, application and launcher examples, and access-log options.

Celery

from structguru.integrations.celery import setup_celery_logging

setup_celery_logging(propagate_context=True, context_keys=["request_id"])
# Binds task_id/task_name to context, propagates selected keys via headers

Flask

from structguru.integrations.flask import setup_flask_logging

app = Flask(__name__)
setup_flask_logging(app, request_id_header="X-Request-ID")

Django

# settings.py
from structguru.integrations.django import build_logging_config, StructguruMiddleware

LOGGING = build_logging_config(service="myapp", level="INFO", json_logs=True)
MIDDLEWARE = ["structguru.integrations.django.StructguruMiddleware", ...]

SQLAlchemy

from structguru.integrations.sqlalchemy import setup_query_logging

setup_query_logging(engine, slow_threshold_ms=100, log_all=False)

gRPC

from structguru.integrations.grpc import StructguruInterceptor

server = grpc.server(
    futures.ThreadPoolExecutor(),
    interceptors=[StructguruInterceptor()],
)

Sentry

import logging

from structguru import update
from structguru.integrations.sentry import SentryProcessor

sentry = SentryProcessor(event_level=logging.ERROR, tag_keys=frozenset({"service"}))
update(sentry_processor=sentry)

Stdlib bridge

Third-party libraries log through the standard logging module. Installing the bridge re-emits those records through structguru, so they share the same JSON / console formatting, redaction, and output stream as your own logs:

from structguru.integrations.stdlib import install_stdlib_bridge

bridge = install_stdlib_bridge(
    level="INFO",
    suppress_loggers=("urllib3", "botocore"),
    disable_existing_loggers=False,
)

import logging

logging.getLogger("sqlalchemy.engine").info("SELECT 1")
# → {"logger":"sqlalchemy.engine","level":"INFO",...,"message":"SELECT 1"}

While the bridge is installed, logger.add() sinks receive third-party records only through it — rendered once, never also raw. Pass the returned handler to uninstall_stdlib_bridge() to restore the previous behavior.

Installing a second bridge while one is active raises RuntimeError. When logging setup legitimately runs more than once per process (a Django manage.py that imports a Celery app module, repeated setup in test suites), pass replace=True to release the previous bridge first — last call wins:

bridge = install_stdlib_bridge(level="INFO", replace=True)

The swap is atomic for callers: a record logged by another thread during it is delivered at most once (rendered, raw, or dropped — never twice). Suppression levels applied by the earlier install are not reverted, and calling uninstall_stdlib_bridge() on the replaced handler is a no-op.

disable_existing_loggers=True disables named stdlib loggers that already exist at installation time; False re-enables them, following dictConfig semantics. When the option is omitted, install_stdlib_bridge() reads STRUCTGURU_STDLIB_DISABLE_EXISTING_LOGGERS; if the variable is also unset, existing states are preserved. Explicit Python values override the environment. An empty environment value is treated as unset.

STRUCTGURU_STDLIB_DISABLE_EXISTING_LOGGERS=false python -m myapp

To configure all bridge options from environment variables at a controlled point in application startup:

STRUCTGURU_STDLIB_LEVEL=INFO \
STRUCTGURU_STDLIB_DISABLE_EXISTING_LOGGERS=false \
python -m myapp
from structguru.integrations.stdlib import install_stdlib_bridge_from_env

bridge = install_stdlib_bridge_from_env()

Requirements

  • Python 3.11+
  • The compiled Rust extension (shipped as abi3 wheels for Linux/macOS/Windows)

Documentation & Examples

Development

uv sync --all-extras
uv run pytest
make bench
uv run ruff check .
uv run mypy src/

License

MIT — Copyright (c) 2025 Aleksandr Pavlov

Download files

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

Source Distribution

structguru-1.3.0.tar.gz (121.0 kB view details)

Uploaded Source

Built Distributions

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

structguru-1.3.0-cp311-abi3-win_amd64.whl (963.6 kB view details)

Uploaded CPython 3.11+Windows x86-64

structguru-1.3.0-cp311-abi3-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

structguru-1.3.0-cp311-abi3-musllinux_1_2_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

structguru-1.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.0 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

structguru-1.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (986.8 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

structguru-1.3.0-cp311-abi3-macosx_11_0_arm64.whl (934.3 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

structguru-1.3.0-cp311-abi3-macosx_10_12_x86_64.whl (969.4 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file structguru-1.3.0.tar.gz.

File metadata

  • Download URL: structguru-1.3.0.tar.gz
  • Upload date:
  • Size: 121.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for structguru-1.3.0.tar.gz
Algorithm Hash digest
SHA256 986ad9bbb4d47db8a3f7798f35917e0c111186274f051feeeb91256516490b9f
MD5 19b12b8c0c5baf45b5f2affb4efc5742
BLAKE2b-256 5bd0ba511c5f3c39dc41d34f40c721848ef264aa8ea2fad3f57fc99ce5d51a50

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0.tar.gz:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: structguru-1.3.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 963.6 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for structguru-1.3.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 11293dcfbc006084c272c3217c379bf565817523b5c62736ac0492bea9f0da25
MD5 a45d1291a607d877749966e2dd6dda35
BLAKE2b-256 f455ddeaaea0a8ec9f3e688ecbf954e0ebc1d3f42bc6be024e0bb1012f81b140

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-win_amd64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 da0f2f89f93903ca31c914491d308e332c524274b0e74e22a5f25adb70b16519
MD5 2d4d8f6248872c5ac92f173085e07ee3
BLAKE2b-256 71cf92dfc23bf8fd02deda95e98dea9bf174b4ef485803f14caa7e99aac40154

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 486dbdcd65c36105ca45e9d1d53d9eaafb0f552b9bc464704663a78815926671
MD5 3fdcc916597c0c28719226e6f4630316
BLAKE2b-256 efd8b995315741de2bb93e6076ba9abd0942a9036031ce052d4ac3b8603c4959

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 64a53849ea60600780fc1609bd0d38bb0bb28aeb898dba82fae7ff9501e7c544
MD5 da5e4414632a23edfdb4bb58d5ddb2b4
BLAKE2b-256 b063f516077dcc59f3d188771cf43356589d5b6ee062b7894348556dd2d28f8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d5f7cf3e91728194fdd46d0a9f9ffa2bfe30e13c2b677274927a85b02fe03056
MD5 5083872ecbdaab81ef296e6664bcf713
BLAKE2b-256 36dad57a4ae5d3d24b728c4f8c7b7af2dcb2f4539bcba6e474df4338af3ad6f9

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bf6ee50b44b72a4a12dc7335cf5eae098bd48659be060376a63d1c9d0e2f365a
MD5 df323784c5ac1d15cb4ad27d5a72fbe5
BLAKE2b-256 d51ff6d44ebdce7cf9dd5845d160aefdd105f1d1072162495324e0b7c4317bf8

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: wheels.yml on kidoz/structguru

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

File details

Details for the file structguru-1.3.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for structguru-1.3.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d00a591a78fcd46560fba9ea7c15068dad233b7abdbd6da2551c63403ee6371d
MD5 8b01ae1503efa1fc45aa21b87ba39ee1
BLAKE2b-256 b518a209d4f3194491170cf8fd163c09deae80d90e6e7c97a84f603d7a8f7674

See more details on using hashes here.

Provenance

The following attestation bundles were made for structguru-1.3.0-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: wheels.yml on kidoz/structguru

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

Release history Release notifications | RSS feed

1.3.1

8 files

This release

1.3.0 This release

8 files

1.2.3

8 files

1.2.2

8 files

1.2.1

8 files

1.2.0

8 files

1.1.0

8 files

1.0.6

8 files

1.0.5

8 files

1.0.4

8 files

1.0.3

8 files

1.0.2

8 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page