Skip to main content

proper-wse: a fork of WSE (WebSocket Engine)

This is a fork of wse-server, published on PyPI as proper-wse and maintained for the Proper web framework. It still imports as wse_server, so don't install it next to wse-server. Upstream also has Python and TypeScript clients; this fork keeps only the server.

Changes from wse-server 2.4.3:

  • Broadcast frames over 1 KiB are shared by every connection instead of copied into each one (silvermpx/wse#74).
  • max_pending_handshakes; past it, a 503 counted in wse_handshakes_dropped_total (silvermpx/wse#73). Logs go to stderr.
  • allowed_origins: handshakes from other sites' pages get a 403.
  • topic_backlog(topic): how far behind delivery is on a topic.
  • connection_backlogs(min_pending) and abort_connection(conn_id): find the clients that stopped reading (bytes pending, bytes written so far) and end them at once, which a Close frame queued behind their backlog can't do.
  • The pending-bytes count of a connection drops with each write to its socket, not when a whole backlog is written.
  • Wheels for free-threaded Python (cp314t, cp315t) besides abi3, and for musl (Alpine) Linux.
  • handshake_details: the connect event carries a dict with the cookies, the Authorization header, the path with its query string, the peer address and X-Forwarded-For, instead of the cookies alone.
  • set_connection_user(conn_id, user_id) and untrack_presence(conn_id, topics), for presence on connections the application authenticates; the presence frames name their topic.
  • subscribe_node(topics): the node listens to cluster topics itself, as cluster_msg events, for the application's coordination between nodes.

PyPI License: MIT

High-performance WebSocket server built in Rust with native clustering, E2E encryption, message recovery, presence tracking, and real-time fan-out. Exposed to Python via PyO3 with zero GIL overhead on the data path. Ships with Rust-accelerated utilities for application code: priority queues, rate limiters, event sequencing, compression, cryptography, and JWT.

Features

Server

Feature Details
Rust core tokio async runtime, tungstenite WebSocket transport, dedicated thread pool, zero GIL on the data path
JWT authentication HS256, RS256, ES256 algorithms via jsonwebtoken crate. Validated during handshake (0.01ms), cookie + Authorization header extraction, key rotation, kid validation
Protocol negotiation client_hello/server_hello handshake with feature discovery, capability advertisement, version agreement
Topic subscriptions Per-connection topic subscriptions with automatic cleanup on disconnect
Pre-framed broadcast WebSocket frame built once, shared via Arc across all connections, single allocation per broadcast
Vectored writes write_vectored (writev syscall) batches multiple frames per connection in a single kernel call
Write coalescing Write task drains up to 256 pending frames per iteration via recv_many
DashMap state Lock-free sharded concurrent hash maps for topics, rates, formats, activity tracking
mimalloc allocator Global allocator optimized for multi-threaded workloads with frequent small allocations
Deduplication 50,000-entry AHashSet with FIFO eviction per send_event() call
Rate limiting Per-connection token bucket: 100K capacity, 10K/s refill, client warning at 20% remaining
Zombie detection Server pings every 25s, force-closes connections with no activity for 60s
Drain mode Lock-free crossbeam bounded channel, Python acquires GIL once per batch (not per event)
Compression zlib for client-facing messages above threshold (default 1024 bytes)
MessagePack Opt-in binary transport via ?format=msgpack, roughly 2x faster serialization, 30% smaller
Message signing Selective HMAC-SHA256 signing for critical operations, nonce-based replay prevention
Queue groups Round-robin dispatch within named groups for load-balanced worker pools
Topic ACL Per-connection allow/deny glob patterns for topic access control
Graceful drain drain() sends Close frame to all clients, rejects new connections, notifies cluster peers

End-to-End Encryption

Feature Details
Key exchange ECDH P-256 (per-connection keypair, automatic during handshake)
Encryption AES-GCM-256 with unique 12-byte IV per message
Key derivation HKDF-SHA256 (no salt, info: wse-encryption/aes-gcm-key)
Wire format E: prefix + 12-byte IV + AES-GCM ciphertext + 16-byte auth tag
Key rotation Configurable rotation interval (default 1 hour), automatic renegotiation
Replay prevention Nonce cache (10K entries, 5-minute TTL) on the client side

Cluster Protocol

Feature Details
Topology Full TCP mesh, direct peer-to-peer connections
Wire format Custom binary frames: 8-byte header + topic + payload, 12 message types
Interest routing SUB/UNSUB/RESYNC frames, messages forwarded only to peers with matching subscribers
Gossip discovery PeerAnnounce/PeerList frames, new nodes need one seed address to join
mTLS rustls + tokio-rustls, P-256 certificates, WebPkiClientVerifier for both sides
Compression zstd level 1 for payloads above 256 bytes, capability-negotiated, output capped at 1 MB
Heartbeat 5s ping interval, 15s timeout, dead peer detection
Circuit breaker 10 failures to open, 60s reset, 3 half-open probe calls
Dead letter queue 1000-entry ring buffer for failed cluster sends
Presence sync PresenceUpdate/PresenceFull frames, CRDT last-write-wins conflict resolution
Topology API cluster_info() returns connected peer list with address, instance_id, status

Presence Tracking

Feature Details
Per-topic tracking Which users are active in each topic, with custom metadata (status, avatar, etc.)
User-level grouping Multiple connections from same JWT sub share one presence entry
Join/leave lifecycle presence_join on first connection, presence_leave on last disconnect
O(1) stats presence_stats() returns member/connection counts without iteration
Data updates update_presence() broadcasts to all topics where the user is present
Cluster sync Synchronized across all nodes, CRDT last-write-wins resolution
TTL sweep Background task every 30s removes entries from dead connections

Message Recovery

Feature Details
Ring buffers Per-topic, power-of-2 capacity, bitmask indexing (single AND instruction)
Epoch+offset tracking Precise recovery positioning, epoch changes on buffer recreation
Memory management Global budget (default 256 MB), TTL eviction, LRU eviction when over budget
Zero-copy storage Recovery entries share Bytes (Arc) with the broadcast path
Recovery on reconnect subscribe_with_recovery() replays missed messages automatically
Per-message stamp When recovery is enabled, every topic broadcast carries tp/e/o (topic, epoch, offset) so clients dedup idempotently and detect gaps from the messages themselves

Transport Security

Feature Details
Origin validation allowed_origins: a browser handshake from another origin gets 403 (the handshake's own host is always allowed), against cross-site WebSocket hijacking
Cookie auth access_token HTTP-only cookie with Secure + SameSite=Lax (OWASP recommended for browsers)
Frame protection 1 MB max frame size, serde_json parsing (no eval), escaped user IDs in server_ready; inbound msgpack rejected beyond 64 nesting levels
Cluster frame protection zstd decompression output capped at 1 MB (MAX_FRAME_SIZE), protocol version validation
Slowloris protection At most max_pending_handshakes (512) connections in the handshake at once; past it, a 503 with Retry-After, counted in wse_handshakes_dropped_total
Stalled clients connection_backlogs() finds the connections whose client stopped reading; abort_connection() ends them without the close handshake
Bounded callback dispatch Callback mode caps in-flight on_message callbacks at 256 per connection; excess inbound work is shed and counted as rate-limited
Fail-closed recovery ACL Recovery replay applies the connection's topic ACL — unauthorized topics are never replayed or position-probed

Quick Start

pip install proper-wse
from wse_server import RustWSEServer, rust_jwt_encode
import time, threading

server = RustWSEServer(
    "0.0.0.0", 5007,
    max_connections=10_000,
    jwt_secret=b"replace-with-a-strong-secret-key!",
    jwt_issuer="my-app",
    jwt_audience="my-api",
)
server.enable_drain_mode()
server.start()

def handle_events(srv):
    while True:
        for ev in srv.drain_inbound(256, 50):
            if ev[0] == "auth_connect":
                srv.subscribe_connection(ev[1], ["updates"])
            elif ev[0] == "msg":
                print(f"Message from {ev[1]}: {ev[2]}")
            elif ev[0] == "disconnect":
                print(f"Disconnected: {ev[1]}")

threading.Thread(target=handle_events, args=(server,), daemon=True).start()

while server.is_running():
    time.sleep(1)

Generate a test token:

token = rust_jwt_encode(
    {"sub": "user-1", "iss": "my-app", "aud": "my-api",
     "exp": int(time.time()) + 3600, "iat": int(time.time())},
    b"replace-with-a-strong-secret-key!",
)

Server Configuration

RustWSEServer constructor parameters:

Parameter Default Description
host required Bind address
port required Bind port
max_connections 1000 Maximum concurrent WebSocket connections
jwt_secret None JWT key for validation. HS256: shared secret (bytes, min 32). RS256/ES256: PEM public key. None disables auth
jwt_issuer None Expected iss claim. Skipped if None
jwt_audience None Expected aud claim. Skipped if None
jwt_cookie_name "access_token" Cookie name for JWT token extraction
jwt_previous_secret None Previous key for zero-downtime rotation. HS256: previous secret. RS256/ES256: previous public key PEM
jwt_key_id None Expected kid header claim. Rejects tokens with mismatched key ID
jwt_algorithm None JWT algorithm: "HS256" (default), "RS256", or "ES256"
jwt_private_key None PEM private key for RS256/ES256 token encoding. Not needed for HS256
max_inbound_queue_size 131072 Drain mode bounded queue capacity
recovery_enabled False Enable per-topic message recovery buffers
recovery_buffer_size 128 Ring buffer slots per topic (rounded to power-of-2)
recovery_ttl 300 Buffer TTL in seconds before eviction
recovery_max_messages 500 Max messages returned per recovery response
recovery_memory_budget 268435456 Global memory limit for all recovery buffers (bytes, default 256 MB)
presence_enabled False Enable per-topic presence tracking
presence_max_data_size 4096 Max bytes for a user's presence metadata
presence_max_members 0 Max tracked members per topic (0 = unlimited)
max_outbound_queue_bytes 16777216 Per-connection outbound buffer limit (bytes, default 16 MB). Messages dropped when exceeded
max_subscriptions_per_connection 0 Max topics per connection (0 = unlimited). Prevents topic explosion DoS
max_pending_handshakes 512 Max connections between accept and registration at once. Past it, new connections get 503 with Retry-After: 1. Raise it if thousands of clients may reconnect at once (e.g. after a restart)
allowed_origins None Browser origins allowed to connect (e.g. ["https://example.com"]), besides the one whose host is the handshake's Host, which is always allowed. A handshake from another origin gets 403; one without an Origin header (not a browser) is allowed. None allows any
handshake_details False The connect event's payload is a dict (cookies, authorization, path with the query string, remote_addr, forwarded_for) instead of the cookies string
rate_limit_capacity 100000.0 Token bucket capacity per connection
rate_limit_refill 10000.0 Token bucket refill rate per second
max_message_size 1048576 Maximum WebSocket frame size in bytes (default 1 MB)
ping_interval 25 Server-initiated ping interval in seconds
idle_timeout 60 Force-close connections idle for this many seconds

API Reference

Lifecycle

server.start()                          # Start the server
server.stop()                           # Graceful shutdown
server.is_running()                     # Check server status (bool)

Event Handling

Drain mode (recommended) - events are queued in a lock-free crossbeam channel. Python polls in batches, acquiring the GIL once per batch.

server.enable_drain_mode()              # Switch to batch-polling mode (call before start)
events = server.drain_inbound(256, 50)  # Poll up to 256 events, wait up to 50ms

Each event is a tuple: (event_type, conn_id, payload)

Event Type Trigger Payload
"auth_connect" JWT-validated connection user_id (string)
"connect" Connection without JWT cookies (string); with handshake_details, a dict: cookies, authorization, path, remote_addr, forwarded_for
"msg" Client sent WSE-prefixed JSON parsed dict
"raw" Client sent plain text raw string
"bin" Client sent binary frame bytes
"disconnect" Connection closed None
"presence_join" User's first connection joined a topic dict with user_id, topic, data
"presence_leave" User's last connection left a topic dict with user_id, topic, data
"cluster_msg" Another node published to a topic of subscribe_node() dict with topic, data (the text as published)

Callback mode - alternative to drain mode. Callbacks are invoked via spawn_blocking per event.

server.set_callbacks(on_connect, on_message, on_disconnect)

Sending Messages

server.send(conn_id, text)                      # Send text to one connection
server.send_bytes(conn_id, data)                 # Send binary to one connection
server.send_event(conn_id, event_dict)           # Send structured event (auto-serialized, deduped, rate-checked)

server.broadcast_all(text)                       # Send to every connected client (text)
server.broadcast_all_bytes(data)                 # Send to every connected client (binary)
server.broadcast_local(topic, text)              # Fan-out to topic subscribers on this instance
server.broadcast(topic, text)                    # Fan-out to topic subscribers across all cluster nodes
Method Scope Notes
send Single connection Raw text frame
send_bytes Single connection Raw binary frame
send_event Single connection JSON-serialized, compressed if above threshold, deduplication via 50K-entry FIFO window
broadcast_all All connections Pre-framed, single frame build shared via Arc
broadcast_local Topic (local) Pre-framed, DashMap subscriber lookup, stored in recovery buffer if enabled
broadcast Topic (all nodes) Local fan-out + forwarded to cluster peers with matching interest

Topic Subscriptions

server.subscribe_connection(conn_id, ["prices", "news"])              # Subscribe to topics
server.subscribe_connection(conn_id, ["chat"], {"status": "online"})  # Subscribe with presence data
server.subscribe_connection(conn_id, ["tasks"], queue_group="workers") # Subscribe with queue group (round-robin)
server.unsubscribe_connection(conn_id, ["news"])                      # Unsubscribe from specific topics
server.unsubscribe_connection(conn_id, None)                          # Unsubscribe from all topics
server.get_topic_subscriber_count("prices")                           # Subscriber count for a topic

Subscriptions are cleaned up automatically on disconnect. In cluster mode, interest changes are propagated to peers via SUB/UNSUB frames.

Queue groups: connections in the same queue_group receive messages round-robin instead of fanout. Normal subscribers (no queue group) still receive all messages. Useful for distributing work across a pool of consumers.

Topic ACL

Per-connection topic access control with glob pattern matching.

# Allow only "user:*" topics, deny everything else
server.set_topic_acl(conn_id, allow=["user:*"])

# Allow "data:*" but deny "data:internal:*"
server.set_topic_acl(conn_id, allow=["data:*"], deny=["data:internal:*"])

# Must be called before subscribe_connection
server.subscribe_connection(conn_id, ["data:prices"])   # allowed
server.subscribe_connection(conn_id, ["data:internal:audit"])  # denied

Deny patterns take precedence over allow patterns. Supports * (any characters) and ? (single character) wildcards. Applied at subscribe time.

Presence Tracking

Requires presence_enabled=True in the constructor.

# Query members in a topic
members = server.presence("chat-room")
# {"alice": {"data": {"status": "online"}, "connections": 2},
#  "bob":   {"data": {"status": "away"},   "connections": 1}}

# Lightweight counts (O(1), no iteration)
stats = server.presence_stats("chat-room")
# {"num_users": 2, "num_connections": 3}

# Update a user's presence data across all their subscribed topics
server.update_presence(conn_id, {"status": "away"})

# Without JWT: give the connection its identity first, then subscribe with presence data
server.set_connection_user(conn_id, "alice")
server.subscribe_connection(conn_id, ["chat-room"], {"status": "online"})

# Leave the presence of some topics, keeping the subscriptions
server.untrack_presence(conn_id, ["chat-room"])

Presence is tracked at the user level (JWT sub claim, or set_connection_user). Multiple connections from the same user share a single presence entry. presence_join fires on first connection, presence_leave on last disconnect. In cluster mode, presence state is synchronized across all nodes using CRDT last-write-wins resolution.

Message Recovery

Requires recovery_enabled=True in the constructor.

result = server.subscribe_with_recovery(
    conn_id, ["prices"],
    recover=True,
    epoch=client_epoch,       # From previous session
    offset=client_offset,     # From previous session
)
# {"topics": {"prices": {"epoch": "0000007b", "offset": 456, "recovered": True, "count": 12}}}

The server maintains per-topic ring buffers (power-of-2 capacity, bitmask indexing). When recovery is enabled, every topic broadcast is stamped with tp/e/o (topic, epoch, offset) fields, so clients track their per-topic position from the messages themselves, drop duplicates idempotently by (epoch, offset), and automatically request recovery when they detect an offset gap. On reconnect, the server replays missed messages from the ring buffer. If the gap is too large or the epoch has changed, the client receives a NotRecovered status and should re-subscribe from scratch.

Memory is managed with a global budget (default 256 MB), TTL eviction for idle buffers, and LRU eviction when over budget.

Cluster

# Join a cluster mesh with mTLS
server.connect_cluster(
    peers=["10.0.0.2:9999", "10.0.0.3:9999"],
    tls_ca="/etc/wse/ca.pem",
    tls_cert="/etc/wse/node.pem",
    tls_key="/etc/wse/node.key",
    cluster_port=9999,
)

# With gossip discovery (only seed addresses needed)
server.connect_cluster(
    peers=[],
    seeds=["10.0.0.2:9999"],
    cluster_addr="10.0.0.1:9999",
    cluster_port=9999,
)

server.subscribe_node(["control"])   # Listen to a topic as the node: other nodes' messages come as "cluster_msg" events
server.unsubscribe_node(["control"])
server.cluster_connected()       # True if connected to at least one peer
server.cluster_peers_count()     # Number of active peer connections
server.cluster_info()            # List of connected peers (address, instance_id, connected)

Nodes form a full TCP mesh automatically. The cluster protocol uses a custom binary frame format with an 8-byte header, 12 message types, and capability negotiation during handshake. Features:

  • Interest-based routing - SUB/UNSUB/RESYNC frames. Messages are only forwarded to peers with matching subscribers.
  • Gossip discovery - PeerAnnounce/PeerList frames. New nodes need one seed address to join.
  • mTLS - mutual TLS via rustls with P-256 certificates and WebPkiClientVerifier.
  • zstd compression - payloads above 256 bytes compressed at level 1, capability-negotiated.
  • Circuit breaker - 10 failures to open, 60s reset, 3 half-open probe calls.
  • Heartbeat - 5s interval, 15s timeout, dead peer detection.
  • Dead letter queue - 1000-entry ring buffer for failed cluster sends.
  • Presence sync - PresenceUpdate/PresenceFull frames with CRDT conflict resolution.

Health Monitoring

health = server.health_snapshot()
# {
#     "connections": 150,
#     "inbound_queue_depth": 0,
#     "inbound_dropped": 0,
#     "uptime_secs": 3600.5,
#     "recovery_enabled": True,
#     "recovery_topic_count": 5,
#     "recovery_total_bytes": 1048576,
#     "cluster_connected": True,
#     "cluster_peer_count": 2,
#     "cluster_messages_sent": 50000,
#     "cluster_messages_delivered": 49950,
#     "cluster_messages_dropped": 0,
#     "cluster_bytes_sent": 1048576,
#     "cluster_bytes_received": 1024000,
#     "cluster_reconnect_count": 0,
#     "cluster_unknown_message_types": 0,
#     "cluster_dlq_size": 0,
#     "presence_enabled": True,
#     "presence_topics": 3,
#     "presence_total_users": 25,
# }

Connection Management

server.get_connection_count()        # Lock-free AtomicUsize read
server.get_connections()             # List all connection IDs (snapshot)
server.disconnect(conn_id)           # Force-disconnect a connection
server.drain(close_code=4300, close_reason="shutting down", timeout=10)  # Graceful drain
server.inbound_queue_depth()         # Events waiting to be drained
server.inbound_dropped_count()       # Events dropped due to full queue
server.get_cluster_dlq_entries()     # Retrieve failed cluster messages from dead letter queue

drain() sends a WebSocket Close frame to all connected clients and rejects new connections. The drain wait runs as a separate task, so the command processor stays responsive. Use for zero-downtime deployments and rolling restarts.


Security

JWT Authentication

Rust-native HS256 validation during the WebSocket handshake. Zero GIL acquisition, 0.01ms per decode.

Token delivery:

  • Browser clients: access_token HTTP-only cookie (set by your login endpoint, attached automatically by the browser)
  • Backend clients: Authorization: Bearer <token> header and/or access_token cookie
  • API clients: Authorization: Bearer <token> header

Required claims: sub (user ID), exp (expiration). Recommended: iat (issued at). Optional: iss, aud (validated if configured).

End-to-End Encryption

Per-connection session keys via ECDH P-256 key exchange, AES-GCM-256 encryption, HKDF-SHA256 key derivation.

Wire format: E: prefix + 12-byte IV + AES-GCM ciphertext + 16-byte auth tag.

Enable on the client side - the server handles key exchange automatically during the handshake.

Rate Limiting

Per-connection token bucket: 100,000 token capacity, 10,000 tokens/second refill. Clients receive a rate_limit_warning at 20% remaining capacity, and RATE_LIMITED error when exceeded.

Deduplication

send_event() maintains a 50,000-entry AHashSet with FIFO eviction. Duplicate message IDs are dropped before serialization.

Zombie Detection

Server pings every connected client every 25 seconds. Connections with no activity for 60 seconds are force-closed.

Full security documentation: docs/SECURITY.md


Wire Protocol

WSE uses a custom wire protocol with categorized JSON messages:

Text frames: JSON with c field for category: "WSE" (system), "S" (snapshot), "U" (update)

Binary frames: C: (zlib compressed), M: (MessagePack), E: (AES-GCM encrypted), raw zlib (0x78 magic byte)

MessagePack transport: opt-in per connection via ?format=msgpack query parameter. Roughly 2x faster serialization and 30% smaller payloads.

Protocol negotiation: client_hello/server_hello handshake with feature discovery, capability advertisement, and version agreement.

Full protocol specification: docs/PROTOCOL.md


Compression

Two compression layers:

  • Client-facing: zlib for messages above the configurable threshold (default 1024 bytes). Applied automatically by send_event().
  • Inter-peer (cluster): zstd level 1 for payloads above 256 bytes. Capability-negotiated during handshake. Decompression output capped at 1 MB (MAX_FRAME_SIZE).

Performance

Benchmarked on AMD EPYC 7502P (32 cores / 64 threads, 128 GB RAM), Ubuntu 24.04.

Mode Peak Throughput Connections Message Loss
Standalone (fan-out) 4.7M deliveries/s 100K 0%
Standalone (inbound JSON) 14.7M msg/s 500K 0%
Standalone (inbound msgpack) 30M msg/s 500K 0%
Cluster (2 nodes, 50/50) 6.6M deliveries/s 500 per node 0%

Sub-millisecond latency. Median 0.38ms with JWT authentication. Connection handshake: 0.53ms median (Rust JWT path).

Detailed results: Benchmarks | Fan-out | Rust load generator | Python load scripts


Examples

Working examples in the examples/ directory:

Example Description
standalone_basic.py Basic server with JWT auth and echo
standalone_broadcast.py Topic-based pub/sub with broadcasting
standalone_presence.py Per-topic presence tracking with join/leave events
standalone_recovery.py Message recovery on reconnect with epoch+offset

Documentation


License

MIT

Metadata

Release files for proper-wse 2.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for proper-wse 2.7.0
File Size Uploaded
proper_wse-2.7.0.tar.gz 174.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for proper-wse 2.7.0
File
proper_wse-2.7.0-cp315-cp315t-win_amd64.whl CPython 3.15 CPython 3.15 free-threading Windows x86-64 Details
proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl CPython 3.15 CPython 3.15 free-threading Linux musl 1.2+ x86-64 Details
proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_aarch64.whl CPython 3.15 CPython 3.15 free-threading Linux musl 1.2+ ARM64 Details
proper_wse-2.7.0-cp315-cp315t-manylinux_2_28_aarch64.whl CPython 3.15 CPython 3.15 free-threading Linux glibc 2.28+ ARM64 Details
proper_wse-2.7.0-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.15 CPython 3.15 free-threading Linux glibc 2.17+ x86-64 Details
proper_wse-2.7.0-cp315-cp315t-macosx_11_0_arm64.whl CPython 3.15 CPython 3.15 free-threading macOS 11.0+ ARM64 Details
proper_wse-2.7.0-cp315-cp315t-macosx_10_12_x86_64.whl CPython 3.15 CPython 3.15 free-threading macOS 10.12+ x86-64 Details
proper_wse-2.7.0-cp314-cp314t-win_amd64.whl CPython 3.14 CPython 3.14 free-threading Windows x86-64 Details
proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64 Details
proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64 Details
proper_wse-2.7.0-cp314-cp314t-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64 Details
proper_wse-2.7.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64 Details
proper_wse-2.7.0-cp314-cp314t-macosx_11_0_arm64.whl CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64 Details
proper_wse-2.7.0-cp314-cp314t-macosx_10_12_x86_64.whl CPython 3.14 CPython 3.14 free-threading macOS 10.12+ x86-64 Details
proper_wse-2.7.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
proper_wse-2.7.0-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details
proper_wse-2.7.0-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details
proper_wse-2.7.0-cp312-abi3-manylinux_2_28_aarch64.whl CPython 3.12 abi3 Linux glibc 2.28+ ARM64 Details
proper_wse-2.7.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
proper_wse-2.7.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
proper_wse-2.7.0-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 89.0 MB

Release files / proper_wse-2.7.0.tar.gz

Download URL proper_wse-2.7.0.tar.gz
Size 174.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b85db3163af454586aa14b7eda10b44c0e85922c361168ba5d5b4620b3379bc1
BLAKE2b-256 checksum
How to use checksums
eef56e53f3157d96765a09858559cf122e227febe86fe08913f124010639e07d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-win_amd64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-win_amd64.whl
Size 4.1 MB
Tags CPython 3.15 CPython 3.15 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
1b5f9073ac0fde837f256ca54f5219e57f88ace9c1551d5659417959b2c3f553
BLAKE2b-256 checksum
How to use checksums
f13c38df1bdd67326736c0c4219c38d03eceec9664f6f27f9fcf2a27cfa6ba31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_x86_64.whl
Size 4.7 MB
Tags CPython 3.15 CPython 3.15 free-threading Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
c8579d303f910a9e0c52b6967f30ba34e737b24180b4d16d9f2e3c95ff62576d
BLAKE2b-256 checksum
How to use checksums
d9ae91c56acdf1b2e0f5f00f52bba2908550ee74da74110f17182d4b1c3ccde8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_aarch64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-musllinux_1_2_aarch64.whl
Size 4.3 MB
Tags CPython 3.15 CPython 3.15 free-threading Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
d4fc627093ca68eb6dddf077523ae026e605a4a99fca8eaf97d89fb05a286f3e
BLAKE2b-256 checksum
How to use checksums
29155e70e56583a9622a254b4df26320d4dc022b909a780b9aebc441ca7464b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-manylinux_2_28_aarch64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-manylinux_2_28_aarch64.whl
Size 4.1 MB
Tags CPython 3.15 CPython 3.15 free-threading Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
e96862a33a05b69cd34f133f9aae7f3e66875f6bc764b6270b4ec04757ae0344
BLAKE2b-256 checksum
How to use checksums
bbe767e9e7e558848b6dbf9ad831af4faafa6551496e3ddeaa63a03099e143da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.4 MB
Tags CPython 3.15 CPython 3.15 free-threading Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
cadc8c557f5ace203c25b44072383f62bf45d1d0bd49661016ae3bd6d14637ae
BLAKE2b-256 checksum
How to use checksums
330e51b4e006d0379cfe44c1a135241ea88afe7d04ff1c58aa4fe6413872a9de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-macosx_11_0_arm64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-macosx_11_0_arm64.whl
Size 3.9 MB
Tags CPython 3.15 CPython 3.15 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f2a3221d87ffafd83fdc5d5281bc3aee8042adbbef636f9c3a5839eddf52e13f
BLAKE2b-256 checksum
How to use checksums
e6c26a57b9160785ee3cdae8cffe51aefa302797c3672efed66596db8499305d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp315-cp315t-macosx_10_12_x86_64.whl

Download URL proper_wse-2.7.0-cp315-cp315t-macosx_10_12_x86_64.whl
Size 4.2 MB
Tags CPython 3.15 CPython 3.15 free-threading macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
c56546b9505ad2216a9f8c198d69dd6e232548dc3c5063c2fbc8725e66fa3dda
BLAKE2b-256 checksum
How to use checksums
4fd4f5f3bd56ccd57e44532eabd8a8d3c91105d05fb4ee6b61f2a4535f5bb114
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-win_amd64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-win_amd64.whl
Size 4.1 MB
Tags CPython 3.14 CPython 3.14 free-threading Windows x86-64
SHA-256 checksum
How to use checksums
2aa38a5547ca902a052a37cd94d63ba57582be974139442f736e2a96afc04c81
BLAKE2b-256 checksum
How to use checksums
45e575896b19b6438438d30d09f84de88fab617f047c8a7b020201dea7743649
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl
Size 4.7 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
3847738d747c4c5706544df5c52909a8495bcd0cc19a204f49d702de6f15c06f
BLAKE2b-256 checksum
How to use checksums
1c012ba0cf35c04b28be97f9a4c84d6382ebd0834d8217ff4dedf3a58ce32139
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl
Size 4.3 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
39d77802e66796f4c8a4273dafcde028be5219486e45986e5c793c4152f8ef97
BLAKE2b-256 checksum
How to use checksums
6941356d6040852b27c8a031fb9e310d74154422cd17bb16b0c9faf628308b51
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-manylinux_2_28_aarch64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-manylinux_2_28_aarch64.whl
Size 4.1 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
d843a7803b0a8697bb1b0a1512e8787f4df02f570e944b638728952ffa97e37a
BLAKE2b-256 checksum
How to use checksums
b1309484986457474094875934c35372ac4e34aa870d11ae0d0078e678a7cfce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.4 MB
Tags CPython 3.14 CPython 3.14 free-threading Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
6024beb32c3edac9359d767c75c25e2ab9b3636d51651b4344619d8441ae21d8
BLAKE2b-256 checksum
How to use checksums
36cbec0f1f38418e50e9c3fc889f426ddf111ef3986a0023100aa6ecf1076eb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-macosx_11_0_arm64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-macosx_11_0_arm64.whl
Size 3.9 MB
Tags CPython 3.14 CPython 3.14 free-threading macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
353bc446d5a14e1684a405bee6c40eff20f3699c8cd5cb83ef723955414b77ca
BLAKE2b-256 checksum
How to use checksums
df78f4b0a931e17b5bfe6883b9a2dc8896331f46a4f97ea5e888d32dd13bce8d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp314-cp314t-macosx_10_12_x86_64.whl

Download URL proper_wse-2.7.0-cp314-cp314t-macosx_10_12_x86_64.whl
Size 4.2 MB
Tags CPython 3.14 CPython 3.14 free-threading macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
418433268225903660a9db638370c7d4a159a3b56cddaee6a42a1d53057ce4b4
BLAKE2b-256 checksum
How to use checksums
935b68a2b9ed39e4b77a612025f598120a4f1d8f5ede7d9de8d74e3bf25b8795
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-win_amd64.whl

Download URL proper_wse-2.7.0-cp312-abi3-win_amd64.whl
Size 4.1 MB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
4379588514062e40e56b1efec60360da283a94bb7150c9986580dd28f7a071c0
BLAKE2b-256 checksum
How to use checksums
2fcf51ef97e34fc8c1b812fd45b895c52c05fd6f330edd0d3b999be7608e80f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL proper_wse-2.7.0-cp312-abi3-musllinux_1_2_x86_64.whl
Size 4.7 MB
Tags CPython 3.12 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
4a27055b7a88e42df330b726976ffe2a4b435e0228f2ab2e02a8634cd7f6aff5
BLAKE2b-256 checksum
How to use checksums
440a85169c282cc9362ea4ee3459ad42074d115799783963ecaab71dd36a9216
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-musllinux_1_2_aarch64.whl

Download URL proper_wse-2.7.0-cp312-abi3-musllinux_1_2_aarch64.whl
Size 4.3 MB
Tags CPython 3.12 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
b4931b96b9c7a8eebdacba0e0cbae1e1df278b22a5377b82107ee1ef5e729f2e
BLAKE2b-256 checksum
How to use checksums
4a25c44bf0e08cc82a9ddbe124161a3ebdc7e2a6636e87eeb155e2bf9eae42c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-manylinux_2_28_aarch64.whl

Download URL proper_wse-2.7.0-cp312-abi3-manylinux_2_28_aarch64.whl
Size 4.1 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
4cfe74d738f7a4ffe9d4b5acab58b4cd9ce85de086d7d78bbddfc16ff27795ab
BLAKE2b-256 checksum
How to use checksums
5f68a0c837d6899a6e1b5db1b9a5f7405ae691bbc3c0bce95e51795bc8a86a92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL proper_wse-2.7.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.4 MB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
0ab8f505d455b5a4683681fc847011db1dfdfcccbc4996cc1f9cdf58230a6a1b
BLAKE2b-256 checksum
How to use checksums
6dc88750465ef63ac04b4f4196c1e24fcedd8ba16bb519732396e2904e69a830
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL proper_wse-2.7.0-cp312-abi3-macosx_11_0_arm64.whl
Size 3.9 MB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2e8d8e1bc37e13eca66c7ad59f6f62e4b1811dabe26a4981cdd10e70da448ecd
BLAKE2b-256 checksum
How to use checksums
68f278ec25b630b836ba3209f9911d6493cbc744f23489e46779182a72c0fbbe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / proper_wse-2.7.0-cp312-abi3-macosx_10_12_x86_64.whl

Download URL proper_wse-2.7.0-cp312-abi3-macosx_10_12_x86_64.whl
Size 4.2 MB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
cef687ac19fd0d27093f77e77bf2fdfa38cc062bf7448b2320a0fe1411bfceb9
BLAKE2b-256 checksum
How to use checksums
fd8228ab3e13f053fa2d354cebccd95ce34d33b2edb4bd4e32e67a50383f21e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.7.0 This release

22 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page