Skip to main content

High-performance, schema-agnostic event bus for AI runtime workloads

Project description

Net Python

High-performance, schema-agnostic event bus for AI runtime workloads.

Installation

pip install net

Quick Start

from net import Net

# Create event bus (defaults to CPU core count shards)
bus = Net()

# Ingest events - fast path with raw JSON strings (23M+ ops/sec)
bus.ingest_raw('{"token": "hello", "index": 0}')

# Or use dict for convenience (4M+ ops/sec)
bus.ingest({"token": "world", "index": 1})

# Batch ingestion for maximum throughput
events = [f'{{"token": "tok_{i}"}}' for i in range(10000)]
count = bus.ingest_raw_batch(events)

# Poll events
response = bus.poll(limit=100)
for event in response:
    print(event.raw)
    # Or parse to dict
    data = event.parse()

# Check stats
stats = bus.stats()
print(f"Ingested: {stats.events_ingested}, Dropped: {stats.events_dropped}")

# Shutdown
bus.shutdown()

Context Manager

with Net(num_shards=4) as bus:
    bus.ingest_raw('{"data": "value"}')
# Automatically shuts down

Configuration

bus = Net(
    num_shards=8,                    # Number of parallel shards
    ring_buffer_capacity=1_048_576,  # Events per shard (must be power of 2)
    backpressure_mode="drop_oldest", # What to do when full
)

Net Encrypted UDP Transport

Net provides encrypted point-to-point UDP transport for high-performance scenarios:

from net import Net, generate_net_keypair
import os

# Generate keypair for responder
keypair = generate_net_keypair()
psk = os.urandom(32).hex()

# Responder side
responder = Net(
    num_shards=2,
    net_bind_addr='127.0.0.1:9001',
    net_peer_addr='127.0.0.1:9000',
    net_psk=psk,
    net_role='responder',
    net_secret_key=keypair.secret_key,
    net_public_key=keypair.public_key,
    net_reliability='light',  # 'none', 'light', or 'full'
)

# Initiator side (knows responder's public key)
initiator = Net(
    num_shards=2,
    net_bind_addr='127.0.0.1:9000',
    net_peer_addr='127.0.0.1:9001',
    net_psk=psk,
    net_role='initiator',
    net_peer_public_key=keypair.public_key,
)

# Use as normal
initiator.ingest_raw('{"event": "data"}')

Backpressure Modes

  • "drop_newest" - Reject new events when buffer is full
  • "drop_oldest" - Evict oldest events to make room
  • "fail_producer" - Raise an error

NAT traversal (optimization, not correctness)

Two NATed peers already reach each other through the mesh's routed-handshake path. NAT traversal opens a shorter direct path when the NAT shape allows it; it's never required for connectivity. Every method below is safe to call regardless of NAT type — a failed punch or a traversal: * RuntimeError is not a connectivity failure, traffic keeps riding the relay. The whole surface is a no-op when the native module was built without --features nat-traversal: every call raises RuntimeError("traversal: unsupported").

from net import NetMesh

mesh = NetMesh(bind_addr="0.0.0.0:9000", psk="00" * 32)

mesh.reclassify_nat()

klass  = mesh.nat_type()            # "open" | "cone" | "symmetric" | "unknown"
reflex = mesh.reflex_addr()         # "203.0.113.5:9001" or None

observed = mesh.probe_reflex(peer_node_id)   # "ip:port"

# Attempt a direct connection via the pair-type matrix.
# `coordinator` mediates the punch when the matrix picks one.
# Always returns — inspect stats to learn which path won.
mesh.connect_direct(peer_node_id, peer_pubkey_hex, coordinator_node_id)

# Cumulative counters — all int, monotonic.
s = mesh.traversal_stats()
s.punches_attempted   # coordinator mediated a PunchRequest + Introduce
s.punches_succeeded   # ack arrived AND direct handshake landed
s.relay_fallbacks     # landed on the routed path after skip/fail

Operators with a known-public address skip the classifier sweep entirely. The override pins "open" + the supplied address on every capability announcement; call announce_capabilities() after to propagate (the setter resets the rate-limit floor so the next announce is guaranteed to broadcast).

mesh.set_reflex_override('203.0.113.5:9001')
mesh.announce_capabilities(caps)
# later:
mesh.clear_reflex_override()
mesh.announce_capabilities(caps)

