Skip to main content

Lightweight OpenTelemetry collector

Project description

rotel 🌶️ 🍅

Python package for the Rotel lightweight OpenTelemetry collector.

PyPI - Version PyPI - Python Version

Description

This package provides an embedded OpenTelemetry collector, built on the lightweight Rotel collector. When started, it spawns a background daemon that accepts OpenTelemetry metrics, traces, and logs. Designed for minimal overhead, Rotel reduces resource consumption while simplifying telemetry collection and processing in complex Python applications—without requiring additional sidecar containers.

Telemetry Type Support
Metrics Alpha
Traces Alpha
Logs Alpha

How it works

By default, the Rotel agent listens for OpenTelemetry data over gRPC (port 4317) and HTTP (port 4318) on localhost. It efficiently batches telemetry signals and forwards them to a configurable OpenTelemetry protocol (OTLP) compatible endpoint.

In your application, you use the OpenTelemetry Python SDK to add instrumentation for traces, metrics, and logs. The SDK by default will communicate over ports 4317 or 4318 on localhost to the Rotel agent. You can now ship your instrumented application and efficiently export OpenTelemetry data to your vendor or observability tool of choice with a single deployment artifact.

Future updates will introduce support for filtering data, transforming telemetry, and exporting to different vendors and tools.

Getting started

Rotel configuration

Add the rotel Python package to your project's dependencies. There are two approaches to configuring rotel:

  1. typed config dicts
  2. environment variables

Typed dicts

In the startup section of your main.py add the following code block. Replace the endpoint with the endpoint of your OpenTelemetry vendor and any required API KEY headers.

from rotel import Config, Rotel

rotel = Rotel(
    enabled = True,
    exporters = {
        'otlp': Config.otlp_exporter(
            endpoint = "https://foo.example.com",
            headers = {
                "x-api-key" : settings.API_KEY,
                "x-data-set": "testing"
            }
        ),
    },
    # Define exporters per telemetry type
    exporters_traces = ['otlp'],
    exporters_metrics = ['otlp'],
    exporters_logs = ['otlp']
)
rotel.start()

Environment variables

You can also configure rotel entirely with environment variables. In your application startup, insert:

import rotel
rotel.start()

In your application deployment configuration, set the following environment variables. These match the typed configuration above:

  • ROTEL_ENABLED=true
  • ROTEL_EXPORTERS=otlp
  • ROTEL_EXPORTER_OTLP_ENDPOINT=https://foo.example.com
  • ROTEL_EXPORTER_OTLP_CUSTOM_HEADERS=x-api-key={API_KEY},x-data-set=testing
  • ROTEL_EXPORTERS_TRACES=otlp
  • ROTEL_EXPORTERS_METRICS=otlp
  • ROTEL_EXPORTERS_LOGS=otlp

Any typed configuration options will override environment variables of the same name.


See the Configuration section for the full list of options.

OpenTelemetry SDK configuration

Once the rotel collector agent is running, you may need to configure your application's instrumentation. If you are using the default rotel endpoints of localhost:4317 and localhost:4318, then you should not need to change anything.

To set the endpoint the OpenTelemetry SDK will use, set the following environment variable:

  • OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

Configuration

This is the full list of options and their environment variable alternatives. Any defaults left blank in the table are either False or None.

Option Name Type Environ Default Options
enabled bool ROTEL_ENABLED
pid_file str ROTEL_PID_FILE /tmp/rotel-agent.pid
log_file str ROTEL_LOG_FILE /tmp/rotel-agent.log
log_format str ROTEL_LOG_FORMAT text json, text
debug_log list[str] ROTEL_DEBUG_LOG traces, metrics, logs
otlp_grpc_endpoint str ROTEL_OTLP_GRPC_ENDPOINT localhost:4317
otlp_http_endpoint str ROTEL_OTLP_HTTP_ENDPOINT localhost:4318
otlp_receiver_traces_disabled bool ROTEL_OTLP_RECEIVER_TRACES_DISABLED
otlp_receiver_metrics_disabled bool ROTEL_OTLP_RECEIVER_METRICS_DISABLED
otlp_receiver_logs_disabled bool ROTEL_OTLP_RECEIVER_LOGS_DISABLED
exporter OTLPExporter | DatadogExporter | ClickhouseExporter

