Skip to main content

Säckli

This is a friendly fork of bagz.

Additions so far:

  • Merge some PRs such as S3 support PR by @KefanXIAO and compile fixes.
  • Add access_pattern and cache_policy reader hints:
    • On POSIX filesystems, this can add mmap hints or use pread-based no-cache reads to optimize for random access and larger-than-RAM data.
    • On Linux, support O_DIRECT for even better reading of random access and larger-than-RAM data.
    • On macOS, support F_NOCACHE, MAP_NOCACHE, and madvise-based cache hints on Apple silicon.
  • Make it compatible to Python versions past 3.13.
  • Make it compatible with free-threading (nogil) Python.
  • Add macOS support and wheels.
  • Add CI, stress-tests and automatic wheel releases to PyPI for Linux x86_64, Linux aarch64, and macOS arm64 (macOS 14+).

Säckli uses independent semantic versioning and does not track upstream Bagz releases.

Overview

Säckli is a format for storing a sequence of byte-array records. It supports per-record compression and fast index-based lookup. All indexing is zero based.

Installation

The recommended installation on Linux and Mac is via the pre-built wheels on PyPI. Releases include Linux x86_64 and aarch64 wheels, plus macOS arm64 wheels for macOS 14+:

uv pip install sackli

If you want to build locally to work on this, just uv pip install .. However, building can be slow because of GCS and S3 support; to skip both of these dependencies for much faster builds, you can do:

CMAKE_ARGS="-DSACKLI_ENABLE_GCS=OFF -DSACKLI_ENABLE_S3=OFF" uv pip install .

Python API

Python Reader

Reader for reading a single or sharded Säckli file-set.

from collections.abc import Sequence, Iterable

import sackli
import numpy as np

# Säckli Readers support random access. The order of elements within a Säckli
# file is the order in which they are written. Records are returned as `bytes`
# objects.
data = sackli.Reader('/path/to/data.bagz')

# Säckli Readers can be configured like this - here we require that the file was
# written with separate limits. All options can be passed directly as keyword
# arguments, and enum values can be given as (case-insensitive) strings:
data_separate_limits = sackli.Reader('/path/to/data.bagz',
                                     limits_placement='separate')

# The equivalent explicit form:
data_separate_limits = sackli.Reader('/path/to/data.bagz', sackli.Reader.Options(
    limits_placement=sackli.LimitsPlacement.SEPARATE,
))

# Säckli Readers are Sequences and support slicing, iterating, etc.
assert isinstance(data, Sequence)

# Säckli Readers have a length.
assert len(data) > 10

# Can access record by row-index.
fifth_value: bytes = data[5]

# Can slice.
data_from_5: sackli.Reader = data[5:]

# Slices are still Readers.
assert isinstance(data_from_5, sackli.Reader)

assert data_from_5[0] == fifth_value

# Can access records by multiple row-indices.
fourth, second, tenth = data.read_indices([4, 2, 10])
assert fourth == data[4]
assert second == data[2]
assert tenth == data[10]

# Can iterate records.
for record in data:
  do_something_else(record)

# Can read all records. This eager version can be faster than iteration.
all_records = data.read()

# Can iterate sub-range of records.
for record in data[4:9]:
  do_something_else(record)

# Can read a sub-range of records. This eager form can be faster than
# iteration.
sub_range = data[4:9].read()

# Can use an infinite iterator as source of indices. (Reads ahead in parallel.)
def my_generator(size: int) -> Iterable[int]:
  rng = np.random.default_rng(42)
  while True:
    yield rng.integers(size).item()

data_iter: Iterable[bytes] = data.read_indices_iter(my_generator(len(data)))
for i in range(10):
  random_item: bytes = next(data_iter)

Note that the Sequence methods value in reader, reader.count(value) and reader.index(value) scan the records linearly — on a huge file-set they read (and decompress) everything up to the first match. Use sackli.Index / sackli.MultiIndex if you need repeated record lookups.

Readers hold open file handles (and mmaps) until garbage collected. They can be closed eagerly with reader.close() or by using the reader as a context manager; the underlying files close once the last handle sharing them (the reader, slices made from it, and live iterators) is closed or collected.

with sackli.Reader('/path/to/data.bagz') as data:
  first = data[0]

Python Reader - Index and MultiIndex