Traversal failures surface as RuntimeError with a stable traversal: <kind>[: <detail>] message prefix. The <kind> discriminator is one of reflex-timeout | peer-not-reachable | transport | rendezvous-no-relay | rendezvous-rejected | punch-failed | port-map-unavailable | unsupported. Match on the prefix for machine-readable branching:

try:
    mesh.connect_direct(peer_node_id, peer_pubkey_hex, coord_id)
except RuntimeError as e:
    msg = str(e)
    if msg.startswith("traversal: unsupported"):
        ...   # native module built without --features nat-traversal
    elif msg.startswith("traversal: peer-not-reachable"):
        ...

"unsupported" is the signal that the bindings are linked unconditionally and the native module doesn't have the feature — callers can branch cleanly without probing for symbol presence.

Channels (distributed pub/sub)

Named pub/sub over the encrypted mesh. Publishers register channels with access policy; subscribers ask to join via a membership subprotocol; publish fans payloads out to every current subscriber.

from net import NetMesh, ChannelAuthError, ChannelError

pub = NetMesh('127.0.0.1:9001', '42' * 32)
try:
    pub.register_channel(
        'sensors/temp',
        visibility='global',      # or 'subnet-local' | 'parent-visible' | 'exported'
        reliable=True,
        priority=2,
        max_rate_pps=1000,
    )

    # Subscriber side (after handshake with pub):
    # sub.subscribe_channel(pub.node_id, 'sensors/temp')

    # Fan a payload out to all subscribers.
    report = pub.publish(
        'sensors/temp',
        b'{"celsius": 22.5}',
        reliability='reliable',
        on_failure='best_effort',
        max_inflight=32,
    )
    print(f"{report['delivered']}/{report['attempted']} subscribers received")
finally:
    pub.shutdown()

# Typed errors for ACL outcomes:
# try: sub.subscribe_channel(peer_id, 'restricted')
# except ChannelAuthError: ...   # publisher denied
# except ChannelError: ...       # unknown channel / other rejection

Channel names always cross the binding as strings (not the u16 hash) to avoid ACL bypass via collision. The Python binding does not yet expose a dedicated per-channel receive API; that is a follow-up.

CortEX & NetDb (event-sourced state)

Typed, event-sourced state on top of RedEX — tasks and memories with filterable queries and sync watch iterators. Includes the snapshot_and_watch primitive whose race fix landed on v2, so you can safely "paint what's there now, then react to changes" without losing updates that race during construction.

from net import NetDb, CortexError

db = NetDb.open(origin_hash=0xABCDEF01, with_tasks=True, with_memories=True)
tasks = db.tasks

try:
    seq = tasks.create(1, 'write docs', 100)
    tasks.wait_for_seq(seq)   # block until the fold has applied
except CortexError as e:
    # adapter-level failure (RedEX I/O, fold halted, etc.)
    ...

# Snapshot + watch, one atomic call — no race.
snap, it = tasks.snapshot_and_watch_tasks(status='pending')
print('initial:', len(snap), 'pending tasks')
for batch in it:
    print('update:', len(batch), 'pending tasks')
    if len(batch) == 0:
        it.close()    # idempotent; ends the iterator
        break

db.close()

Standalone adapters

If you only need one model, skip the NetDb facade:

from net import Redex, TasksAdapter

redex = Redex(persistent_dir='/var/lib/net/redex')
tasks = TasksAdapter.open(redex, origin_hash=0xABCDEF01, persistent=True)

MemoriesAdapter exposes the same shape with store / retag / pin / unpin / delete / list_memories / watch_memories / snapshot_and_watch_memories.

Raw RedEX file (no CortEX fold)

For domain-agnostic persistent logs — your own event schema, no fold, no typed adapter — open a RedexFile directly from a Redex. The tail is a sync Python iterator; call close() or let StopIteration fire when the file closes.

from net import Redex, RedexError

redex = Redex(persistent_dir='/var/lib/net/events')
file = redex.open_file(
    'analytics/clicks',
    persistent=True,
    fsync_interval_ms=100,           # or fsync_every_n=1000
    retention_max_events=1_000_000,
)

# Append (or batch-append).
seq = file.append(b'{"url": "/home"}')
first = file.append_batch([b'{"a": 1}', b'{"a": 2}'])

# Tail — backfills the retained range, then streams live appends.
try:
    for event in file.tail(from_seq=0):
        print(event.seq, bytes(event.payload))
        if should_stop:
            break           # idempotent; ends the iterator via close()
