Skip to main content

C-Two is a resource-RPC framework that enables resource-oriented classes to be remotely invoked across different processes or machines.

Project description

C-Two

A resource-oriented RPC framework for Python — turn stateful classes into location-transparent distributed resources.

PyPI Downloads Python Free-threading CI License

中文版


Basic Idea

  • Resources, not services — C-Two doesn't expose RPC endpoints. It makes Python classes remotely accessible while preserving their stateful, object-oriented nature.

  • Zero-copy from process to data — Same-process calls skip serialization entirely. Cross-process IPC can hold shared-memory buffers alive, letting you read columnar data (NumPy, Arrow, …) directly from SHM — no deserialization, no copies.

  • Built for scientific Python — Native support for Apache Arrow, NumPy arrays, and large payloads (chunked streaming for data beyond 256 MB). Designed for computational workloads, not microservices.

  • Rust-powered transport — The IPC layer uses a Rust buddy allocator for shared memory and a Rust HTTP relay for high-throughput networking.


Performance

End-to-end cross-process IPC benchmark — same NumPy payload (row_id u32 + x,y,z f64), same machine, same aggregation. Three transport modes compared:

Rows C-Two hold (ms) Ray (ms) C-Two pickle (ms) Hold vs Ray
1 K 0.07 6.1 0.19 86×
10 K 0.09 7.1 0.82 79×
100 K 0.38 9.8 8.7 26×
1 M 3.7 58 150 15×
3 M 9.7 129 598 13×
  • C-Two hold — SHM zero-copy via np.frombuffer; no serialization on read
  • Ray — object store with zero-copy numpy support (Ray 2.55)
  • C-Two pickle — standard pickle over SHM; included to show serialization cost

Apple M1 Max · Python 3.13 · NumPy 2.4 · See benchmarks/unified_numpy_benchmark.py for full methodology.


Quick Start

pip install c-two

Define a resource contract and its implementation

import c_two as cc

# CRM contract — declares which methods are remotely accessible
@cc.crm(namespace='demo.counter', version='0.1.0')
class Counter:
    def increment(self, amount: int) -> int: ...

    @cc.read
    def value(self) -> int: ...

    def reset(self) -> int: ...


# Resource — a plain Python class implementing the contract
class CounterImpl:
    def __init__(self, initial: int = 0):
        self._value = initial

    def increment(self, amount: int) -> int:
        self._value += amount
        return self._value

    def value(self) -> int:
        return self._value

    def reset(self) -> int:
        old = self._value
        self._value = 0
        return old

Use it locally (zero serialization)

cc.register(Counter, CounterImpl(initial=100), name='counter')
counter = cc.connect(Counter, name='counter')

counter.increment(10)    # → 110
counter.value()          # → 110
counter.reset()          # → 110 (returns old value)
counter.value()          # → 0

cc.close(counter)

Or remotely — same API, different address

# Server process
cc.set_address('ipc:///tmp/my_server')
cc.register(Counter, CounterImpl(), name='counter')

# Client process (separate terminal)
counter = cc.connect(Counter, name='counter', address='ipc:///tmp/my_server')
counter.increment(5)     # works identically
cc.close(counter)

See examples/ for complete runnable demos.


Core Concepts

CRM — Contract

A CRM (Core Resource Model) declares which methods a remote resource exposes. It's decorated with @cc.crm(), and method bodies are ... (pure interface — no implementation).

@cc.crm(namespace='demo.greeter', version='0.1.0')
class Greeter:
    @cc.read                              # concurrent reads allowed
    def greet(self, name: str) -> str: ...

    @cc.read
    def language(self) -> str: ...

Methods can be annotated with @cc.read (concurrent access allowed) or left as default write (exclusive access).

Resource — Runtime Instance

A resource is a plain Python class that implements a CRM contract. It holds state and domain logic. It is not decorated — the framework discovers its methods through the CRM contract it was registered under. Name the class by what it is (GreeterImpl, PostgresGreeter, MultilingualGreeter), not the interface.

class GreeterImpl:
    def __init__(self, lang: str = 'en'):
        self._lang = lang
        self._templates = {'en': 'Hello, {}!', 'zh': '你好, {}!'}

    def greet(self, name: str) -> str:
        return self._templates.get(self._lang, 'Hi, {}!').format(name)

    def language(self) -> str:
        return self._lang