You can use Index to find the first index of a record and MultiIndex to find all instances of an item.

keys = sackli.Reader('/path/to/keys.bag')
# Get the index of the first occurrence of key.
index = sackli.Index(keys)
key_index: int = index[b'example_key']

# Get all occurrences of key.
multi_index = sackli.MultiIndex(keys)
all_indices: list[int] = multi_index[b'example_key']

Python Writer

For writing a single Säckli file.

Example:

import sackli

# Compression is selected based on the file extension:
# `.bagz` will use Zstandard compression with default settings.
# `.bag` will use no compression.
with sackli.Writer('/path/to/data.bagz') as writer:
  for d in generate_records():
    writer.write(d)

# Adjust compression level explicitly.
# Note this will no longer use the extension to detemine whether to compress.
with sackli.Writer(
    '/path/to/data.bagz',
    compression=sackli.CompressionZstd(level=3),
) as writer:
  for d in generate_records():
    writer.write(d)

Options

All options can be given either bundled in an Options object (sackli.Reader(path, sackli.Reader.Options(...))) or directly as keyword arguments (sackli.Reader(path, cache_policy='drop_after_read')); keyword arguments override the corresponding Options field. Enum-valued options accept the case-insensitive name of an enum value (e.g. 'random', 'in_memory'), and compression accepts 'auto', 'none' or 'zstd'.

Reader Options

sackli.Reader.Options has these optional arguments.

  • compression: Can be one of:
    • sackli.CompressionAutoDetect(): Default - Uses extension whether to compress. (.bagz - Compressed (ZStandard), .bag - Uncompressed)
    • sackli.CompressionNone(): Records are not decompressed.
    • sackli.CompressionZstd(): Records are decompressed using Zstandard.
  • limits_placement: Can be one of:
    • sackli.LimitsPlacement.TAIL: Default- Reads limits from a tail of file.
    • sackli.LimitsPlacement.SEPARATE: Reads limits from a separate file.
  • limits_storage: Can be one of:
    • sackli.LimitsStorage.ON_DISK: Default - Reads limits from disk for each read.
    • sackli.LimitsStorage.IN_MEMORY: Reads all limits from disk in one go.
  • access_pattern: Can be one of:
    • sackli.AccessPattern.SYSTEM: Default - no specific hint to the OS.
    • sackli.AccessPattern.RANDOM: Hints that you read entries in random order.
    • sackli.AccessPattern.SEQUENTIAL: Hints that you read entries roughly sequentially.
  • cache_policy: Can be one of:
    • sackli.CachePolicy.SYSTEM: Default - no specific hint to the OS.
    • sackli.CachePolicy.DROP_AFTER_READ: Reads data in such a way that the OS is unlikely to hold any of it in cache. For POSIX filesystems, this means using OS-specific no-cache hints: Linux uses pread with posix_fadvise, while macOS uses MAP_NOCACHE plus madvise for mmap-backed reads and F_NOCACHE for streaming reads. This is more efficient when you read more data than your RAM before doing any repeats (ie when an epoch is larger than RAM).
    • sackli.CachePolicy.DIRECT_IO: Uses O_DIRECT on Linux and F_NOCACHE on macOS to read records. This is the most aggressive os-cache avoidance option and can be best for random reads on huge data with rare re-reads. Linux empirically probes direct-I/O alignment from 512 bytes, caches the result per device, and treats STATX_DIOALIGN only as a hint. If direct I/O cannot be validated, it falls back to pread with cache-dropping advice. For the unaligned tail, it does a one-time standard read at init.
  • max_parallelism: Default number of threads when reading many records.
  • read_ahead_bytes: Byte budget that sizes the record batches the iterators read ahead (default 1 MiB). For compressed files, the budget counts compressed on-disk bytes; decompressed records can require substantially more RAM, especially for high compression ratios or large records. The double-buffered iterator can hold up to two batches in flight, so this is a sizing heuristic rather than a memory bound. The read_ahead argument of read_indices_iter/read_range_iter, which counts records, takes precedence when given.
  • sharding_layout: Can be one of:
    • sackli.ShardingLayout.CONCATENATED: Default - See Sharding
    • sackli.ShardingLayout.INTERLEAVED: See Sharding

access_pattern and cache_policy are currently interpreted only for local POSIX files and influence OS-level behaviour on page cache and cache lines.

