Skip to main content

A multi-threaded async runtime

Project description

TonIO

TonIO is a multi-threaded async runtime for free-threaded Python, built in Rust on top of the mio crate, and inspired by tinyio, trio and tokio.

Warning: TonIO is currently a work in progress and in alpha state. The APIs are subtle to breaking changes.

Note: TonIO is available on free-threaded Python and Unix systems only.

TonIO supports both using yield and the more canonical async/await notations, with the latter being available as part of the tonio.colored module. Following code snippets show both the usages.

Warning: despite the fact TonIO supports async and await notations, it's not compatible with any asyncio object like futures and tasks.

In a nutshell

yield syntax

import tonio

def wait_and_add(x: int) -> int:
    yield tonio.sleep(1)
    return x + 1

def foo():
    four, five = yield tonio.spawn(
        wait_and_add(3), 
        wait_and_add(4)
    )
    return four, five

out = tonio.run(foo())
assert out == (4, 5)

await syntax

import tonio.colored as tonio

async def wait_and_add(x: int) -> int:
    await tonio.sleep(1)
    return x + 1

async def foo():
    four, five = await tonio.spawn(
        wait_and_add(3), 
        wait_and_add(4)
    )
    return four, five

out = tonio.run(foo())
assert out == (4, 5)

Usage

Entrypoint

Every TonIO program consist of an entrypoint, which should be passed to the run method:

yield syntax

import tonio

def main():
    yield
    print("Hello world")

tonio.run(main())

await syntax

import tonio.colored as tonio

async def main():
    await tonio.yield_now()
    print("Hellow world")

tonio.run(main())

TonIO also provides a main decorator, thus we can rewrite the previous example as:

yield syntax

import tonio

@tonio.main
def main():
    yield
    print("Hello world")

main()

await syntax

import tonio.colored as tonio

@tonio.main
async def main():
    await tonio.yield_now()
    print("Hello world")

main()

Note: as you can see the colored module provides the additional yield_now coroutine, a quick way to define a suspension point, given you cannot just yield as in the non-colored notation.

Note: both run and main can only be called once per program. To run the runtime multiple times in the same program, follow the section below.

Manually managing the runtime

TonIO also provides the runtime function, to manually manage the runtime lifecycle:

import tonio

def _run1():
    ...

async def _run2():
    ...

def main():
    runtime = tonio.runtime()
    runtime.run_until_complete(_run1())
    runtime.run_until_complete(_run2())

Runtime options

The run, main and runtime methods accept options, specifically:

option name description default
context enable contextvars usage in coroutines False
signals list of signals to listen to
threads Number of runtime threads # of CPU cores
blocking_threadpool_size Maximum number of blocking threads 128
blocking_threadpool_idle_ttl Idle timeout for blocking threads (in seconds) 30

Events

The core object in TonIO is Event. It's basically a wrapper around an atomic boolean flag, initialised with False. Event provides the following methods:

  • is_set(): return the value of the flag
  • set(): set the flag to True
  • clear(): set the flag to False
  • wait(timeout=None): returns a coroutine you can yield on that unblocks when the flag is set to True or the timeout expires. Timeout is in seconds.

yield syntax

import tonio

@tonio.main
def main():
    event = tonio.Event()

    def setter():
        yield tonio.sleep(1)
        event.set()

    tonio.spawn(setter())
    yield event.wait()

await syntax

import tonio.colored as tonio

@tonio.main
async def main():
    event = tonio.Event()

    async def setter():
        await tonio.sleep(1)
        event.set()

    tonio.spawn(setter())
    await event.wait()

Spawning tasks

TonIO provides the spawn method to schedule new coroutines onto the runtime:

yield syntax

import tonio

def doubv(v):
    yield
    return v * 2

@tonio.main
def main():
    parallel = tonio.spawn(doubv(2), doubv(3))
    v3 = yield doubv(4)
    v1, v2 = yield parallel
    print([v1, v2, v3])