except RedexError as e:
    ...

file.close()

Errors from the RedEX surface raise RedexError (invalid channel name, bad config, append / tail / sync / close failures).

Why snapshot_and_watch_*?

Calling list_tasks() then watch_tasks() takes two independent state reads. A mutation landing between them would be silently lost under the old skip(1) implementation. The atomic primitive returns the snapshot and an iterator seeded so that any divergent initial emission is forwarded through instead of dropped — see docs/STORAGE_AND_CORTEX.md.

Redis Streams consumer-side dedup helper

The Net Redis adapter writes a stable dedup_id field on every XADD entry: {producer_nonce:hex}:{shard_id}:{sequence_start}:{i}. Combined with the bus's persistent producer-nonce path (producer_nonce_path on EventBusConfig), the id is stable across both within-process retries AND cross-process restart — the MULTI/EXEC-timeout race becomes filterable at consume time.

RedisStreamDedup is the consumer-side helper, exposed on the net PyO3 module:

from net import RedisStreamDedup
import redis

# ~10k events/sec * 1 min dedup window → ~600,000.
dedup = RedisStreamDedup(capacity=600_000)

r = redis.Redis(host="localhost", port=6379)
cursor = "0"
while True:
    # XRANGE bounds are INCLUSIVE on both ends. After the first
    # page we must use the exclusive form `(<id>` so we don't
    # re-read the entry the cursor points at — a vanilla
    # `min=cursor` loop spins forever once the cursor reaches the
    # tail and the same entry is returned every iteration.
    start = cursor if cursor == "0" else f"({cursor}"
    entries = r.xrange("net:shard:0", min=start, max="+", count=100)
    for entry_id, fields in entries:
        dedup_id = fields.get(b"dedup_id", b"").decode()
        if not dedup_id:
            # No dedup_id → older entry or non-Net producer; skip
            # dedup and process as-is.
            process(entry_id, fields)
            continue
        if not dedup.is_duplicate(dedup_id):
            process(entry_id, fields)
        cursor = entry_id.decode()
    if not entries:
        break

Surface:

dedup = RedisStreamDedup()                # default capacity 4096
dedup = RedisStreamDedup(capacity=N)      # explicit; 0 → 1
dedup.is_duplicate(id: str) -> bool       # test-and-insert
dedup.len                                 # property — tracked-id count
dedup.capacity                            # property — configured cap
dedup.is_empty                            # property
dedup.clear()                             # reset (e.g. on consumer-group rebalance)

The helper is transport-agnostic — bring your own redis-py / aioredis / equivalent client; it just answers the dedup question against an in-memory LRU. Concurrency: each handle wraps a Rust Mutex<RedisStreamDedup>, so concurrent calls from multiple Python threads are safe but serialize. Production-shape is one helper per consumer thread.

Security Surface (Stage A–E)

The mesh layer surfaces the same identity / capabilities / subnets / channel-auth story that the Rust SDK and the TypeScript / Node SDKs ship. Full staging and rationale: docs/SDK_SECURITY_SURFACE_PLAN.md. Python-binding parity details: docs/SDK_PYTHON_PARITY_PLAN.md.

Identity + permission tokens

Every node has an ed25519 identity; permission tokens are ed25519- signed delegations that authorize a subject to publish / subscribe / delegate / admin on a channel, optionally with further delegation depth.

from net import Identity, parse_token, verify_token, delegate_token

alice = Identity.generate()
bob = Identity.generate()

# Alice issues Bob a subscribe+delegate token good for 5 min, with
# one re-delegation hop remaining.
token = alice.issue_token(
    subject=bob.entity_id,
    scope=["subscribe", "delegate"],
    channel="sensors/temp",
    ttl_seconds=300,
    delegation_depth=1,
)
assert verify_token(token) is True

# Bob re-delegates to Carol; depth drops to 0 (leaf).
carol = Identity.generate()
child = delegate_token(bob, token, carol.entity_id, ["subscribe"])
assert parse_token(child)["delegation_depth"] == 0

Capability announcements + peer discovery

Announce hardware / software / model / tool / tag fingerprints, then query the local capability index with a filter.

mesh.announce_capabilities({
    "hardware": {
        "cpu_cores": 16,
        "memory_mb": 65536,
        "gpu": {"vendor": "nvidia", "model": "h100", "vram_mb": 81920},
    },
    "models": [{"model_id": "llama-3.1-70b", "family": "llama",
                "context_length": 128_000}],
    "tags": ["gpu", "prod"],
})

