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"
    )

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.3.0.tar.gz (54.1 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.3.0-cp314-cp314t-musllinux_1_1_x86_64.whl (605.8 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ x86-64

tonio-0.3.0-cp314-cp314t-musllinux_1_1_armv7l.whl (665.0 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARMv7l

tonio-0.3.0-cp314-cp314t-musllinux_1_1_aarch64.whl (551.9 kB view details)

Uploaded CPython 3.14tmusllinux: musl 1.1+ ARM64

tonio-0.3.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (390.9 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

tonio-0.3.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (388.3 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARMv7l

tonio-0.3.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (374.3 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

tonio-0.3.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl (421.4 kB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.12+ i686

tonio-0.3.0-cp314-cp314t-macosx_11_0_arm64.whl (338.2 kB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

tonio-0.3.0-cp314-cp314t-macosx_10_12_x86_64.whl (360.4 kB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

tonio-0.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl (610.2 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ x86-64

tonio-0.3.0-cp313-cp313t-musllinux_1_1_armv7l.whl (664.7 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARMv7l

tonio-0.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl (555.7 kB view details)

Uploaded CPython 3.13tmusllinux: musl 1.1+ ARM64

tonio-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (395.4 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ x86-64

tonio-0.3.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (387.9 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARMv7l

tonio-0.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (377.9 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.17+ ARM64

tonio-0.3.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl (420.8 kB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.12+ i686

tonio-0.3.0-cp313-cp313t-macosx_11_0_arm64.whl (338.1 kB view details)

Uploaded CPython 3.13tmacOS 11.0+ ARM64

tonio-0.3.0-cp313-cp313t-macosx_10_12_x86_64.whl (360.2 kB view details)

Uploaded CPython 3.13tmacOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for tonio-0.3.0.tar.gz
Algorithm Hash digest
SHA256 20cff9754f78acc6894b1a4014f51ba852283b6a61889d2f1be58de9a2dbb1bf
MD5 836656a08f9a7680b65c0624f518f303
BLAKE2b-256 340a3f3e39ad848a12b2f52779793afc4802e2062b5373e93d638d9aaba10a13

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 e3c98bf28bb7e0ca7f2944698bcf74a3e011e8f5e3e55f09873d7a8b0f4986ce
MD5 5af305c09d4d1c776eec2cbb902c8c0e
BLAKE2b-256 4fd4c895d2093289e1e5dc1211f33a7d29d6f54c4de61d8bd85bc4ceef971491

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 1c13232d46c0430da45fa13671ec48dcea4434ade615628b967984e73a368e3b
MD5 a0738cc953490f18bd662a074a62b1ec
BLAKE2b-256 0ff5c94518a085ec90275a4d4eff0b3cd749dd65f8d3b5fa58ae46f3e1d5ed3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 abee728eeb0852e0bbacb02040e23c6bafdb7a126b7861ac58985c2ed176ceb9
MD5 be426db717e6f0c042d2be70e5ee9ddb
BLAKE2b-256 25a2f0fb22867e6eb2605615f2fd9a5270629c5fe8a07a1ececa6cff3ef142b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a59b792718778862ca2bb9aa55a02fb85901cde75d72c16014046e2f6d96aca8
MD5 ae2cdeb8d9529af6bc4c66699e8d588c
BLAKE2b-256 92bbfc15e8aab6b859249d35aad5078cb729af4ed0857bd42c2e0a6fd25020ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 1f4b615dab6bb854205bb6beb8b7a3728888df87e042db0be6b27fc593826631
MD5 a34c7d096a50c6600b48e44b4387ab36
BLAKE2b-256 44324b6ec4f887c9b290a10d6de3adf7bb015effa71856b76b4c0036e99fb7b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 69951646c504665d0d5ccfde4481d43b3c912953dcfb9da6b6d0bc2b199eb2ba
MD5 747c081bcf4f8f380aa5e727f3d9f8ac
BLAKE2b-256 2a8465aecb7bbf4b21f5c0f0b447ee4b17e3923bb495d09aec99fcd7402236a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 fa0b07693054625bf72d753754a6cded65d7511b0710eec8a76fdddeadd84d63
MD5 e83834c88f2c15c59427e65336bff660
BLAKE2b-256 a771700e0b2b7a301dcdd4cf457e080a3c4ee7cbda010ccec7b25b379c555eed

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 95a5196d8166f2ef3caa8da1cb32c5e8043c7cff7751c1a66b8038f648a26c53
MD5 c8423065a6f6ad6f110bb71cad033a09
BLAKE2b-256 f8ce0940cb8a63370e446d5801068f7232c869f4aa937779c442c97eafa4890c

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b1b996a9961ffc9c668314da2f00c76c98440592cc2dc0dfdeb75fa214be30b1
MD5 698906af0c4b3e7d2dbefdc5bb884b1b
BLAKE2b-256 a863c5bdd01097e8aa7557be7e3c826b0a70a8803c316d8d50d3bfbd7f019234

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ccfb02e5e5880baa58aae205510d7dabf285017e8ea36af9b0f085615072952e
MD5 c8bc3c98d291a423a35c6080df0b683d
BLAKE2b-256 adf4eeaa9369deaaa46d23df72856b43a1f4a589bfbe8be65f9529959eba34b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-musllinux_1_1_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-musllinux_1_1_armv7l.whl
Algorithm Hash digest
SHA256 facf65d8841c4083aac358006023e41f5f21ad6169d7f922c1f58a3cf30e5806
MD5 eedee86eca0f4b9e9acf11745fd5e7e6
BLAKE2b-256 24d1a539c089c23603df3f2ab2cdc3a3f577602386420dc667871d4ae0322b4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 e409c1f26b008d9810c9155d92b36f98a4e546bed59cce9c4fb0db0af16b2adb
MD5 92a0c3e01daae47f67727e4aeefc9704
BLAKE2b-256 9dfc80506225b5883c3bf2210a325192559f9e9341e9a983dd0d8839419cbbd5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0f6906d4925336b7b2e8a553cdbfd3720edcb411c765a857f893b82bd7778d63
MD5 06b13a208215872593f606e34a320aed
BLAKE2b-256 cc5da2d83504507c78ee5649a58ea5c84dd1f03119076fa085b4bf7123ff99fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 2b8c1c2c15005a2f42b9d9db94bccbbe1762e82879983c77b2601121a10e893c
MD5 e8a7b2b7f7aeef37079843f1b750a544
BLAKE2b-256 e65b19d88b575d7ed02168b081de1f5f42a2576cf91a94756f9610bfcf1abb88

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c345d097e47b77c077f034cac00c160b562107895c1288fb08b673cdeb062c44
MD5 ffc7596ad07031cdb2c2a5900872978c
BLAKE2b-256 349af703ff9d2edd759da0c17f30c92141be44f059f5aa62fcb1847deba7e868

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.whl
Algorithm Hash digest
SHA256 0bee371c1fa901c8d2edffbc77e6eb15589b3c31a9dd451651be2cb749df1575
MD5 6b1bdb67abd88e8f0d0a97656e865d62
BLAKE2b-256 a2afb232cb56531a41113a536ca38fac02832c74f8a1c3ab4081e1bc0cdccc00

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5e8ebc683b017a7ce774d5cbee81c2f756a1f7f4ca4cb079e976c5acac901254
MD5 44dc04183a825bfd85eb1ace3a5df794
BLAKE2b-256 524ca89a6a0a62134f63f4dc5ff5fbe2d2a89909f33ff3dfcd4affe242755bf3

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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.3.0-cp313-cp313t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tonio-0.3.0-cp313-cp313t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 44fc99f64ad6218b4b0578e386fddeff2a0655ea7cab48a3f4d61eb6e84619b7
MD5 056d7945de4401eac7d54dd1ab54ae65
BLAKE2b-256 1304c46c0c33a5a6537822c3a53219d3a025753af494bc0dbbae663852d40ac7

See more details on using hashes here.

Provenance

The following attestation bundles were made for tonio-0.3.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