await syntax

import tonio.colored as tonio

async def doubv(v):
    await tonio.yield_now()
    return v * 2

@tonio.main
async def main():
    parallel = tonio.spawn(doubv(2), doubv(3))
    v3 = await doubv(4)
    v1, v2 = await parallel
    print([v1, v2, v3])

Coroutines passed to spawn get schedule onto the runtime immediately. Using yield or await on the return value of spawn just waits for the coroutines to complete and retreive the results.

Blocking tasks

TonIO provides the spawn_blocking method to schedule blocking operations onto the runtime:

yield syntax

import tonio

def read_file(path):
    with open(file, "r") as f:
        return f.read()

@tonio.main
def main():
    file_data = yield tonio.spawn_blocking(
        read_file, 
        "sometext.txt"
    )

await syntax

import tonio.colored as tonio

def read_file(path):
    with open(file, "r") as f:
        return f.read()

@tonio.main
async def main():
    file_data = await tonio.spawn_blocking(
        read_file, 
        "sometext.txt"
    )

Running tasks from synchronous contexts

TonIO provides the block_on method to spawn coroutines from a synchronous context. It works the same way of spawn, except it accepts a single coroutine and it blocks the current thread until the coroutine is completed.

Warning: using block_on from within a coroutine might produce a runtime deadlock.

Map utilities

TonIO provides the map and map_blocking utilities to spawn the same operation with an iterable of parameters:

yield syntax

import tonio

accum = []

def task(no):
    yield tonio.sleep(0.5)
    accum.append(no * 2)

@tonio.main
def main():
    yield tonio.map(task, range(4))

await syntax

import tonio.colored as tonio

accum = []

async def task(no):
    await tonio.sleep(0.5)
    accum.append(no * 2)

@tonio.main
async def main():
    await tonio.map(task, range(4))

Scopes and cancellations

TonIO provides a scope context, that lets you cancel work spawned within it:

yield syntax

import tonio

def slow_push(target, sleep):
    yield tonio.sleep(sleep)
    target.append(True)

@tonio.main
def main():
    values = []
    with tonio.scope() as scope:
        scope.spawn(_slow_push(values, 0.1))
        scope.spawn(_slow_push(values, 2))
        yield tonio.sleep(0.2)
        scope.cancel()
    yield scope()
    assert len(values) == 1

await syntax

import tonio.colored as tonio

async def slow_push(target, sleep):
    await tonio.sleep(sleep)
    target.append(True)

@tonio.main
async def main():
    values = []
    async with tonio.scope() as scope:
        scope.spawn(_slow_push(values, 0.1))
        scope.spawn(_slow_push(values, 2))
        await tonio.sleep(0.2)
        scope.cancel()
    assert len(values) == 1

When you yield on the scope, it will wait for all the spawned coroutines to end. If the scope was canceled, then all the pending coroutines will be canceled.

Note: as you can see, the colored version of scope doesn't require to be awaited, as it will yield when exiting the context.

Time-related functions

  • tonio.time.time(): a function returning the runtime's clock (in seconds, microsecond resolution)
  • tonio.time.sleep(delay): a coroutine you can yield on to sleep (delay is in seconds)
  • tonio.time.timeout(coro, timeout): a coroutine you can yield on returning a tuple (output, success). If the coroutine succeeds in the given time then the pair (output, True) is returned. Otherwise this will return (None, False).

Note: time.sleep is also exported to the main tonio module.

Note: all of the above functions are also present in tonio.colored.time module.

Scheduling work

TonIO provides the time.interval function to create interval objects you can yield on a scheduled basis:

yield syntax

import tonio
from tonio import time

def some_task():
    ...

def scheduler():
    interval = time.interval(1)
    while True:
        yield interval.tick()
        tonio.spawn(some_task())

@tonio.main
def main():
    tonio.spawn(scheduler())
    # do some other work

await syntax