For tail-formatted files, non-default POSIX record-cache policies open a second POSIX read handle to the same file so limits metadata reads keep the default cache policy.

Writer Options

sackli.Writer.Options has these optional arguments.

  • compression: Can be one of:
    • sackli.CompressionAutoDetect(): Default - Uses extension whether to compress. (.bagz - Compressed (Zstandard), .bag - Uncompressed)
    • sackli.CompressionNone(): Records are not compressed.
    • sackli.CompressionZstd(level = 3): Records are compressed using Zstandard the level of the compression can be specified.
  • limits_placement: Can be one of:
    • sackli.LimitsPlacement.TAIL: Default - Writes limits to a tail of file.
    • sackli.LimitsPlacement.SEPARATE: Writes limits to a separate file.

Sharding

An ordered collection of Säckli-formatted files ("shards") may be opened together and indexed via a single global-index. The global-index is mapped to a shard and an index within that shard (shard-index) in one of two ways:

  1. Concatenated (default). Indexing is equivalent to the records in each Säckli-formatted shard being concatenated into a single sequence of records.

    Example:

    When opening four Säckli-formatted files with sizes [8, 4, 0, 5], the global-index with range [0, 17) (shown as the table entries) maps to shard and shard-index like this:

                   | shard-index
    shard          |  0  1  2  3  4  5  6  7
    -------------- | -----------------------
    00000-of-00004 |  0  1  2  3  4  5  6  7
    00001-of-00004 |  8  9 10 11
    00002-of-00004 |
    00003-of-00004 | 12 13 14 15 16
    

    Mappings

    global-index shard shard-index
    0 00000-of-00004 0
    1 00000-of-00004 1
    2 00000-of-00004 2
    ... ... ...
    8 00001-of-00004 0
    9 00001-of-00004 1
    ... ... ...
    15 00003-of-00004 3
    16 00003-of-00004 4
  2. Interleaved where the global-index is interleaved in a round-robin manner across all the shards.

    Example:

    When opening three Säckli-formatted files with sizes [6, 6, 5], the global-index with range [0, 17) (shown as the table entries) maps to shard and shard-index like this:

                   |  shard-index
    shard          |  0  1  2  3  4  5
    -------------- | -----------------
    00000-of-00003 |  0  3  6  9 12 15
    00001-of-00003 |  1  4  7 10 13 16
    00002-of-00003 |  2  5  8 11 14
    

    Mappings

    global-index shard shard-index
    0 00000-of-00003 0
    1 00001-of-00003 0
    2 00002-of-00003 0
    ... ... ...
    6 00000-of-00003 2
    7 00001-of-00003 2
    8 00002-of-00003 2
    ... ... ...
    15 00000-of-00003 5
    16 00001-of-00003 5

Apache Beam Support

Säckli also provides Apache Beam connectors for reading and writing Säckli files in Beam pipelines.

Ensure you have Apache Beam installed.

uv pip install apache_beam

Säckli Source

import apache_beam as beam
from sackli.beam import sacklio
import tensorflow as tf

with beam.Pipeline() as pipeline:
  examples = (
      pipeline
      | 'ReadData' >> sacklio.ReadFromSackli('/path/to/your/data@*.bagz')
      | 'Decode' >> beam.Map(tf.train.Example.FromString)
  )
  # Continue your pipeline.

Säckli Sink

from sackli.beam import sacklio
import tensorflow as tf

def create_tf_example(data):
  # Replace with your actual feature creation logic.
  feature = {
      'data': tf.train.Feature(bytes_list=tf.train.BytesList(value=[data])),
  }
  return tf.train.Example(features=tf.train.Features(feature=feature))

with beam.Pipeline() as pipeline:
  data = [b'record1', b'record2', b'record3']

  examples = (
      pipeline
      | 'CreateData' >> beam.Create(data)
      | 'Encode' >> beam.Map(lambda x: create_tf_example(x).SerializeToString())
      | 'WriteData' >> sacklio.WriteToSackli('/path/to/output/data@*.bagz')
  )

Cloud Storage

Säckli supports POSIX file-systems, Google Cloud Storage (GCS), and Amazon S3. These can be enabled or disabled at compile-time, but the PyPI-deployed wheels have support for both built-in.

GCS authentication