OTLP Exporter

To construct an OTLP exporter, use the method Config.otlp_exporter() with the following options.

Option Name Type Environ Default Options
endpoint str ROTEL_OTLP_EXPORTER_ENDPOINT
protocol str ROTEL_OTLP_EXPORTER_PROTOCOL grpc grpc or http
headers dict[str, str] ROTEL_OTLP_EXPORTER_CUSTOM_HEADERS
compression str ROTEL_OTLP_EXPORTER_COMPRESSION gzip gzip or none
request_timeout str ROTEL_OTLP_EXPORTER_REQUEST_TIMEOUT 5s
retry_initial_backoff str ROTEL_OTLP_EXPORTER_RETRY_INITIAL_BACKOFF 5s
retry_max_backoff str ROTEL_OTLP_EXPORTER_RETRY_MAX_BACKOFF 30s
retry_max_elapsed_time str ROTEL_OTLP_EXPORTER_RETRY_MAX_ELAPSED_TIME 300s
batch_max_size int ROTEL_OTLP_EXPORTER_BATCH_MAX_SIZE 8192
batch_timeout str ROTEL_OTLP_EXPORTER_BATCH_TIMEOUT 200ms
tls_cert_file str ROTEL_OTLP_EXPORTER_TLS_CERT_FILE
tls_key_file str ROTEL_OTLP_EXPORTER_TLS_KEY_FILE
tls_ca_file str ROTEL_OTLP_EXPORTER_TLS_CA_FILE
tls_skip_verify bool ROTEL_OTLP_EXPORTER_TLS_SKIP_VERIFY

Datadog Exporter

Rotel provides an experimental Datadog exporter that supports traces at the moment. To use it instead of the OTLP exporter, use the method Config.datadog_exporter() with the following options.

Option Name Type Environ Default Options
region str ROTEL_DATADOG_EXPORTER_REGION us1 us1, us3, us5, eu, ap1
custom_endpoint str ROTEL_DATADOG_EXPORTER_CUSTOM_ENDPOINT
api_key str ROTEL_DATADOG_EXPORTER_API_KEY

When configuring Rotel with only environment variables, you must set ROTEL_EXPORTER=datadog in addition to the above environment variables.

Clickhouse Exporter

Rotel provides a Clickhouse exporter with support for traces and logs. To use the Clickhouse exporter instead of the OTLP exporter, use the method Config.clickhouse_exporter() with the following options.

Option Name Type Environ Default Options
endpoint str ROTEL_CLICKHOUSE_EXPORTER_ENDPOINT
database str ROTEL_CLICKHOUSE_EXPORTER_DATABASE otel
table_prefix str ROTEL_CLICKHOUSE_EXPORTER_TABLE_PREFIX otel
compression str ROTEL_CLICKHOUSE_EXPORTER_COMPRESSION lz4
async_insert bool ROTEL_CLICKHOUSE_EXPORTER_ASYNC_INSERT true
user str ROTEL_CLICKHOUSE_EXPORTER_USER
password str ROTEL_CLICKHOUSE_EXPORTER_PASSWORD

When configuring Rotel with only environment variables, you must set ROTEL_EXPORTER=clickhouse in addition to the above environment variables.

Multiple exporters

Pyrotel supports multiple exporters, allowing you to send data to different destinations per telemetry type. Just set the exporters entry to a dict map of exporter definitions and then configure the exporters per telemetry type. For example, this will send metrics and logs to an OTLP endpoint while sending traces to Datadog:

from rotel import Config, Rotel