import tonio.colored as tonio
from tonio.colored import time

async def some_task():
    ...

async def scheduler():
    interval = time.interval(1)
    while True:
        await interval.tick()
        tonio.spawn(some_task())

@tonio.main
async def main():
    tonio.spawn(scheduler())
    # do some other work

The interval method first argument is the interval in seconds resolution, and the method also accepts an optional at argument, to delay the first execution at a specific time (from the runtime's clock perspective):

from tonio import time

# tick every 500ms, with the first tick happening in 5 seconds from now
interval = time.interval(0.5, time.time() + 5)

Synchronization primitives

Synchronization primitives are exposed in the tonio.sync module.

Lock

Implements a classic mutex, or a non-reentrant, single-owner lock for coroutines:

yield syntax

import tonio
from tonio import sync

@tonio.main
def main():
    # counter can't go above 1
    counter = 0

    def _count(lock):
        nonlocal counter
        with (yield lock()):
            counter += 1
            yield
            counter -= 1
    
    lock = sync.Lock()
    yield tonio.spawn(*[
        _count(lock)
        for _ in range(10)
    ])

await syntax

import tonio.colored as tonio
from tonio.colored import sync

@tonio.main
async def main():
    # counter can't go above 1
    counter = 0

    async def _count(lock):
        nonlocal counter
        async with lock:
            counter += 1
            await tonio.yield_now()
            counter -= 1
    
    lock = sync.Lock()
    await tonio.spawn(*[
        _count(lock)
        for _ in range(10)
    ])

The Lock object also implements an or_raise method, that will immediately fail when the lock cannot be acquired:

from tonio.exceptions import WouldBlock

try:
    with lock.or_raise():
        ...
except WouldBlock:
    ...

Semaphore

A semaphore for coroutines:

yield syntax

import tonio
from tonio import sync

@tonio.main
def main():
    # counter can't go above 2
    counter = 0

    def _count(semaphore):
        nonlocal counter
        with (yield semaphore()):
            counter += 1
            yield
            counter -= 1
    
    semaphore = sync.Semaphore(2)
    yield tonio.spawn(*[
        _count(semaphore)
        for _ in range(10)
    ])

await syntax

import tonio.colored as tonio
from tonio.colored import sync

@tonio.main
async def main():
    # counter can't go above 2
    counter = 0

    async def _count(semaphore):
        nonlocal counter
        async with semaphore:
            counter += 1
            await tonio.yield_now()
            counter -= 1
    
    semaphore = sync.Semaphore(2)
    await tonio.spawn(*[
        _count(semaphore)
        for _ in range(10)
    ])

As for locks, the Semaphore object also implements an or_raise method, that will immediately fail when the lock cannot be acquired:

from tonio.exceptions import WouldBlock

try:
    with semaphore.or_raise():
        ...
except WouldBlock:
    ...

The Semaphore object also implements a tokens method, that returns the number of available tokens.

Barrier

A barrier for coroutines:

yield syntax

import tonio
from tonio import sync

@tonio.main
def main():
    barrier = sync.Barrier(3)
    count = 0

    def _start_at_3():
        nonlocal count
        count += 1
        i = yield barrier.wait()
        assert count == 3
        return i

    yield tonio.spawn(*[
        _start_at_3()
        for _ in range(3)
    ])

await syntax

import tonio.colored as tonio
from tonio.colored import sync

@tonio.main
async def main():
    barrier = sync.Barrier(3)
    count = 0

    async def _start_at_3():
        nonlocal count
        count += 1
        i = await barrier.wait()
        assert count == 3
        return i

    await tonio.spawn(*[
        _start_at_3()
        for _ in range(3)
    ])

The Barrier object also implements a value method, which returns the current value of the barrier.

Channels

Multi-producer multi-consumer channels for inter-coroutine communication.

The tonio.sync.channel module provides both a channel and an unbounded constructors.
The main difference between bounded and unbounded channels, as the names suggest, is that while the first will suspend sending messages once the specified length is reached, and it will resume accepting messages once the existing buffer is consumed, the latter will always accept new messages. That's also why, the sender part of a bounded channel is async, while in the unbounded is not.

Bounded channel

yield syntax

import tonio
from tonio import sync
from tonio.sync import channel

def producer(sender, barrier, offset):
    for i in range(20):
        message = offset + 1
        yield sender.send(message)
    yield barrier.wait()

def consumer(receiver):
    while True:
        try:
            message = yield receiver.receive()
            print(message)
        except Exception:
            break

@tonio.main
def main():
    def close(sender, barrier):
        yield barrier.wait()
        sender.close()

    sender, receiver = channel.channel(2)
    barrier = sync.Barrier(3)
    yield tonio.spawn(*[
        producer(sender, barrier, 100),
        producer(sender, barrier, 200),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        close(sender, barrier),
    ])

await syntax

import tonio.colored as tonio
from tonio.colored import sync
from tonio.colored.sync import channel

async def producer(sender, barrier, offset):
    for i in range(20):
        message = offset + 1
        await sender.send(message)
    await barrier.wait()

async def consumer(receiver):
    while True:
        try:
            message = await receiver.receive()
            print(message)
        except Exception:
            break

@tonio.main
async def main():
    async def close(sender, barrier):
        await barrier.wait()
        sender.close()

    sender, receiver = channel.channel(2)
    barrier = sync.Barrier(3)
    await tonio.spawn(*[
        producer(sender, barrier, 100),
        producer(sender, barrier, 200),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        close(sender, barrier),
    ])
Unbounded channel

yield syntax

import tonio
from tonio import sync
from tonio.sync import channel

def producer(sender, barrier, offset):
    for i in range(20):
        message = offset + 1
        sender.send(message)
    yield barrier.wait()

def consumer(receiver):
    while True:
        try:
            message = yield receiver.receive()
            print(message)
        except Exception:
            break

@tonio.main
def main():
    def close(sender, barrier):
        yield barrier.wait()
        sender.close()

    sender, receiver = channel.unbounded()
    barrier = sync.Barrier(3)
    yield tonio.spawn(*[
        producer(sender, barrier, 100),
        producer(sender, barrier, 200),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        close(sender, barrier),
    ])

await syntax

import tonio.colored as tonio
from tonio.colored import sync
from tonio.colored.sync import channel

async def producer(sender, barrier, offset):
    for i in range(20):
        message = offset + 1
        sender.send(message)
    await barrier.wait()

async def consumer(receiver):
    while True:
        try:
            message = await receiver.receive()
            print(message)
        except Exception:
            break

@tonio.main
async def main():
    async def close(sender, barrier):
        await barrier.wait()
        sender.close()

    sender, receiver = channel.unbounded()
    barrier = sync.Barrier(3)
    await tonio.spawn(*[
        producer(sender, barrier, 100),
        producer(sender, barrier, 200),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        consumer(receiver),
        close(sender, barrier),
    ])

Network module

Network primitives are exposed under the tonio.net module.

Streams

The high-level network primitives in TonIO are centered aroud the SocketStream and SocketListener objects.

The SocketListener object implements an accept coroutine which returns a SocketStream object.
The SocketStream object implements the send_all and receive_some coroutines to send and receive data.
Both objects implement a close method to shutdown the underlying socket.

You can create and interact with the above objects using some high-level helpers in the net module, specifically:

  • open_tcp_stream: a coroutine to open a SocketStream connected to a TCP endpoint
  • open_unix_socket: a coroutine to open a SocketStream connected to an Unix socket
  • open_tcp_listeners: a coroutine to initialise SocketListener objects
  • serve_listeners: a coroutine to spawn SocketListener accept loops targeting a handler
  • serve_tcp: a coroutine that join open_tcp_listener and serve_listeners in one call

yield syntax

from tonio.net import open_tcp_stream, serve_tcp

def server():
    yield serve_tcp(
        server_handle, 
        host='127.0.0.1', 
        port=8000
    )

def server_handle(stream):
    # receive some data
    data = yield stream.receive_some()

def client():
    stream = yield open_tcp_stream(
        host='127.0.0.1', 
        port=8000
    )
    # send some data
    yield stream.send_all("message")

await syntax

from tonio.colored.net import open_tcp_stream, serve_tcp

async def server():
    await serve_tcp(
        server_handle, 
        host='127.0.0.1', 
        port=8000
    )

async def server_handle(stream):
    # receive some data
    data = await stream.receive_some()

async def client():
    stream = await open_tcp_stream(
        host='127.0.0.1', 
        port=8000
    )
    # send some data
    await stream.send_all("message")

SSL streams

TonIO implement SSL wrappers around the streaming APIs through primitives in the tonio.net.ssl module.

TonIO provides the SSLStream and SSLListener object wrappers and the following high-level helpers:

  • open_ssl_over_tcp_stream: a coroutine to open a SSLStream wrapping a TCP SocketStream
  • open_ssl_over_tcp_listeners: a coroutine to initialise SSLListener objects
  • serve_ssl_over_tcp: a coroutine that join open_tls_over_tcp_listeners and serve_listeners in one call

Low-level sockets

The tonio.net.socket module provides TonIO's basic low-level networking API.
Generally, the API exposed by this module mirrors the standard library socket module.

TonIO socket objects are overall very similar to the standard library socket objects, with the main difference being that blocking methods become coroutines.

yield syntax

import tonio
from tonio.net import socket

def server():
    sock = socket.socket()
    with sock:
        yield sock.bind(('127.0.0.1', 8000))
        sock.listen()

        while True:
            client, _ = yield sock.accept()
            tonio.spawn(server_handle(client))

def server_handle(connection):
    with connection:
        # receive some data
        data = yield connection.recv(4096)

def client():
    sock = socket.socket()
    with sock:
        yield sock.connect(('127.0.0.1', 8000))
        yield sock.send("message")

await syntax

import tonio.colored as tonio
from tonio.colored.net import socket

async def server():
    sock = socket.socket()
    with sock:
        await sock.bind(('127.0.0.1', 8000))
        sock.listen()

        while True:
            client, _ = await sock.accept()
            tonio.spawn(server_handle(client))

async def server_handle(connection):
    with connection:
        # receive some data
        data = await connection.recv(4096)

async def client():
    sock = socket.socket()
    with sock:
        await sock.connect(('127.0.0.1', 8000))
        await sock.send("message")

Signals

TonIO provides a context manager to catch signals.

The usage of such context manager requires to first configure the runtime to listen for such signals:

yield syntax

import signal
import tonio
from tonio.time import interval

def sig_handle():
    with tonio.signal_receiver(
        signal.SIGHUP, 
        signal.SIGUSR1
    ) as sigs:
        for ev in sigs:
            sig = yield ev
            if sig == signal.SIGHUP:
                ...

@tonio.main(
    signals=[signal.SIGHUP, signal.SIGUSR1]
)
def main():
    tonio.spawn(sig_handle())
    ticker = interval(1)
    while True:
        yield ticker.tick()

await syntax

import signal
import tonio.colored as tonio
from tonio.colored.time import interval

async def sig_handle():
    with tonio.signal_receiver(
        signal.SIGHUP, 
        signal.SIGUSR1
    ) as sigs:
        async for sig in sigs:
            if sig == signal.SIGHUP:
                ...

@tonio.main(
    signals=[signal.SIGHUP, signal.SIGUSR1]
)
async def main():
    tonio.spawn(sig_handle())
    ticker = interval(1)
    while True:
        await ticker.tick()

License

TonIO is released under the BSD License.

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

tonio-0.4.0.tar.gz (55.3 kB view details)

Uploaded Source

Built Distributions

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

tonio-0.4.0-cp314-cp314t-musllinux_1_1_x86_64.whl (607.0 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

tonio-0.4.0-cp314-cp314t-musllinux_1_1_armv7l.whl (666.3 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

tonio-0.4.0-cp314-cp314t-musllinux_1_1_aarch64.whl (553.2 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

tonio-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (391.9 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

tonio-0.4.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (389.7 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

tonio-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (375.4 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

tonio-0.4.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (422.2 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

tonio-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl (339.6 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

tonio-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl (361.6 kB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

tonio-0.4.0-cp313-cp313t-musllinux_1_1_x86_64.whl (611.6 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

tonio-0.4.0-cp313-cp313t-musllinux_1_1_armv7l.whl (666.0 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

tonio-0.4.0-cp313-cp313t-musllinux_1_1_aarch64.whl (556.9 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

tonio-0.4.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (396.7 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

tonio-0.4.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (389.2 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

tonio-0.4.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (379.1 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARM64

tonio-0.4.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl (421.9 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

tonio-0.4.0-cp313-cp313t-macosx_11_0_arm64.whl (339.4 kB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

tonio-0.4.0-cp313-cp313t-macosx_10_12_x86_64.whl (361.1 kB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

File details

Details for the file tonio-0.4.0.tar.gz.

File metadata

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

File hashes

Hashes for tonio-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d829004cbc858ae7f7d7122747978bedeb6123e5608c836b1550216b5747301d
MD5 faeb9b11ec47cc0cd7362bbd0234badb
BLAKE2b-256 986c92955d7e833d712877846addc0e40753e7bb8ae3cd5840d428cbc838c358

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0.tar.gz:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 6009956de8ebb7ee0a79966f396dba028c2d0d838a298a2aa0e3e8f2c433f2cf
MD5 552159118312f590235fdf63a9d54040
BLAKE2b-256 75c890ad917384acc44146bb0b677b2c28a1efaf76d4ef4bb33cece7969a443a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-musllinux_1_1_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 745f887eabd240b892e7e41971140d8983039095d2c20e90d69ed4b806e39eec
MD5 dea62093b05d9aa4898a99b5882787c0
BLAKE2b-256 5d037b3a5fe51eba79550be0479daa4d028687e6996f4534759db3f2c6cad7f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-musllinux_1_1_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 d8a659d54b11d5db2643a6a82fc805b6e35ddb4e7c49b3ce508894302e4144c6
MD5 7314626b5526d18de41beaffc969e80d
BLAKE2b-256 a85b105e41c75eeca985d6129882848356bb3de51ed3926622d82d95f6ae9ea4

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-musllinux_1_1_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6d358b96c9f03334da0ee2c8914e821a139c6c20098f0a87d224fb2b3ac12569
MD5 6e538e289b9ff9eb785a09de03fcdd82
BLAKE2b-256 8955dbf90ace53704b0875408e67ab770aa022aabd24da2f2c17315edeb378ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 d7f4eeeb04d6d9467f0770e444c12cca114265e87372de1aec3af1b0cf8ff6b9
MD5 c428a504dd4dd30bc6202bd736a8e766
BLAKE2b-256 57c1cbfa9b11b5317a2225f0e991a758508405a2e826c164272aa70726ca432b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f368fce3a10cefce9c0bc1a5b2f1297d1085c021b1cdbd3a69b01e70fd5c0817
MD5 8d95dd0193609444470f1c689bd46be6
BLAKE2b-256 6fc6dcb6ecdd0e703a504847109b0abc7c152be514b7615197c64e39879e14ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 9312809d0085750d4edc9cf2397a468f86bb0998efd82315aa7fa4fb7e0811b3
MD5 0593e0399451c8e1d64dd9d848deb2c8
BLAKE2b-256 4e359168795c12dd289afc85d385d34ebade5c21ede283a6a3e6c14dda1a6718

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d13337033f308408d55b3bd42dcef06da907d6b523134be45186995804ed29e6
MD5 6bebd6b86ed153994e3c32cd1983c16a
BLAKE2b-256 37f72d764d5e4053190d9e5140ff27f14d943e733f8dfe0733d9fb73c68c04e9

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8c65a2340344a85b5770192ed0f2399b51cbbb2999522b9904b8bf813af63f9a
MD5 0bbb060488e9ba5e7242433c2d2bb32a
BLAKE2b-256 2f3a47ed6e43888c3af0b763458b558abe3c4cbcc3072c600a702b1fe73a9f7b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp314-cp314t-macosx_10_12_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 0bfff8b5cd782510649d88a194717fe0cf0d8ce8de3c6bb7b35f4620fad3d246
MD5 b95c58c7e03ac37aa1333122e9c5ca60
BLAKE2b-256 b920775d22b983433e86a4779408f9efb82384e94033715ed1a0f8078d8616fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-musllinux_1_1_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 95224509a2f4e6be68654da0da4fdf87a74df383b93214ce8947bfb839af8d0b
MD5 b5edda32f9fb75b09ce4839944863534
BLAKE2b-256 fd9690e0ff451816f535dcac635ecdebbf9721da8d00635ce71e94ae3404522f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-musllinux_1_1_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 9886186dbd4d8da22ec71a73fae74aa754118d333f8334b35dd8f882334cf87f
MD5 7aa0815108ab95f0eeeeb5047f8547ae
BLAKE2b-256 bc2f83be72ad9a3ed2f0f4c3b448dd641b5716784d4f145abc7f254eb92a661d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-musllinux_1_1_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ed20812e2c2ca2c20f112b1a551e4bfa083956a02f50dfa0feb5f3dc0a9c16cd
MD5 0b493a3d1f2fe9383b3096b77f7a3f37
BLAKE2b-256 facded904376221579f1458d299fa12a6ab39095f438c519d407ca253df16ac9

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 6f8fb4c4865e7636733d48e951cd7bef9179ab670a1a9493592f7fb9540b9f12
MD5 2e3c48ead0fce1b570116517d1be9c54
BLAKE2b-256 07ff114e2d7b5fe7d12903d0c33afef6c47ac16482968263591e292fdffada31

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3acb56dce54211f2c332a5f9f6e346887238ca73c6538c4fd7dc09d69c8e5f0a
MD5 4f3fb9a500e73f8b7069c5575b0b7b60
BLAKE2b-256 7b690bb9ef8a2c8d9f137af0c44212119e1d4b6d495098eaef5720e78a552b9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 22db9b0077cfa9a68dfa7b2253d3321d3482562a60631a61c55dc1e998eebed0
MD5 3ae465e6520ce0e341c23d50a5bd2613
BLAKE2b-256 2a58b50944ba50c2eebc8cee343f7d9599fb3d3bc0ee5a4ca336b25e6ab7f273

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3385c46fe6b10191d9613cb6fbe5c020fcd05bb6b5126bac967de52fe7c4c6b5
MD5 764c29d50931bbb47ee7e409173b8465
BLAKE2b-256 0f9d238a9527887c3e5444f403fcd75e3a16d230c7225aabcc2d41866cbf75ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-macosx_11_0_arm64.whl:

Publisher: release.yml on gi0baro/tonio

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

File details

Details for the file tonio-0.4.0-cp313-cp313t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.4.0-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f9e4fff5e693895f558730ce7d359bc8d0189ba1a63816873abcfcaed4b8a99c
MD5 1e352012a13c113db272779421a39051
BLAKE2b-256 6edfbf05aef6ac95386fdcacf2a2bfc87bfc13e114e05cad26d7412f79fa4bed

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.4.0-cp313-cp313t-macosx_10_12_x86_64.whl:

Publisher: release.yml on gi0baro/tonio

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