These examples assume you have the gcloud CLI installed.

gcloud config set project your-project-name
gcloud auth application-default login

S3 authentication

Authentication uses the standard AWS credential chain (environment variables, ~/.aws/credentials, IAM roles, etc.).

aws configure

Paths

Use the gs: and s3: file-system prefixes in paths.

import pathlib
import sackli

# This may freeze if you have not configured the GCS project.
gcs_reader = sackli.Reader('gs://your-bucket-name/your-file.bagz')
s3_reader = sackli.Reader('s3://your-bucket-name/your-file.bagz')

# Path supports a leading slash to work well with pathlib.
gcs_bucket = pathlib.Path('/gs://your-bucket-name')
gcs_reader = sackli.Reader(gcs_bucket / 'your-file.bagz')

s3_bucket = pathlib.Path('/s3://your-bucket-name')
s3_reader = sackli.Reader(s3_bucket / 'your-file.bagz')

Säckli/Bagz file format

For now, Säckli still preserves exactly the Bagz file format. However, this is not guaranteed to remain the case.

The Bagz file format has two parts: the records section and the limits section.

  • The records section consists of the concatenation of all (possibly compressed) records. (There are no additional bytes inside or between records, and records are not aligned in any way.)
  • The limits section is a dense array of the end-offsets of each record in order, encoded in little-endian 64-bit unsigned integers.

These can be stored as tail-limits in one file, where the limits section is appended to the records section, or as separate-limits, where they are stored in separate files.

Tail-limits example

Given a Bagz-formatted file with the following 3 uncompressed records:

Records
abcdef
123
catcat

The raw bytes of the Bagz-formatted file corresponding to the records above:

0x61 a 0x62 b 0x63 c 0x64 d 0x65 e 0x66 f
0x31 1 0x32 2 0x33 3
0x63 c 0x61 a 0x74 t 0x63 c 0x61 a 0x74 t
0x06   0x00   0x00   0x00   0x00   0x00   0x00   0x00  # 6 byte offset
0x09   0x00   0x00   0x00   0x00   0x00   0x00   0x00  # 9 byte offset
0x0f   0x00   0x00   0x00   0x00   0x00   0x00   0x00  # 15 byte offset

The last 8 bytes represent the end-offset of the last record. This is also the start of the limits section. Therefore reading the last 8 bytes will directly tell you the offset of the records/limits boundary.

Download files

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

Source Distribution

sackli-0.3.3.tar.gz (111.0 kB view details)

Uploaded Source

Built Distributions

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

