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.7.tar.gz (200.6 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.7-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.7-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.7-cp314-cp314t-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14tmacOS 11.0+ ARM64

c_two-0.4.7-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.7-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.7-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.7-cp314-cp314-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

c_two-0.4.7-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.7-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.7-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.7-cp313-cp313-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

c_two-0.4.7-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.7-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.7-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.7-cp312-cp312-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

c_two-0.4.7-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.7-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.7-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.7-cp311-cp311-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

c_two-0.4.7-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.7-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.7-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.7-cp310-cp310-macosx_11_0_arm64.whl (2.6 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

c_two-0.4.7-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.7.tar.gz.

File metadata

  • Download URL: c_two-0.4.7.tar.gz
  • Upload date:
  • Size: 200.6 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.7.tar.gz
Algorithm Hash digest
SHA256 a273022a5d68fdd403bf7d698fc1b087ed59504b4e601143ff4dad53d8528f62
MD5 dc2592aa82ac75ccbd72eb1ee703d6e6
BLAKE2b-256 bb63b4c068a31d534f29f5663e64a86867d23b22486f39c73d02a04f617ad135

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 099af857b62d6d840a2c21468f89ae3c21927c278f49547178766a636fd35178
MD5 847cf1dde10ca54945b9911f6829e312
BLAKE2b-256 8d0cfc45c4fed730dc6ebf2b6b9258bcd45ca7695c1ddda8b3029a02a6c660ab

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f82a4665e19e3a03410f2917e0b6ca04d26605c32d267e4b6e717dac314d8a01
MD5 72f7d2209cc52df25f3187580a0811d6
BLAKE2b-256 ab65379608630d50c23a70b2a87338335fed556e2cf1bda86873d934198864e8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314t-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7d8d7983a3701a77e36a5ef864b1ea61b88b0dc9aae8e8b9460ef17f30003734
MD5 af702a56519ab5978da2278d2532ce75
BLAKE2b-256 81d8fba82c4024a8f1fa80e3cf1ed961c112722a7a7fe0c4effa921a0c7bfda2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314t-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bd538a8861ec69ca6b7b79e85a6a6a5a5d6b8494646aea753d4a70799913591a
MD5 afc994812ce6ed49f67774d88f1b7181
BLAKE2b-256 e4a36fed84ae53c107bee6afb1d4ab7e4b29f4dc2b4b27eaa5a95249dcce59e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8ce65e7b3be495e70fa25c50ef669ea9eadfc0270d6669adcc70653f99a4317e
MD5 2092ef22e9454c504c2f93503fc143f1
BLAKE2b-256 973ecccb8f7abdec933d86d31a3dfa13a24512dff61810cbb6c2e7cac1608d4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6403e32853f0ce5a69c1fe9c9b62bef6a9b2846ecf86ecff6d5a6449ea8a6c4a
MD5 1674c296c03bb719b3df71a524d3a04e
BLAKE2b-256 aeaaaec052d35b2f75a22400aba150d357d8af2eee300e91c111bb72ddffd99e

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 363f12a0deceb9fea38a6de62b4a40f5dccb3825c6687f5e3e8a4f8d5b6c3f68
MD5 4743c6bae95d3c0fa46032059c2caf28
BLAKE2b-256 134375bab7d9d0866bdea7251065ca9767d12251d62ef898abb07a757a976fdf

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 df5d1453ab90d1e5fde88d628f92de620d4a75c991b59c047aa7beef63126be2
MD5 17ddf121fe6b19f63160c2e5b301b073
BLAKE2b-256 ffc849bce35f133d2673291930d321b86358865c2b3507c9ffa07a54c891ae7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d9ade62931224ed952437b8f777bc64352f09ff4d0391eea19064975447735d8
MD5 b2d5aa63cefce2b8bede9f667a6b5875
BLAKE2b-256 70eebf9fc54c950e985cebac566e3ec8f98e0ab746e1a7efd4ee230c091910d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 7df6ff26d8ef649e4acace026aae31c2557990f8f3b7a52bf17b8030ffa58ec3
MD5 19033afcd2e1c24f9b92013319a5d2b0
BLAKE2b-256 8c5aa461c0d033d199f76988a490fe55532b2eea0c605bee517777abdcafb230

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d25572a69c32e7eca2080fc96f3b0256bce02ec8d26d92ef689ac36bfb875fbb
MD5 33b921ca948f1a4b1dc189d280f0bb16
BLAKE2b-256 4c53c4104a554144dabc833c881e949559949f3ddf9d90a00cd48e5f2b017e47

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6594fd0ebf86f1b05ac0e153c2f7719992b28bdfb895fca282dbe978894725d4
MD5 f95734d988d3c2f48311dd7b2db18aea
BLAKE2b-256 6c9412a35f986c9f6efc4dc9c982cd603ec8e27db0a5b513a2490e106a8782ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e5672daf8440ad9fb742053694b6bc8b6200489341d9974dc7c538613a60fa58
MD5 f7ae5633077265ac5d1cf58359414505
BLAKE2b-256 e91292ad5e8e1c8e67b82d8a7fb96f73decccb3bd4377a4725e70419a4622604

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ac9360d3e78fc5a3699ee81477e829ff90ee104d1a2c135dddb970f4c0cc226b
MD5 d0a9c5aef58ce827c909ea8a44d63dc3
BLAKE2b-256 8adacdba870d2611d0d995c8db6a06e482fb864b5920e4aa3973b38f5fc8af62

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a426abd6b80bd56582829e35a9e12a442949188f94305cecb28cbc258343dec1
MD5 0e637b981046686b30cd85afb05e7b07
BLAKE2b-256 7885d903191d99e7e035efab3d4e457acdd528eecc8a7fd954a09c330f37903e

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 95f35a3e35798733482680e00c5f636f58be00c0a55436eaa0ddb8a59377e573
MD5 376e7f074e4875fa6489865ac0b179b1
BLAKE2b-256 67eb0dd94662d3e2577e0505048fdb197dae1fe3aa9e9a96c6b703ee75470fa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6c0230fd8c306f757d61b0718cbf7790e325289ed0ac60450720e7eb6a3409d9
MD5 619c7a4b011c40a3cba04919bd1c6f5f
BLAKE2b-256 2635fdbb941fae203f5bba4fe32d08eb25e0ef35d1aa895f4339ef001bfaa1ae

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9a7d874f140d34d0c2cb145ab4aeeffe250e814cb0f0ceb056d8851f8ddefd1e
MD5 0290d0a0abf01b758abdbfd2823b2f44
BLAKE2b-256 fae6afd4ab9420ea865aba6638370314fa6661049cc3df3d75f40c6de33725a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e83d26e8e56e20c93bdeb27cb2fe918d0c93349af2db91732517c7b136dc5202
MD5 b360542d448afa59c7e052a9f7af5ba8
BLAKE2b-256 7216c3749337cbf54d91aa4c18ba789144a01a6c6dcd13ff10c366349096ff99

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1179d11cd964b83d17f7c127e11f3aafc727dcbd1fe843926096b48f9f0604de
MD5 f99f21d04a2050b830f757c70cfcb609
BLAKE2b-256 955bf477b5d04dbb820ff6ec46e836f42abc630fce8865eb8a91fb9cc6a5307e

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 c52bd1afa4108af42d640d323e24108ea1edddfcd1ccc555e10b7eeb60998675
MD5 c95190c711841e011f6781bef999918b
BLAKE2b-256 5d36044b1694e1ae8f5bac2120a06cbc3b14c35901dacca7c350e7f7c204812b

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 077653653a1f90abe3540f4861046d8beae026ae6a9344d9b0b1c3f7e79c5f02
MD5 216b0d7f86d8a06ad35a877b33f02bc8
BLAKE2b-256 4cea2215128e1865cac6373905ae7b585af7ac7b09bc65722e803d76236891cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bf3dc92e7a1212f948deaf5da279fa28fa6adf359cfe5629e12fa28005603082
MD5 a8091567e016ecde0770298b33da1be8
BLAKE2b-256 3d8c452885c9dd0bc17c19a976fefd26d07777ecc18a25f83341b0caffa68ab6

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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.7-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for c_two-0.4.7-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fe042b35f11cdbbebb48ad4d8e13bcbcbf389b0a944d4fa6d2ea1dd21bdd611e
MD5 6d4309a7346bb85151268be6bf4f05ed
BLAKE2b-256 55d916c885a3254941730f925f2c4239e206670c191b56d5e31aba0feb233497

See more details on using hashes here.

Provenance

The following attestation bundles were made for c_two-0.4.7-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