rotel = Rotel(
    enabled = True,
    exporters = {
        'logs_and_metrics': Config.otlp_exporter(
            endpoint = "https://foo.example.com",
            headers = {
                "x-api-key" : settings.API_KEY,
                "x-data-set": "testing"
            }
        ),
        'tracing': Config.datadog_exporter(
            api_key = "1234abcd",
        ),
    },
    # Define exporters per telemetry type
    exporters_traces = ['tracing'],
    exporters_metrics = ['logs_and_metrics'],
    exporters_logs = ['logs_and_metrics']
)
rotel.start()

Retries and timeouts

You can override the default request timeout of 5 seconds for the OTLP Exporter with the exporter setting:

  • request_timeout: Takes a string time duration, so "250ms" for 250 milliseconds, "3s" for 3 seconds, etc.

Requests will be retried if they match retryable error codes like 429 (Too Many Requests) or timeout. You can control the behavior with the following exporter options:

  • retry_initial_backoff: Initial backoff duration
  • retry_max_backoff: Maximum backoff interval
  • retry_max_elapsed_time: Maximum wall time a request will be retried for until it is marked as permanent failure

All options should be represented as string time durations.

Full OTEL example

To illustrate this further, here's a full example of how to use Rotel to send trace spans to Axiom from an application instrumented with OpenTelemetry.

The code sample depends on the following environment variables:

  • ROTEL_ENABLED=true: Turn on or off based on the deployment environment
  • AXIOM_DATASET: Name of an Axiom dataset
  • AXIOM_API_TOKEN: Set to an API token that has access to the Axiom dataset
import os

from rotel import Config, Rotel

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace.export import SimpleSpanProcessor


# Enable at deploy time with ROTEL_ENABLED=true
if os.environ.get("ROTEL_ENABLED") == "true":
    #
    # Configure Rotel to export to Axiom
    #
    otlp_exporter = Config.otlp_exporter(
        endpoint="https://api.axiom.co",
        protocol="http", # Axiom only supports HTTP
        headers={
            "Authorization": f"Bearer {os.environ['AXIOM_API_TOKEN']}",
            "X-Axiom-Dataset": os.environ["AXIOM_DATASET"],
        },
    )

    rotel = Rotel(
        enabled=True,
        exporters = {
            'axiom': otlp_exporter,
        },
        exporters_traces = ['axiom']
    )

    # Start the agent
    rotel.start()

    #
    # Configure OpenTelemetry SDK to export to the localhost Rotel
    #

    # Define the service name resource for the tracer.
    resource = Resource(
        attributes={
            SERVICE_NAME: "pyrotel-test"
        }
    )

    # Create a TracerProvider with the defined resource for creating tracers.
    provider = TracerProvider(resource=resource)

    # Create the OTel exporter to send to the localhost Rotel agent
    exporter = OTLPSpanExporter(endpoint = "http://localhost:4318/v1/traces")

    # Create a processor with the OTLP exporter to send trace spans.
    #
    # You could also use the BatchSpanProcessor, but since Rotel runs locally
    # and will batch, you can avoid double batching.
    processor = SimpleSpanProcessor(exporter)
    provider.add_span_processor(processor)

    # Set the TracerProvider as the global tracer provider.
    trace.set_tracer_provider(provider)

For the complete example, see the hello world application.

Debugging

If you set the option debug_log to ["traces"], or the environment variable ROTEL_DEBUG_LOG=traces, then rotel will log a summary to the log file /tmp/rotel-agent.log each time it processes trace spans. You can add also specify metrics to debug metrics and logs to debug logs.

FAQ

Do I need to call rotel.stop() when I exit?

In most deployment environments you do not need to call rotel.stop() and it is generally recommended that you don't. Calling rotel.stop() will terminate the running agent on a host, so any further export calls from OTEL instrumentation will fail. In a multiprocess environment, such as gunicorn, terminating the Rotel agent from one process will terminate it for all other processes. On ephemeral deployment platforms, it is usually fine to leave the agent running until the compute instance, VM/container/isolate, terminate.

Community

Want to chat about this project, share feedback, or suggest improvements? Join our Discord server! Whether you're a user of this project or not, we'd love to hear your thoughts and ideas. See you there! 🚀