gpu_peers = mesh.find_nodes({
    "require_gpu": True,
    "gpu_vendor": "nvidia",
    "min_vram_mb": 40_000,
})

Scoped discovery (reserved scope:* tags)

A provider can narrow who its query result reaches by tagging its CapabilitySet with reserved scope:* tags. Queries call mesh.find_nodes_scoped(filter, scope) to filter candidates. The wire format and forwarders are untouched — enforcement is purely query-side.

# GPU pool advertised to one tenant only.
mesh.announce_capabilities({
    "tags": ["model:llama3-70b", "scope:tenant:oem-123"],
})

# Tenant-scoped query — returns this node + any Global (untagged) peers.
oem_nodes = mesh.find_nodes_scoped(
    {"require_tags": ["model:llama3-70b"]},
    {"kind": "tenant", "tenant": "oem-123"},
)

Accepted scope dict shapes: {"kind": "any"} (default), {"kind": "global_only"}, {"kind": "same_subnet"}, {"kind": "tenant", "tenant": "<id>"}, {"kind": "tenants", "tenants": [...]}, {"kind": "region", "region": "<name>"}, {"kind": "regions", "regions": [...]}. Reserved announcement tags: scope:subnet-local (visible only under same_subnet), scope:tenant:<id>, scope:region:<name> — strictest scope wins. Untagged peers resolve to Global and stay visible under permissive queries. Full design: docs/SCOPED_CAPABILITIES_PLAN.md.

Capability propagation is multi-hop, bounded by MAX_CAPABILITY_HOPS = 16 with (origin, version) dedup on every forwarder. capability_gc_interval_ms controls both the index TTL sweep and the dedup cache eviction. See docs/MULTIHOP_CAPABILITY_PLAN.md.

Subnets

Nodes can bind to a hierarchical SubnetId (1–4 levels, each 0–255) directly, or derive one from announced tags via a SubnetPolicy.

# Explicit subnet.
mesh = NetMesh("127.0.0.1:9000", PSK, subnet=[3, 7, 2])

# Or derive from tags.
mesh = NetMesh(
    "127.0.0.1:9001", PSK,
    subnet_policy={
        "rules": [
            {"tag_prefix": "region:", "level": 0,
             "values": {"eu": 1, "us": 2, "apac": 3}},
            {"tag_prefix": "zone:", "level": 1,
             "values": {"a": 1, "b": 2, "c": 3}},
        ]
    },
)

Channel authentication

Publishers set publish_caps / subscribe_caps / require_token on register_channel. Subscribers present a PermissionToken via the optional token=bytes kwarg on subscribe_channel.

mesh.register_channel(
    "gpu/jobs",
    subscribe_caps={"require_gpu": True, "min_vram_mb": 16_000},
    require_token=True,
)

# Subscriber side, with a token issued by the publisher:
mesh.subscribe_channel(publisher_node_id, "gpu/jobs", token=token_bytes)

Denied subscribes raise ChannelAuthError (a subclass of ChannelError); malformed tokens raise TokenError whose message has the form "token: <kind>" (invalid_signature, expired, delegation_exhausted, …). Successful subscribes populate an AuthGuard bloom filter on the publisher so every subsequent publish admits the subscriber in constant time. An expiry sweep (default 30 s) evicts subscribers whose tokens age out; a per- peer auth-failure rate limiter throttles bad-token storms. Cross- SDK behaviour is fixed by the Rust integration suite; see tests/channel_auth.rs and tests/channel_auth_hardening.rs.

Compute (daemons + migration)

Run MeshDaemons directly from Python. DaemonRuntime owns the factory table, the per-daemon hosts, and the Registering → Ready → ShuttingDown lifecycle gate that decides when inbound migrations may land. Daemons are any Python object whose process(event) returns a list of bytes/bytearray payloads — the runtime wraps each output in a causal link and forwards it.

Build the native module with the compute feature (maturin picks it up on the default build) and import from net. Full design notes: docs/SDK_COMPUTE_SURFACE_PLAN.md.

from net import DaemonRuntime, NetMesh, Identity, CausalEvent