sackli-0.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (12.0 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

sackli-0.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (11.1 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

sackli-0.3.3-cp314-cp314t-macosx_14_0_arm64.whl (5.8 MB view details)

Uploaded CPython 3.14tmacOS 14.0+ ARM64

sackli-0.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (12.0 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

sackli-0.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (11.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

sackli-0.3.3-cp314-cp314-macosx_14_0_arm64.whl (5.8 MB view details)

Uploaded CPython 3.14macOS 14.0+ ARM64

sackli-0.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (12.0 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

sackli-0.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (11.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

sackli-0.3.3-cp313-cp313-macosx_14_0_arm64.whl (5.8 MB view details)

Uploaded CPython 3.13macOS 14.0+ ARM64

sackli-0.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (12.0 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

sackli-0.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (11.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

sackli-0.3.3-cp312-cp312-macosx_14_0_arm64.whl (5.8 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

File details

Details for the file sackli-0.3.3.tar.gz.

File metadata

  • Download URL: sackli-0.3.3.tar.gz
  • Upload date:
  • Size: 111.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sackli-0.3.3.tar.gz
Algorithm Hash digest
SHA256 02b90f01292ec64b0dadbfae3fc6b86c1246fe0620a04a78ef2a9bf816bcb08c
MD5 85f9ee04680aa7c4c1bef685178deca8
BLAKE2b-256 0251f342d767d8286ebe5f1ffba90b0a5ec5bce21dc547655d0d78ff8b99cd54

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3.tar.gz:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fab620bcf9773656538cd398181976eb5a32f7fd9cf1cabc5e64d9c0ea0ef4d9
MD5 e36f23b0174812789dd2382fc3372b18
BLAKE2b-256 e40cdd1d37a790aeda97bace4e604262ac7a353a9c45f875b547d9bacc0c0d71

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d395ba2e684500a3d8e6a4c8c53e5be9625ad2597f91200f1366f86ea1252ce6
MD5 027c21b886d45423c9c23bd3e0583ce9
BLAKE2b-256 d6eccb6bbd527133424bc874cd48e5bd22bf31412716cc666b9ed541bde279aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314t-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314t-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 f38526c05a32c71ec8b7260fbd2218ad8771c06bd416ba80a3e1a6f514b9a232
MD5 0492c250a490fabb3d4418964a8efc66
BLAKE2b-256 51bf267d818c54a136e53aab896e3340062e19941616cc3a82d390b97b81c864

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314t-macosx_14_0_arm64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8aaf15ad10f87b8a65837fac1ed375f28c71c429dbfbd92df390378f1826f600
MD5 7cd564c5f0ed35efc9609053742db0ed
BLAKE2b-256 8ffb824dcf21815fb834f50ea32bc6ac9340b28ba7422bb10177cc0707dde189

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 5a02c142deb55a808149b1b56dbf97470716e4587f5e344bf56414e8e9eb8d8e
MD5 359438e8740b91a9b108312962d16084
BLAKE2b-256 432342595520ffd2639e24e99b3c0b7bfd47925f27cc1bcbbe10684a2189ee03

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp314-cp314-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp314-cp314-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 09f5c6df13c9f45a8d2cec35024043466cc71b2d5a3774b545bdd54ca08c09ad
MD5 82c1ef327a1b30a96033f4a20fcfb696
BLAKE2b-256 357111c1de7bb0d3245f863eba811dd4055533eab84e25966a5b5b72f53017b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp314-cp314-macosx_14_0_arm64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f667724ccdbef5f3e307934cfffccb09eb93189d2b0b7cfe3f7250172570a942
MD5 298de4d67807cec080709e9df353e431
BLAKE2b-256 9eaf6ea24dac6a618c60b2a4270676e8991ea6f860e82e95bac461710ff67ec9

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 da7e231359ac5b2fcef3a7d5f02da2234895c6a03aad732c8372523855069537
MD5 6f7c0cd86d9a7f21e3830d1e4907b578
BLAKE2b-256 1e48055edaee1fcfc8ebe12b4b4c8243fac6c17af592e96ea6943c0cd64de868

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp313-cp313-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp313-cp313-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 d75113b1e8a82ec66c1d572c49c9e49980cbbc0fd8c8df5a19d1afd3e988426b
MD5 804973bc3d366ed330aad1758c83094f
BLAKE2b-256 7904ba977f7db3735b9a90580efd5f7651c19ed3f97ede7b26e2c4d25143242d

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp313-cp313-macosx_14_0_arm64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 43975dc70056495307f1272d7c0e9253f58715ded5d34ba3ecba1d57ad9cb23e
MD5 3ab1c09493c07a7454cc254e78f45586
BLAKE2b-256 32b364975c05f193404c6879f3e8c2358671dbf0599f47b1a8d525090f83a1a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 38e17b28059937fb1d559ddccb55326e71154e52cdd235f1245238bf5f62793e
MD5 eda370703a7f48b5acabf7ab5082af99
BLAKE2b-256 00b36c1d59ee0b656bba9d966b8eaf82111b50be0863dd7dc4100445bb6f796f

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

File details

Details for the file sackli-0.3.3-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for sackli-0.3.3-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 f395556c338975d10ca7249acba01ab3bf92fc59b2d379476e68a4e50ce10bbb
MD5 a155daf28cf1f1e2c85474cbf871fc33
BLAKE2b-256 854a2d61f37b1e1ab78c09ce677ddcf97e538c3f3122fca970442571bc2cb220

See more details on using hashes here.

Provenance

The following attestation bundles were made for sackli-0.3.3-cp312-cp312-macosx_14_0_arm64.whl:

Publisher: publish.yml on lucasb-eyer/sackli

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

Release history Release notifications | RSS feed

0.3.4

13 files

This release

0.3.3 This release

13 files

0.3.2

13 files

0.3.1

13 files

0.3.0

9 files

0.2.8

9 files

0.2.7

9 files

0.2.6

6 files

0.2.5

5 files

0.2.3

5 files

0.2.2

2 files

0.2.1

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