Developing

See the DEVELOPING.md doc for building and development instructions.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

rotel-0.0.1a12-cp313-cp313-manylinux_2_34_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ x86-64

rotel-0.0.1a12-cp313-cp313-manylinux_2_34_aarch64.whl (6.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.34+ ARM64

rotel-0.0.1a12-cp313-cp313-macosx_10_9_universal2.macosx_12_3_arm64.whl (6.1 MB view details)

Uploaded CPython 3.13macOS 10.9+ universal2 (ARM64, x86-64)macOS 12.3+ ARM64

rotel-0.0.1a12-cp312-cp312-manylinux_2_34_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

rotel-0.0.1a12-cp312-cp312-manylinux_2_34_aarch64.whl (6.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ ARM64

rotel-0.0.1a12-cp312-cp312-macosx_10_9_universal2.macosx_12_3_arm64.whl (6.1 MB view details)

Uploaded CPython 3.12macOS 10.9+ universal2 (ARM64, x86-64)macOS 12.3+ ARM64

rotel-0.0.1a12-cp311-cp311-manylinux_2_34_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ x86-64

rotel-0.0.1a12-cp311-cp311-manylinux_2_34_aarch64.whl (6.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.34+ ARM64

rotel-0.0.1a12-cp311-cp311-macosx_10_9_universal2.macosx_12_3_arm64.whl (6.1 MB view details)

Uploaded CPython 3.11macOS 10.9+ universal2 (ARM64, x86-64)macOS 12.3+ ARM64

rotel-0.0.1a12-cp310-cp310-manylinux_2_34_x86_64.whl (6.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

rotel-0.0.1a12-cp310-cp310-manylinux_2_34_aarch64.whl (6.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ ARM64

rotel-0.0.1a12-cp310-cp310-macosx_10_9_universal2.macosx_12_3_arm64.whl (6.1 MB view details)

Uploaded CPython 3.10macOS 10.9+ universal2 (ARM64, x86-64)macOS 12.3+ ARM64

File details

Details for the file rotel-0.0.1a12-cp313-cp313-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp313-cp313-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 af71f031b45f8c842bde2b9231e970fd473f7119023b3aa527b86e772b2a52ae
MD5 ae411f5079594522dbdbc7db2cdad1f9
BLAKE2b-256 a54e2da3492730bce1baeea5d9abcceb3d23871ae79220c3b2412ce2fc736ccd

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp313-cp313-manylinux_2_34_x86_64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp313-cp313-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp313-cp313-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 909de068be0e426c7fbfa11277d4a45dc14ad619259423e5d617b152739535a3
MD5 b180c88666135867d7f0110013efa2b0
BLAKE2b-256 339e66ea32cae212a64cdd56bd299173a0dc6374dd03b3e0832920e275f16b4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp313-cp313-manylinux_2_34_aarch64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp313-cp313-macosx_10_9_universal2.macosx_12_3_arm64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp313-cp313-macosx_10_9_universal2.macosx_12_3_arm64.whl
Algorithm Hash digest
SHA256 f20b1749aedb7442850d7d56651cee74f2785265feca5918b8ce7c994e2289a5
MD5 cf108721c75145d1ccc152d622a06bb2
BLAKE2b-256 cb87af21934f3d648e4beb8a51dd618557d98d7f8302e13e353b1dd47d44b133

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp313-cp313-macosx_10_9_universal2.macosx_12_3_arm64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 4816683e9a353d13dd8c21b31233c947dcb4e4c0eb838d4d5b9cd1191cc1989c
MD5 a06f0f6a96906b3a22faecabec996e0a
BLAKE2b-256 60fc296aa61af7230d5465bff317733f9d8b1ba32b0c5fe30d28f936a1120928

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp312-cp312-manylinux_2_34_x86_64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp312-cp312-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp312-cp312-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 1bdad69b1162873666fee8278a0b73d4bc48eba56033760283da8f9cd32966b5
MD5 30c658abb1d6abe0e4f0d6d8a4d31f9c
BLAKE2b-256 89be912855be715189f5ffdaf6bd6d4ac2af08dad41246e4059ebc84db9efb45

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp312-cp312-manylinux_2_34_aarch64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp312-cp312-macosx_10_9_universal2.macosx_12_3_arm64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp312-cp312-macosx_10_9_universal2.macosx_12_3_arm64.whl
Algorithm Hash digest
SHA256 8912a7bc0e689649c9cd28b65a7988b7a6eb44700bf1ebd4a55d99909ea8fcb6
MD5 9a8835aa9db22ef50221704c7b789df9
BLAKE2b-256 2871330f982042323cc1aada3a703471320941166ca140817db35f3f1c536965

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp312-cp312-macosx_10_9_universal2.macosx_12_3_arm64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp311-cp311-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp311-cp311-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 dca518ee73f5ac5a727a7f4804794c18d09cce683b9e6c68d6b0a9d4d2c97b13
MD5 1baacabddd4611d7272d4f3afe4a02d8
BLAKE2b-256 01cb4575df70f7396fc76c687de8b204b2f41c050ee5b4d8c142f1b65cd7fa5d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp311-cp311-manylinux_2_34_x86_64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp311-cp311-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp311-cp311-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 7eac395c56f7af83bf14f4c2056c23e9e2bc941f93e1ffbf9212fde5e1b04232
MD5 aca7406c7e04dea64fd064823b4ea078
BLAKE2b-256 0cd1081dfbc2c323a97c490e5ab22623e8eb5522cc6a8dd2968ae8fca3ee85ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp311-cp311-manylinux_2_34_aarch64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp311-cp311-macosx_10_9_universal2.macosx_12_3_arm64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp311-cp311-macosx_10_9_universal2.macosx_12_3_arm64.whl
Algorithm Hash digest
SHA256 24cde17cea809b81acf9ff8b1dd68636f5e08ccf4281b16d790950982fb78184
MD5 a614d43ac57af41d404ad20d95ec7ae0
BLAKE2b-256 df1e949220733d5d94075103edf49c2e2d2565522aa84a7af471ec3f84e6a46f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp311-cp311-macosx_10_9_universal2.macosx_12_3_arm64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 bf5169feb1ca7389ccb85be780fc027a1072a59a20a75b93c7435e7b7af85abf
MD5 313731a8e1432c7665d6506f04a9c3b3
BLAKE2b-256 40ee128e3ec920048cac120666f613b52821d1bb59ff6cb2e542f080fbc916fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp310-cp310-manylinux_2_34_x86_64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp310-cp310-manylinux_2_34_aarch64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp310-cp310-manylinux_2_34_aarch64.whl
Algorithm Hash digest
SHA256 7f0140e49385afc3dc385083ea38add73cc19f9dbbf114790f774f6ec01c7177
MD5 aa169354a5868bf09cfce79491fe2219
BLAKE2b-256 e5d57786cc720442cdb9abc53a1d1d4c2d385d02046a7910c9e175b59d7f22fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp310-cp310-manylinux_2_34_aarch64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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

File details

Details for the file rotel-0.0.1a12-cp310-cp310-macosx_10_9_universal2.macosx_12_3_arm64.whl.

File metadata

File hashes

Hashes for rotel-0.0.1a12-cp310-cp310-macosx_10_9_universal2.macosx_12_3_arm64.whl
Algorithm Hash digest
SHA256 568203d7e1c1b00b8f9a91792fee352fcadd4b7ac28f1b6fddc58b8a05237e2b
MD5 366b9ee903b28626512490d8c546a4e8
BLAKE2b-256 713681ea45d338181b1fed6f53f0eecb9d55a6c3875d74d09b1c77891c1efc36

See more details on using hashes here.

Provenance

The following attestation bundles were made for rotel-0.0.1a12-cp310-cp310-macosx_10_9_universal2.macosx_12_3_arm64.whl:

Publisher: build-release.yml on streamfold/pyrotel

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