class EchoDaemon:
    """Stateless echo — ships every event's payload straight back."""

    name = "echo"

    def process(self, event: CausalEvent) -> list[bytes]:
        return [bytes(event.payload)]

    # Optional: snapshot() / restore(state) for migration-capable daemons.


mesh = NetMesh("127.0.0.1:9000", "42" * 32)
rt = DaemonRuntime(mesh)

# 1. Register factories BEFORE flipping the runtime to Ready.
rt.register_factory("echo", lambda: EchoDaemon())

# 2. Ready the runtime — after this point spawn / migration accept.
rt.start()

# 3. Spawn a daemon; Identity pins the ed25519 keypair so
#    origin_hash / entity_id stay stable across migrations.
identity = Identity.generate()
handle = rt.spawn("echo", identity)
print(f"origin = 0x{handle.origin_hash:08x}")

# 4. Manually feed an event for testing; real delivery happens
#    via the mesh's causal chain.
event = CausalEvent(handle.origin_hash, sequence=1, payload=b"hello")
outputs = rt.deliver(handle.origin_hash, event)

# 5. Clean shutdown.
rt.stop(handle.origin_hash)
rt.shutdown()

process must be synchronous — the core's contract is sync, and the PyO3 bridge re-attaches the GIL for the duration of each call. Raising inside process surfaces as DaemonError on the caller.

Migration

start_migration(origin_hash, source_node, target_node) orchestrates the six-phase cutover (Snapshot → Transfer → Restore → Replay → Cutover → Complete). The source seals the daemon's ed25519 seed into the outbound snapshot using the target's X25519 static pubkey; the target rebuilds the daemon via the factory registered under the same kind, replays any events that arrived during transfer, then activates.

from net import MigrationError, migration_error_kind

try:
    mig = rt.start_migration(handle.origin_hash, src_node_id, dst_node_id)
    # mig.phase  — "snapshot" | "transfer" | "restore" | ...
    # mig.source_node / mig.target_node
    mig.wait()                      # blocks to completion
except MigrationError as e:
    kind = migration_error_kind(e)
    if kind == "not-ready":               ...  # target start() didn't run
    elif kind == "factory-not-found":     ...  # target missing this kind
    elif kind == "compute-not-supported": ...  # target has no DaemonRuntime
    elif kind == "state-failed":          ...  # snapshot / restore threw
    elif kind == "identity-transport-failed": ...  # seal / unseal failed
    # ...see SDK_COMPUTE_SURFACE_PLAN.md for the full enum

start_migration_with(origin, src, dst, opts) exposes options such as seal_seed=False for test scenarios. On the target node, call rt.register_migration_target_identity(kind, identity) before any migration of that kind lands; without it the runtime rejects sealed-seed envelopes with migration_error_kind == "identity-transport-failed".

Surface at a glance

Method Description
DaemonRuntime(mesh) Construct against an existing NetMesh
rt.register_factory(kind, fn) Install a factory (before start())
rt.start() / rt.shutdown() Flip the lifecycle gate
rt.spawn(kind, identity, config=None) Spawn a local daemon
rt.spawn_from_snapshot(kind, identity, bytes, config=None) Rehydrate
rt.stop(origin) Stop a local daemon
rt.snapshot(origin) Capture bytes for persistence / migration
rt.deliver(origin, event) Feed an event (returns list[bytes])
rt.start_migration(origin, src, dst) Orchestrate a live migration
rt.register_migration_target_identity(kind, id) Pin unseal keypair on target for kind
handle.origin_hash / entity_id / stats() Per-daemon identity + stats
DaemonError / MigrationError Typed exceptions; migration_error_kind(e) parses e.kind

Compute Groups (Replica / Fork / Standby)

HA / scaling overlays on top of DaemonRuntime. Build the native module with the groups feature (implies compute) to expose ReplicaGroup, ForkGroup, StandbyGroup, and the GroupError exception class.

  • ReplicaGroup — N interchangeable copies of a daemon. Deterministic identity from group_seed + index, so a replacement respawned on another node has a stable origin_hash. Load-balances inbound events across healthy members; auto-replaces on node failure.
  • ForkGroup — N independent daemons forked from a common parent at fork_seq. Unique keypairs, shared ancestry via a verifiable ForkRecord.
  • StandbyGroup — active-passive replication. One member processes events; standbys hold snapshots and catch up via sync_standbys(). On active failure the most-synced standby promotes and replays the events buffered since the last sync.