Client — Consumer

Anything that calls cc.connect(...) is a client (or consumer / application code). The returned proxy is location-transparent — it works the same whether the resource lives in the same process or on a remote machine.

greeter = cc.connect(Greeter, name='greeter')
greeter.greet('World')     # → 'Hello, World!'
cc.close(greeter)

# Or with context manager:
with cc.connect(Greeter, name='greeter') as greeter:
    greeter.greet('World')

Server — Resource Host

A server is any process that calls cc.register(...) to host one or more resources, then usually cc.serve() to block on the request loop. One server process can host many resources (each under a unique name), and will auto-bind an IPC endpoint the first time a resource is registered.

import c_two as cc

cc.set_address('ipc://my_server')              # optional — default is auto UUID path
cc.register(Greeter, GreeterImpl(), name='greeter')
cc.register(Counter, CounterImpl(), name='counter')
cc.serve()                                     # blocks; Ctrl-C triggers graceful shutdown
  • Address (ipc://...) is the local transport endpoint. Clients in the same process skip it entirely (zero serialization); clients in a different process on the same host connect to this address directly.
  • cc.serve() is optional — if your host process has its own event loop (web server, GUI, simulation), you can register resources and let them serve in the background while your main loop runs.
  • A process can be both a server and a client at the same time (register some resources, connect to others).

Relay — Distributed Discovery

An HTTP relay (c3 relay) is a lightweight broker that lets clients reach servers by name, across machines. Servers announce their IPC address to the relay when they register; clients ask the relay and get routed transparently.

# Start a relay anywhere reachable on your network
c3 relay --bind 0.0.0.0:8080
# Server side — announce resources to the relay
cc.set_relay('http://relay-host:8080')
cc.register(MeshStore, MeshStoreImpl(), name='mesh')
cc.serve()

# Client side — resolve by name, no address needed
cc.set_relay('http://relay-host:8080')
mesh = cc.connect(MeshStore, name='mesh')

Multiple relays can form a mesh cluster via gossip — any relay can resolve any resource registered anywhere in the mesh. See the Relay Mesh example below.

When do I need a relay? Only for cross-machine or name-based discovery. Same-process and same-host (IPC) usage work without any relay.

@transferable — Custom Serialization

For custom data types that need to cross the wire, use @cc.transferable. Without it, pickle is used as fallback.

A transferable class defines up to three static methods (written without @staticmethod — the framework adds it automatically):

Method Required Purpose
serialize(data) → bytes ✅ Yes Encode data for wire transfer (outbound)
deserialize(raw) → T ✅ Yes Decode wire bytes into an owned Python object (inbound)
from_buffer(buf) → T ❌ Optional Build a zero-copy view over the raw buffer (inbound, hold mode)
import numpy as np

@cc.transferable
class Matrix:
    rows: int
    cols: int
    data: np.ndarray

    def serialize(mat: 'Matrix') -> bytes:
        header = struct.pack('>II', mat.rows, mat.cols)
        return header + mat.data.tobytes()

    def deserialize(raw: bytes) -> 'Matrix':
        rows, cols = struct.unpack_from('>II', raw)
        arr = np.frombuffer(raw, dtype=np.float64, offset=8).reshape(rows, cols)
        return Matrix(rows=rows, cols=cols, data=arr.copy())  # owned copy

    def from_buffer(buf: memoryview) -> 'Matrix':
        header = bytes(buf[:8])
        rows, cols = struct.unpack('>II', header)
        arr = np.frombuffer(buf[8:], dtype=np.float64).reshape(rows, cols)
        return Matrix(rows=rows, cols=cols, data=arr)  # zero-copy view into SHM

When from_buffer is present, the server automatically uses hold mode — the SHM buffer stays alive so from_buffer can return a zero-copy view. Without from_buffer, the server uses view mode — the buffer is released immediately after deserialize.

@cc.transfer — Per-Method Control

Use @cc.transfer() on CRM contract methods to explicitly specify which transferable type handles serialization, or to override the buffer mode:

@cc.crm(namespace='demo.compute', version='0.1.0')
class Compute:
    @cc.transfer(input=Matrix, output=Matrix, buffer='hold')
    def transform(self, mat: Matrix) -> Matrix: ...

    @cc.transfer(input=Matrix, buffer='view')  # force copy even if from_buffer exists
    def ingest(self, mat: Matrix) -> None: ...

Without @cc.transfer, the framework automatically matches registered @transferable types by function signature and resolves the buffer mode from the input type's capabilities.

cc.hold() — Client-Side Zero-Copy

On the client side, cc.hold() requests that the response SHM buffer remain alive, enabling zero-copy reads of the result. The returned HeldResult wraps the value and provides a three-layer safety net for SHM lifecycle:

  1. Explicit .release() — preferred for complex workflows holding multiple buffers
  2. Context manager (with) — recommended for single-buffer scopes
  3. __del__ fallback — last resort, emits ResourceWarning if you forget to release
grid = cc.connect(Compute, name='compute', address='ipc://server')

# Normal call — buffer released immediately after deserialize
result = grid.transform(matrix)

# Option 1: Context manager — clean for single holds
with cc.hold(grid.transform)(matrix) as held:
    data = held.value          # zero-copy NumPy array backed by SHM
    process(data)              # read directly from shared memory
# SHM buffer released on context exit

# Option 2: Explicit release — better for multiple concurrent holds
a = cc.hold(grid.transform)(matrix_a)
b = cc.hold(grid.transform)(matrix_b)
try:
    combined = np.concatenate([a.value.data, b.value.data])
    process(combined)
finally:
    a.release()
    b.release()

When to use hold mode: Large array/columnar data where deserialization dominates cost. For small payloads (< 1 MB), the overhead of tracking SHM lifecycle exceeds the copy cost.


Examples

Single Process — Thread Preference

When cc.connect() targets a CRM registered in the same process, the proxy calls methods directly with zero serialization overhead.

import c_two as cc

cc.register(Greeter, Greeter(lang='en'), name='greeter')
cc.register(Counter, Counter(initial=100), name='counter')

greeter = cc.connect(Greeter, name='greeter')
counter = cc.connect(Counter, name='counter')

print(greeter.greet('World'))    # → Hello, World!
print(counter.value())           # → 100
counter.increment(10)

cc.close(greeter)
cc.close(counter)
cc.shutdown()

Best for: local prototyping, testing, single-machine computation.

Multi-Process IPC — with Custom Transferable

Separate server and client processes communicating over Unix domain sockets with shared memory.

Shared types (types.py):

import c_two as cc
import numpy as np, struct

@cc.transferable
class Mesh:
    n_vertices: int
    positions: np.ndarray   # (N, 3) float64

    def serialize(mesh: 'Mesh') -> bytes:
        header = struct.pack('>I', mesh.n_vertices)
        return header + mesh.positions.tobytes()

    def deserialize(raw: bytes) -> 'Mesh':
        (n,) = struct.unpack_from('>I', raw)
        arr = np.frombuffer(raw, dtype=np.float64, offset=4).reshape(n, 3).copy()
        return Mesh(n_vertices=n, positions=arr)

    def from_buffer(buf: memoryview) -> 'Mesh':
        header = bytes(buf[:4])
        (n,) = struct.unpack('>I', header)
        arr = np.frombuffer(buf[4:], dtype=np.float64).reshape(n, 3)
        return Mesh(n_vertices=n, positions=arr)  # zero-copy view

@cc.crm(namespace='demo.mesh', version='0.1.0')
class MeshStore:
    @cc.read
    def get_mesh(self) -> Mesh: ...

    def update_positions(self, mesh: Mesh) -> int: ...

    @cc.on_shutdown
    def cleanup(self) -> None: ...

Server (server.py):

import c_two as cc
from types import MeshStore, Mesh

class MeshStore:
    def __init__(self):
        self._mesh = Mesh(n_vertices=0, positions=np.empty((0, 3)))

    def get_mesh(self) -> Mesh:
        return self._mesh

    def update_positions(self, mesh: Mesh) -> int:
        self._mesh = mesh
        return mesh.n_vertices

    def cleanup(self):
        print('MeshStore shutting down')

cc.set_address('ipc://mesh_server')
cc.register(MeshStore, MeshStore(), name='mesh')
cc.serve()  # blocks until interrupted

Client (client.py):

import c_two as cc
from types import MeshStore, Mesh
import numpy as np

mesh_store = cc.connect(MeshStore, name='mesh', address='ipc://mesh_server')

# Upload data
big_mesh = Mesh(n_vertices=1_000_000,
                positions=np.random.randn(1_000_000, 3))
mesh_store.update_positions(big_mesh)

# Read with hold — zero-copy SHM access
with cc.hold(mesh_store.get_mesh)() as held:
    positions = held.value.positions  # np.ndarray backed by SHM, no copy
    centroid = positions.mean(axis=0)
    print(f'Centroid: {centroid}')
# SHM released here

cc.close(mesh_store)

Best for: multi-process on same host, worker isolation, high-throughput local IPC.

Cross-Machine — HTTP Relay

An HTTP relay bridges network requests to CRM processes running on IPC. CRM processes register with the relay, and clients discover resources by name.

CRM Server (resource.py):

import c_two as cc

cc.set_relay('http://relay-host:8080')
cc.set_address('ipc://mesh_server')
cc.register(MeshStore, MeshStore(), name='mesh')
cc.serve()  # blocks until Ctrl-C

Relay — start via the c3 CLI:

# Bind address from CLI flag, env var C2_RELAY_BIND, or .env file
c3 relay --bind 0.0.0.0:8080

Client (client.py):

import c_two as cc

cc.set_relay('http://relay-host:8080')
mesh = cc.connect(MeshStore, name='mesh')  # relay resolves the name
mesh.get_mesh()
cc.close(mesh)

Best for: network-accessible services, web integration, cross-machine deployment.

Relay Mesh — Multi-Relay Clusters

Multiple relays form a mesh network with gossip-based route propagation. CRMs register with their local relay; clients discover resources across the entire cluster.

# Start relay A (seeds point to peer relays for auto-join)
c3 relay --bind 0.0.0.0:8080 --relay-id relay-a \
    --advertise-url http://relay-a:8080 --seeds http://relay-b:8080

# Start relay B
c3 relay --bind 0.0.0.0:8080 --relay-id relay-b \
    --advertise-url http://relay-b:8080 --seeds http://relay-a:8080

CRM processes register with their local relay; the mesh propagates routes automatically. Clients can connect through any relay in the mesh.

Best for: multi-node clusters, high availability, geographic distribution.

See examples/relay_mesh/ for a complete runnable mesh demo.

Server-Side Monitoring

Use cc.hold_stats() to monitor SHM buffers held by resource methods in hold mode:

stats = cc.hold_stats()
# {'active_holds': 3, 'total_held_bytes': 52428800, 'oldest_hold_seconds': 12.5}

Architecture

The design philosophy of C-Two is not to define services, but to empower resources.

In scientific computation, resources encapsulating complex state and domain-specific operations need to be organized into cohesive units. We call the contracts describing these resources Core Resource Models (CRMs). Applications care more about how to interact with resources than where they are located. C-Two provides location transparency and uniform resource access, so any client can interact with a resource as if it were a local object.

graph LR
    subgraph Client Layer
        C1[Client] -->|cc.connect| P1[CRM Proxy]
        C2[Client] -->|cc.connect| P2[CRM Proxy]
    end

    subgraph Transport Layer
        P1 --> T{Protocol<br/>Auto-detect}
        P2 --> T
        T -->|thread://| TH[Thread<br/>Direct Call]
        T -->|ipc://| IPC[IPC<br/>UDS + SHM]
        T -->|http://| HTTP[HTTP<br/>Relay]
    end

    subgraph Resource Layer
        TH --> CRM1[Resource Instance]
        IPC --> CRM1
        HTTP --> CRM1
    end

Client Layer

Any code that calls cc.connect(...) to consume a resource. The returned proxy provides full type safety and location transparency — clients don't know (or care) where the resource is running.

  • cc.connect(CRMClass, name='...', address='...') returns a typed CRM proxy
  • The proxy supports context management: with cc.connect(...) as x: auto-closes

Resource Layer

Server-side stateful instances exposed through standardized CRM contracts.

  • CRM contract: Interface class decorated with @cc.crm(). Only methods declared here are remotely accessible.
  • Resource: Plain Python class implementing the contract — state + domain logic. Not decorated.
  • @transferable: Custom serialization for domain data types. Optionally provides from_buffer for zero-copy SHM views.
  • @cc.transfer: Per-method control over input/output transferable types and buffer mode.
  • @cc.read / @cc.write: Concurrency annotations — parallel reads, exclusive writes.
  • @cc.on_shutdown: Lifecycle callback invoked when a resource is unregistered (not exposed via RPC).

Transport Layer

Protocol-agnostic communication with automatic protocol detection based on address scheme:

Scheme Transport Use case
thread:// In-process direct call Zero serialization, testing
ipc:///path Unix domain socket + shared memory Multi-process, same host
http://host:port HTTP relay Cross-machine, web-compatible

The IPC transport uses a control-plane / data-plane separation: method routing flows through UDS inline frames while payload bytes are exchanged via shared memory — zero-copy on the data path. When from_buffer is available, hold mode keeps the SHM buffer alive across the CRM method call, enabling the CRM to operate directly on shared memory without deserialization.

Rust Native Layer

Performance-critical components are implemented in Rust and compiled as a Python extension via PyO3 + maturin:

The Rust workspace contains 7 crates organized in 4 layers (foundation → protocol → transport → bridge):

  • Buddy Allocator — Zero-syscall shared memory allocation for the IPC transport. Cross-process, lock-free on the fast path.
  • Wire Protocol — Frame encoding, chunk assembly, and chunk registry for large-payload lifecycle management.
  • HTTP Relay — High-throughput axum-based gateway bridging HTTP to IPC. Handles connection pooling and request multiplexing.

The Rust extension is compiled automatically during pip install c-two (from pre-built wheels) or uv sync (from source).


Installation

From PyPI

pip install c-two

Pre-built wheels are available for:

  • Linux: x86_64, aarch64
  • macOS: Apple Silicon (aarch64), Intel (x86_64)
  • Python: 3.10, 3.11, 3.12, 3.13, 3.14, 3.14t (free-threading)

If no pre-built wheel is available for your platform, pip will build from source (requires a Rust toolchain).

Development Setup

git clone https://github.com/world-in-progress/c-two.git
cd c-two
cp .env.example .env               # configure environment (optional)
uv sync                            # install dependencies + compile Rust extensions
uv sync --group examples           # install examples dependencies (pandas, pyarrow)
uv run pytest                      # run the test suite

Requires uv and a Rust toolchain.


Roadmap

Feature Status
Core RPC framework (CRM + Resource + Client) ✅ Stable
IPC transport with SHM buddy allocator ✅ Stable
HTTP relay (Rust-powered) ✅ Stable
Relay mesh with gossip-based discovery ✅ Stable
Chunked streaming (payloads > 256 MB) ✅ Stable
Heartbeat & connection management ✅ Stable
Read/write concurrency control ✅ Stable
Unified config architecture (Python SSOT) ✅ Stable
CI/CD & multi-platform PyPI publishing ✅ Stable
Disk spill for extreme payloads ✅ Stable
Hold mode with from_buffer zero-copy ✅ Stable
SHM residence monitoring (cc.hold_stats()) ✅ Stable
Async interfaces 🔜 Planned
Cross-language clients (TypeScript/Rust) 🔮 Future

See the full roadmap for details.


License

MIT


Built for scientific Python. Powered by Rust.

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

c_two-0.4.6.tar.gz (199.3 kB view details)

Uploaded Source

Built Distributions

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

c_two-0.4.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

c_two-0.4.6-cp314-cp314t-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.14tmacOS 10.12+ x86-64

c_two-0.4.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp314-cp314-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

c_two-0.4.6-cp314-cp314-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

c_two-0.4.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp313-cp313-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

c_two-0.4.6-cp313-cp313-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

c_two-0.4.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp312-cp312-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

c_two-0.4.6-cp312-cp312-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

c_two-0.4.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp311-cp311-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

c_two-0.4.6-cp311-cp311-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

c_two-0.4.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

c_two-0.4.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

c_two-0.4.6-cp310-cp310-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

c_two-0.4.6-cp310-cp310-macosx_10_12_x86_64.whl (2.7 MB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

Details for the file c_two-0.4.6.tar.gz.

File metadata

  • Download URL: c_two-0.4.6.tar.gz
  • Upload date:
  • Size: 199.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for c_two-0.4.6.tar.gz
Algorithm Hash digest
SHA256 f55b0ca072006895d6e963b1ef322ccd03cf8a33dc48d98a0d0f622881197283
MD5 b79f6c1eefb9daab21a4b3b977f6ed79
BLAKE2b-256 5ae5b7a4410327802d0fe098052cf54effb17843da5fabde29e27053c01bbfdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6.tar.gz:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9c86171a3fd2a72edb85a717ce8656024f5dbecef4315a64bce8d095de5056d9
MD5 392c72071d0c206953f3867dc7783a3f
BLAKE2b-256 aa166a165a2286291056bdb8114d8519d01d9c0dadb5ff1c32cd51ebd2d34daf

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2c71bd2f76776f8f94038812ad9a80b5dfd85ca04423f3109761127255492b5f
MD5 0ad8f01993f76a782dba1b85655e1eab
BLAKE2b-256 44c21c02e1bd8f1402685514e153efa7af807970f1be9919c545fe66ca0ece32

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e55a64511e99b8a7f612d7efdceafcfd047fc93a3d111d79680e01d3ab1b83a5
MD5 4d49c3d7f7ae73bafa5832f4a32d008e
BLAKE2b-256 2160b1fab851754cab24f08f9f738ce4359a9a09bf0fac31d6fbbf0099012b4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314t-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314t-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 145bab01672533d4fb8df3f2fe16ce3a54f52068a511601b1e255637c0e872aa
MD5 4a3d12dd31e1398ed2059f9cac47ebfb
BLAKE2b-256 3a5f2e6f9192178b1e82bac1d306a2774cc01213bb2cf4d76bd54cbcd401d477

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314t-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 249ec9411a1f26d923fda9fb9c09e1d52098678619ac3143c9c6b9670559faf3
MD5 cba2c9d1852b1c307e4bebf259691de0
BLAKE2b-256 85bcbec07d029638fed59218bfb0c30bd96410df3fe450efe82fd8ca54885f98

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 242c41baedfe01e583cae830abc824bb02ae91faf21123f9dbddb9b970ac0e55
MD5 8969beeebddfe8ecbf45029d6feafc9c
BLAKE2b-256 799aefdac13bd7ae5214041d88455d904173c8187d853a7a558353e9c0c8d5cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f62091fd38b424ccf588d7993eb7fef31c76081046187c60b0feb9e0e4a03aa7
MD5 db2dfd03c0029c653431a8155355f69a
BLAKE2b-256 818dd0415ae32e741e14eaf04df126da94d7da1ff51e60e078bcfd771b0f89fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 28e298de3bb7b1350140d14d03742b3581ec3e11d4dcadd81b3581069c3c9b2a
MD5 baa66ec9a5abf9eb74818affddac6bd4
BLAKE2b-256 04545f2ef85751dde13cfffdced0b2fed74fc2e1bb207d2a25a7b8d89dd2068b

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d1d7ede5b0e258209cd48f7de23fe089a8feae2d173c167c31c50605f65971d2
MD5 ac6a32a0793b5e552796f7565898202f
BLAKE2b-256 04d80c75a900689707cee8864e7233dd79435aa71870e3554b4bddd3755003be

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a9d04a1438242aea0efe3347ad16aa21a9565ce15b694f48be33fc8b55294fd0
MD5 b183c931dd0a09e51d969a0dbc5394a7
BLAKE2b-256 2fee0960695b5c071ca99b5721e2ba5eda4a5d9bbfbecc2eeb625be84f2f8e2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c15e902f160bb6df9db867067187efbdcf6e177aef5a40fb24bb3999caad74ce
MD5 adffd039cd6dcbea72cadf53ec6d630e
BLAKE2b-256 dd3b36d9a4455f885997ebff09ecaeb700c659bcafadf944b23ea6d4a991851f

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6e6dc3b374fce3c1a6c0e144e8e736e823c341240cf0a911ae2a4e1bf8693754
MD5 20dd7bef5abf82e004ba8e6888cb0d59
BLAKE2b-256 cbd73a283c5cfc085b50b1c1aa9fbd4b81c5cae89fc9fa862a0390fb80a634dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 608e6a0670fb9570b321a9c95266e92aa64cda6361cc33dd50e0975565507f24
MD5 6f909da401b1f54308b4e765e683fe10
BLAKE2b-256 99aae844721e59f472ad261ffcacd9c7ef50f1fba77cd31dd6fb5451218b1476

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1e898f4d11d429060dbf7fff451b065265f3163e7292c75a6fc4938956ba5515
MD5 beb5e474fa79ce87b3c66832ee2da7f1
BLAKE2b-256 8e52773318a0685e457c04a4ab914588b3c34fb9b7f9d944ccc7293925e65968

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c0ca0d7eea2d9b3d343770ea39eb80c43c0b3d0220846ab0b53cd579ac797679
MD5 95b5790f5521e8dda41574793db7b1a6
BLAKE2b-256 2860e073deb23c8cb305afd18c6b2c0c8ee867993e847951e8c9a06a2db1702c

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3a6e624ae91c2d0de0f454f2dc1b02c769c8928aea7da34e062d62b9861b4e16
MD5 3fc5f9fb6b6b12f06498449332ecf5fd
BLAKE2b-256 3f9a692125863cbeb86a5d6f9ef1bece3f9c3451272c2cc6f0c6c6582882b615

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 87406e546214a47bbb4a15527953b1df57ef0ed37be0c45e8686dc24626c4d32
MD5 9eadfdc335db64bd9980844939342924
BLAKE2b-256 e71b494864df005e43fcd6c081a01d781581d5955a4ef235c7b51a24a622d469

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9db729c644c84398c54c6f83e301e10cf3238b1d813ff41c68f9df4119458d1c
MD5 56b928958ed8cb5c08d6391e2f35928f
BLAKE2b-256 6899ece976c2e628d35fec55ecd887205ff33a773797dfb44b30388bcfedc187

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b9ea583632e27d8686c547b745cc9ea7e27bce3b6a70d865cf0295de3c56c647
MD5 51490e7f2556b4123ebe4d9c6cb27a6e
BLAKE2b-256 e153f48a5deb1ba0b5e122937f83f7cab24e75c2a38ae1dbdbb00093a778e089

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fc3d11f5856918a7227ca9a48676bf336270d1c3589868a3ab38a451c33b6aad
MD5 9f103ea494527fdad45e9455a46e8a61
BLAKE2b-256 9bd75d5ca0bc76e55caed6608c7f1a409560450c1e81f11017fb8f5a7e771c4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1903336402a4fdc96d718bb618acf1728d04a462d759de145d02a9b2b7f0a62f
MD5 66532cbe8eed1efd229c7b8425b13895
BLAKE2b-256 36b870eed37db9ca73d25ba48dadcec3b10c933f77471fa4617651cf7394af9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e57f08f90a9ec912ef5b91180e47626e2ef7359e13b22c63b33287e13157a952
MD5 1f923e1203f08b59a23958588dfc242a
BLAKE2b-256 04f93202b2135aa02ce8211e211ed72772a77ecc94bed211d082e1733cbbfcdf

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 20549a48428168e166fc9b4983ca34bb11b5f415af70c0705e8e43635361f47f
MD5 81da7535af899a7d0cd90f1b09d1019b
BLAKE2b-256 7b31ef382205b1a7ab08a0f1fffa5b93eece2cdc93e071ba85cf611de9d0e237

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on world-in-progress/c-two

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

File details

Details for the file c_two-0.4.6-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.6-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 3a3f66753ce2f344a8e86b195cf1734e0bd11fe274f082282afba2963f6b7ed1
MD5 2ac8a284938074df7772483fe05396db
BLAKE2b-256 db20207cf0ea0b74ec42232d76f4b2016599f66c0a92cc09f7c4e69452aaec2b

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.6-cp310-cp310-macosx_10_12_x86_64.whl:

Publisher: release.yml on world-in-progress/c-two

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