from net import (
    DaemonRuntime, ForkGroup, GroupError, ReplicaGroup, StandbyGroup,
    group_error_kind,
)

rt = DaemonRuntime(mesh)
rt.register_factory("counter", lambda: CounterDaemon())

# --- ReplicaGroup ----------------------------------------------------
replicas = ReplicaGroup.spawn(
    rt, "counter",
    replica_count=3,
    group_seed=bytes([0x11] * 32),
    lb_strategy="consistent-hash",   # or "round-robin" / "least-load"
                                     #    / "least-connections" / "random"
)
origin = replicas.route_event({"routing_key": "user:42"})
rt.deliver(origin, event)
replicas.scale_to(5)                 # grow
replicas.on_node_failure(failed_node_id)   # respawn elsewhere

# --- ForkGroup -------------------------------------------------------
forks = ForkGroup.fork(
    rt, "counter",
    parent_origin=0xABCDEF01,
    fork_seq=42,
    fork_count=3,
    lb_strategy="round-robin",
)
assert forks.verify_lineage()
for record in forks.fork_records():
    print(record["forked_origin"], record["fork_seq"])

# --- StandbyGroup ----------------------------------------------------
hot = StandbyGroup.spawn(
    rt, "counter",
    member_count=3,                  # 1 active + 2 standbys
    group_seed=bytes([0x77] * 32),
)
rt.deliver(hot.active_origin, event)
hot.sync_standbys()                  # periodic catchup
# On active-node failure:
# new_origin = hot.on_node_failure(failed_node_id)  # auto-promotes

Typed errors

Failures raise GroupError (a subclass of DaemonError). Use group_error_kind(e) to parse the discriminator from the Rust side's daemon: group: <kind>[: detail] message prefix:

from net import GroupError, group_error_kind

try:
    ReplicaGroup.spawn(rt, "never-registered",
                       replica_count=2, group_seed=bytes(32))
except GroupError as e:
    kind = group_error_kind(e)
    if kind == "not-ready":               ...  # runtime.start() didn't run
    elif kind == "factory-not-found":     ...  # kind wasn't registered
    elif kind == "no-healthy-member":     ...  # routed on an all-down group
    elif kind == "invalid-config":        ...  # e.g. replica_count == 0
    elif kind in ("placement-failed",
                  "registry-failed",
                  "daemon"):              ...  # core failure — read e args

Full staging, wire formats, and rationale: docs/SDK_GROUPS_SURFACE_PLAN.md. Core semantics live in the main README.md#daemons.

Performance Tips

  1. Use ingest_raw() for maximum throughput - Pass pre-serialized JSON strings
  2. Use ingest_raw_batch() for bulk operations - Reduces per-call overhead
  3. Increase ring_buffer_capacity - Larger buffers handle bursts better
  4. Match num_shards to CPU cores - Default is optimal for most cases

License

Apache-2.0

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

ai2070_net-0.8.0.tar.gz (2.6 MB view details)

Uploaded Source

Built Distributions

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

ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded PyPymanylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp314-cp314t-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp314-cp314-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.14Windows x86-64

ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp314-cp314-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

ai2070_net-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

ai2070_net-0.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.13tmanylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp313-cp313-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.13Windows x86-64

ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp313-cp313-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

ai2070_net-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

ai2070_net-0.8.0-cp312-cp312-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.12Windows x86-64

ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp312-cp312-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

ai2070_net-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

ai2070_net-0.8.0-cp311-cp311-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.11Windows x86-64

ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

ai2070_net-0.8.0-cp311-cp311-macosx_11_0_arm64.whl (1.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

ai2070_net-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

ai2070_net-0.8.0-cp310-cp310-win_amd64.whl (1.5 MB view details)

Uploaded CPython 3.10Windows x86-64

ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

File details

Details for the file ai2070_net-0.8.0.tar.gz.

File metadata

  • Download URL: ai2070_net-0.8.0.tar.gz
  • Upload date:
  • Size: 2.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0.tar.gz
Algorithm Hash digest
SHA256 4d15c10ea91535c746a31b27cec3490b9e84f057582ebd0112afaf66d7fed924
MD5 871bbe163528d437deed6cdf524dce72
BLAKE2b-256 90df4c09de569550add8b4f2459133c32a2cfe1210573d38f499b2be1049c1ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0.tar.gz:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5de7eda32c908af8e31bb660b2e56ee2e806497d60b4ff403f975a6127ddd7c0
MD5 59e909ba16885611976fe74ad19b477b
BLAKE2b-256 f07aa04c247e9ed607aaeb97677c9106e6fc938e9c7e80a08b66ce8ca55c17dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 aa474c3f02b1133382096065bf73ce5686e1030979cba27fe2e5faab5babb96f
MD5 c46e9395064561306b1e8add22b433d2
BLAKE2b-256 2c8c32d83d3a3e363fa32350a0403ca8726b01fb35323daf73056ae7703d0a26

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314t-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3d4627ea0dc644fca576f433af25b6eec3d7fb8e8fbdb2f60d6c277f25acc40c
MD5 2176850bba8d80102c805d9392aacec0
BLAKE2b-256 d584c435093bd8edf98b2107df4e645700ed198ef4df8d5ba8d92ee12a9338f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314t-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: ai2070_net-0.8.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 545bd88f441d9cb38a1ac5fbf7ef8317131f1962d4ddaf40d562f62385b9b217
MD5 94601a063d5b51c59c3255e8cae2e1be
BLAKE2b-256 0703ef8f18d0a63ba267d2bacc1a601c712ce856b32895e4a7776e85d868df7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314-win_amd64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5b74ecb9567b38b5d83390f224aba0812c247d6210ad199ef5804eaefbc3ccf9
MD5 7be79dba272c5e2477161a544e237f55
BLAKE2b-256 5e028986525830944b505758f72c70e3aa7cc31bb5ff74a18d33b9a7c9692c87

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 19fc005c95888d8eb3e59186891648d3afdcf0866def85ccc3478a972de665bf
MD5 8e4a8d97aacdf506f8ae7555a4a0e1ab
BLAKE2b-256 34a4f45e1aec93a7221757ec91da2bb850562a72b6f9cb1d089179f39d1c0297

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd2be12b6c1c2dbd3bc41a9787bba822bced8be6855cf137d81dbed4c1db03b4
MD5 0f343578e6134eeea99554ea7363e68a
BLAKE2b-256 f64af299c88165d71bcdb0a592b81454d7e0ebb912312aa111567490a3a378cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 8c403628176047fb8c3089911c08e9f00166e09c75965231e7faa7436785e747
MD5 515d2ffbce9168460ad0977ce5405b3a
BLAKE2b-256 c1d965a51e7618e1350808ddf6333189ffdf9773a5529a6c369e617446bbada1

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 03006b9e3ea3ec6f9a3cb751fe14eba7d3ad7887593767d397cca569c6667645
MD5 215cb52e8249d9ae90d7e95b9245e123
BLAKE2b-256 3c25d40c6d7b1144bcd6503baca4ed1bfb9413142cda861a20fe5468e1622a24

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313t-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: ai2070_net-0.8.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 96738b07d28cdfadaca28a54e04a3de86c4259ba1d9c5ade281916e851131f20
MD5 9ce073dc1c4e475c54ad38b9566ce011
BLAKE2b-256 1329002d01299a218d21f671ee6a02b33fce3888fae0a48a808944b4daf9c5a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313-win_amd64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 738da31bc3b532e8d71b10269f4d9d9e239c694d28385d113a3afeac23453a12
MD5 fffdb6d92038b7da43a8289f1fdc3137
BLAKE2b-256 7a5340403af0af29e0a3cf1be768a6d6ebecbf5aae64dd9dfc8e17578aca3846

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d4b1d31410a214aae1fc056636a86c962b9418e0d83950cc5fea437e44980363
MD5 92f9fffe0c38a26fb32e16cd3f43ce00
BLAKE2b-256 cdf77659fd725e63e5c10b242f1bfb2a16c6d31241c1365770749d08357964c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7284657f7339959bb74261a8b10cf0173506f4e8d86535898eb6d3e1fce8315d
MD5 73eb7bb013c64d67df704ee096550449
BLAKE2b-256 152dfe92b76fe7c7f469bf1da639073647b22ecf39e9745bf2694f66fb50332a

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 88486b8337fbefd4183a523a12547c0139e353cad130fc1caa3a74eb5ce6738d
MD5 b81c81b0b78606983f82819c412b86a5
BLAKE2b-256 f10ec145acf857215f6ff5944e7c778b85be3b7b6e2cf04acace06123607ac7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: ai2070_net-0.8.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 40490bf64dd96f43506ec8ba53e1b82409cfb4f8e8731f63983f09fac3fe18ca
MD5 010b2bcbc323ba8a8817a4f2eb0b65a6
BLAKE2b-256 17eeaba853c48d5c1e96d8294a4b41cdcfb65aeb8d35d4cdef793e8a47767ccf

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp312-cp312-win_amd64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d1c5c3c42aa5f84e34130bae67d2de0a35385b98ffd43b4b80d43b6104380c4f
MD5 52e0cefd3f7294906cb188b27b00c5c6
BLAKE2b-256 cc64441f05b04fd8948e76064c94e6cc8a84b56e7e64dac81faecc9b5b6e2078

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8cc8e078392354a85ddc1c217a8919f6920e136f420654d235365f4babf33d24
MD5 0e071491bfd17fa357be065a18b0b885
BLAKE2b-256 00e3e3f9cace07073ecd0e748bf2fee59ee669266481beb49923b13058aaffa2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp312-cp312-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b1778d6d6107c1c632599a46f27662aa1c675bbd0c5c35b4e3b76930f2f2bad5
MD5 ef84e6a7432e9fc41c064d23ee44898a
BLAKE2b-256 b4bbc0d1ce99a428c21b9acecfe47e2429216650b0b5065fe7a10d76b43e7172

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fd47c92f6d44dff4513a9141b8bda459ead619386f4c9ae79e31c6be24f18978
MD5 e699e79797f5fdd86c5ebb535d60aab8
BLAKE2b-256 30ce9834c34c7b81b36d7c4a3789d892b99a677c4b7b5e3a20813b3716d608f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: ai2070_net-0.8.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 f6f425c429f382ea7671f34b292d0b3e5bf477fc648aaefc340cdaa016e2479b
MD5 e5a623d8a0a0d6589aeffe585a1cba93
BLAKE2b-256 7ce26d0c7f2db8b8e033df1e00efeb3de6081bb1b71dac687d68fb5f3440b718

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp311-cp311-win_amd64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 38a08346cd32026edff75e903c9108b4c4d4a45e791389492a659f28c6937477
MD5 05e8c93059c04d1bc6fe4533c396513d
BLAKE2b-256 37f5ca33fba137c4afc351b1b967643c3c8a12240dcfa07c6a9f7b3d17191129

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0a3ca5c68d4dca1ec2973daabd0172f1fa60f49d1099d46645ef24b0af121b50
MD5 4e5a56582616838ab08fe4b0c0decff8
BLAKE2b-256 86053188a629f8623e99c4f38488699429456dbc1018e717166558b7c796181f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp311-cp311-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 15011df94b6ba16a511556f897de3cff1b2fbb16b9dcc39f44fa3870d9eea19c
MD5 64f803ccd1903e556785ae98af2c563b
BLAKE2b-256 98c359e037288264fc54e09209671292a3e531db2db699388cede332f7c83aa6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c3ac6669c529b91835c14a6451ffc75b13526d8d83def3120caa7c4d76df69e9
MD5 4cb9065f20da5ec255e7c57b19302143
BLAKE2b-256 af59a8eb8f37381fecc20423ece66e7c7c45ffb8a66aee5d6803f2a1b0c0bb41

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: ai2070_net-0.8.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 1.5 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ai2070_net-0.8.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 0bda7bac48cd23ce50859778e4f066965d038de2c2183f88beffbfe2574997f9
MD5 4eeeb30088c271b5c7345677b6a4cfaa
BLAKE2b-256 21ce84b4aaaf74e5008d054aec46f01946bd46c28e9de426e29c53eb20a4833d

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp310-cp310-win_amd64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4572e959ffff8dbc372d8503e8240a1b2c8d577e6ff565be195b29d1aecff1f4
MD5 c33c6580d5bca719799aae3ac12a4307
BLAKE2b-256 20cf5fc42c3fba0394fc343ff45e8f1af63db0199855ead2cea89ca7c7538ea3

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: release-python.yml on ai-2070/net

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

File details

Details for the file ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 73b9da8098b7f2f6bca15230185053207df77b33deab5423fd95dd4dde1ee5d5
MD5 d4492e7ea2fa2c86846ab80524244d25
BLAKE2b-256 0f14f01f591955431ee04157a80a0418a1c3a83d581178e0d546be8335b518d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai2070_net-0.8.0-cp310-cp310-manylinux_2_28_aarch64.whl:

Publisher: release-python.yml on ai-2070/net

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