Skip to main content

polynode

Python SDK for the Polynode real-time prediction market data platform.

New in v0.14.0: Web platforms can take a user from wallet authorization through an exact browser-signed user-owned order without exposing backend credentials. The SDK imports the shared versioned browser bundle into memory, produces a credential-free signing request with a complete order preview, supports one-time multi-worker state, validates canonical signatures and wallet identity, checks BUY collateral before prompting, and submits with exact zero builder attribution.

In v0.13.0: Trading added explicit user_owned execution. Existing builder mode remains the default; opted-in wallets use zero builder attribution, one wallet-ownership authorization, and strict wallet-bound gasless credentials. Builder credentials and nonzero builder codes fail closed in this mode. EOA-controlled Safe and deposit wallets are supported; legacy Magic/proxy wallets are intentionally excluded from the first release.

In v0.12.2: Python provides the same core capabilities as the TypeScript and Rust SDKs: complete V3 API access, the V3 perps WebSocket, reconnect-aware settlement delivery, and PN1 orderbook integrity. Unknown additive events remain available as raw payloads, decimal values remain precision-safe, and any local queue eviction is reported.

New in v0.11.0: Current-production parity. Trading now defaults to CLOB V2 on clob.polymarket.com, uses Polynode's public builder attribution unless overridden, omits removed V1 wire fields, and supports V2 GTD expiration. Managed 5-minute, 15-minute, and 4-hour streams select the required 30/60-second Chainlink TWAP lookbacks on a dedicated connection and reconnect/resubscribe at every market rotation. WebSocket models, presets, and filters now cover current redemption, position-conversion, dome/fill, and PM2 combo events. REST position queries now include redeemable/condition filters, multi-wallet batches, and market-holder views; connection and status observability match the current public API.

New in v0.10.8: POLY_1271 V2 order signatures now normalize the ERC-7739 TypedDataSign recovery byte to Ethereum v=27/28 for on-chain ERC-1271 validation.

In v0.10.7: Polymarket V2 deposit-wallet trading fixes. ensure_ready() detects deployed POLY_1271 wallets correctly, V2 type-3 orders use the deposit wallet as both maker and signer, and existing local credentials can be repaired by rerunning ensure_ready().

Install

pip install polynode

For trading support:

pip install 'polynode[trading]'

Quick Start

REST API

from polynode import PolyNode

with PolyNode(api_key="pn_live_...") as pn:
    status = pn.status()
    connections = pn.connections()
    markets = pn.markets(count=10)
    settlements = pn.recent_settlements(count=5)
    wallet_positions = pn.wallet_positions(
        address, redeemable=True, condition_id=condition_id
    )
    batch_positions = pn.multi_wallet_positions([address, second_address], limit=100)
    market_positions = pn.market_positions(
        condition_id, sort_by="CURRENT_VALUE", min_size=0.01
    )
    onchain_positions = pn.wallet_onchain_positions(
        address, since=window_start, tag_slug="crypto"
    )

Sports and Online Context

from polynode import PolyNode

with PolyNode(api_key="pn_live_...") as pn:
    state = pn.sports_game_state(
        "nba-cle-nyk-2026-05-31",
        price_limit_tokens=20,
    )

    context = pn.sports_game_context(
        "nba-cle-nyk-2026-05-31",
        sources=["online"],
        query_set="injuries",
        max_queries=2,
        max_per_query=5,
        include_state=True,
    )

    web = pn.search_online(
        "Cavaliers Knicks injury news",
        max_results=5,
    )

Async REST

import asyncio
from polynode import AsyncPolyNode

async def main():
    async with AsyncPolyNode(api_key="pn_live_...") as pn:
        status = await pn.status()
        markets = await pn.markets(count=10)

asyncio.run(main())

Complete V3 API

V3 includes wallets, combos, rewards, credits, identities, markets, builders, profiles, perps, crypto, sports, backtesting, and other current product families. execute() gives you access to all 120 current V3 operations through one consistent Python interface.

import asyncio
from polynode import AsyncPolyNode

async def read_v3(address: str):
    async with AsyncPolyNode(api_key="pn_live_...") as pn:
        print(len(pn.v3.operations))  # 120

        combo_activity = await pn.v3.execute(
            "GET /v3/combos/activity",
            query={"limit": 25},
        )
        wallet_rewards = await pn.v3.execute(
            "GET /v3/wallets/{address}/rewards",
            path_params={"address": address},
            query={"limit": 100},
        )
        return combo_activity, wallet_rewards

asyncio.run(read_v3("0xabc..."))

The SDK encodes path parameters for you. Read requests that are safe to repeat retry transient failures and honor Retry-After; requests that change data are never retried automatically. JSON decimals decode as Decimal, and ApiError exposes the status, request ID, retry details, and a request URL with credentials removed.

Current presets include dome, fills, combos, redemptions, and deposits. Current filters include since(), combo_condition_ids(), leg_position_ids(), event_ids(), module_ids(), action(), and direction().

dome and fills change settlement delivery into a flat, per-fill wire format. Use one of those presets on a dedicated PolyNodeWS connection when also consuming non-fill events; the server deduplicates delivery per connection and cannot deliver both wire formats for the same settlement.

Reconnect and delivery behavior

Why: a reconnect can overlap the last event or exceed the server's retained history. The SDK resubscribes with the latest accepted timestamp, deduplicates the overlap, preserves unknown additive events, and reports replay state. Replay is best effort, not an unbounded gapless guarantee.

pn.ws.on_replay(
    lambda notice: print(
        notice.phase, notice.since, notice.guaranteed, notice.warning
    )
)

sub.on_overflow(
    lambda overflow: print("local iterator queue evicted", overflow.dropped_events)
)

Chainlink TWAP and short-form markets

The TWAP values are lookback windows, not update cadence: 5-minute markets use 30 seconds; 15-minute and 4-hour markets use 60 seconds.

async def stream_short_markets(pn):
    prices = await (
        pn.ws.subscribe("chainlink")
        .feeds(["BTC/USD", "ETH/USD"])
        .twap_windows([30])
        .send()
    )
    print(prices.price_source, prices.twap_windows, prices.warnings)
    prices.on("price_feed", lambda event: print(event.feed, event.price))

    stream = pn.ws.short_form("5m", coins=["btc", "eth"])
    stream.on("rotation", lambda rotation: print([m.slug for m in rotation.markets]))
    stream.on("price_feed", lambda event: print(event.feed, event.price))
    stream.on("settlement", lambda event: print(event.market_slug, event.status))

A Chainlink selection is scoped to its WebSocket connection, so combine feeds and windows into one Chainlink subscription per connection. The resolved subscription exposes the server acknowledgement through price_source, twap_windows, and warnings. short_form() handles rotation safely with its own socket. At each market boundary it closes that socket, discovers the new slugs, reconnects, and subscribes to the exact settlement and TWAP filters again.

V3 perps WebSocket

The V3 perps WebSocket streams tickers, best bid/offer, full books, trades, statistics, and klines. The managed client confirms which channels were accepted, reconnects and resubscribes, and emits an explicit gap notice because the perps stream cannot replay missed messages.

import asyncio
from polynode import AsyncPolyNode, PerpsEvent, perps_channels

async def stream_perps():
    async with AsyncPolyNode(api_key="pn_live_...") as pn:
        perps = pn.perps
        hello = await perps.connect()
        ack = await perps.subscribe([
            perps_channels.tickers,
            perps_channels.book("BTC-USD"),
            perps_channels.trades("BTC-USD"),
        ])
        print(hello.max_subscriptions, ack.channels, ack.rejected)

        try:
            async for message in perps:
                if isinstance(message, PerpsEvent) and message.channel == "perps_tickers":
                    # Prices, quantities, funding, and equity values stay exact strings.
                    print(message.data["mark_price"], message.data["funding_rate"])
                elif message.type in ("lag_warning", "reconnect"):
                    print(message)
        finally:
            await perps.disconnect()

asyncio.run(stream_perps())

Use perps_channels.bbo(), .book(), .trades(), and .klines(instrument, "1m" | "1h") for scoped channels. Each perps_book event is a complete replacement snapshot; perps.book("BTC-USD") returns the latest complete book. Authentication (4401) and connection-cap (4429) closes are terminal. Queue eviction is observable through on_overflow().

WebSocket Streaming

import asyncio
from polynode import AsyncPolyNode

async def main():
    async with AsyncPolyNode(api_key="pn_live_...") as pn:
        sub = await pn.ws.subscribe("settlements").min_size(1000).send()

        async for event in sub:
            print(event.event_type, event.market_title, event.taker_price)

asyncio.run(main())

Orderbook

import asyncio
from polynode import OrderbookEngine

async def main():
    engine = OrderbookEngine(api_key="pn_live_...", integrity=True)
    await engine.subscribe(["token_id_1", "token_id_2"])

    engine.on("ready", lambda: print(f"Tracking {engine.size} books"))
    engine.on("update", lambda u: print(f"{u.asset_id}: {engine.midpoint(u.asset_id)}"))
    engine.on("integrity_error", lambda error: print(error.token, error.code))

asyncio.run(main())

With PN1 integrity enabled, the engine validates sequence continuity and deterministic checksums, fails stale or invalid books closed by default, and requests a fresh anchor before making them readable again. Integrity mode requires explicit markets; wildcard subscriptions are unavailable. Set allow_stale_reads=True only when your application explicitly prefers availability over verified state.

Trading

import asyncio
from polynode.trading import PolyNodeTrader, TraderConfig, OrderParams, ExchangeVersion

async def main():
    # CLOB V2 (pUSD collateral) is the current production default.
    trader = PolyNodeTrader(TraderConfig(
        polynode_key="pn_live_...",
        # exchange_version=ExchangeVersion.V2,
        # builder_code=None,  # disables default public Polynode attribution
    ))
    status = await trader.ensure_ready("0xYourPrivateKey...")

    result = await trader.order(OrderParams(
        token_id="...",
        side="BUY",
        price=0.55,
        size=100,
        builder="0x<your_builder_code_bytes32>",  # V2 only; omit for V1
    ))
    print(result)

    trader.close()

asyncio.run(main())

For the V2 order flow, required approvals, and common failure modes, see docs.polynode.dev.

V2 fees are determined at match time and are not signed into an order, so V2 payloads omit feeRateBps, nonce, and taker. Explicit legacy V1 mode still signs feeRateBps; for that path the SDK fetches /fee-rate and fails closed if fee, tick-size, or neg-risk metadata is unavailable or malformed.

Optional user-owned execution

Set execution_mode=ExecutionMode.USER_OWNED when the signing wallet should trade with zero builder attribution and use its own gasless authorization. Builder mode remains the default and existing integrations are unchanged.

import os
from polynode.trading import (
    ExecutionMode,
    PolyNodeTrader,
    TraderConfig,
    UserOwnedClobTransport,
)

trader = PolyNodeTrader(TraderConfig(
    polynode_key=os.environ["POLYNODE_API_KEY"],
    execution_mode=ExecutionMode.USER_OWNED,
    # Optional transport selection; direct is the default.
    # user_owned_clob_transport=UserOwnedClobTransport.PROXY,
))
ready = await trader.ensure_ready(user_wallet_signer)
print(ready.execution_mode, ready.user_relayer_authorized)

user_wallet_signer is a caller-controlled RouterSigner; the SDK asks it to sign scoped messages and never persists or transmits its private key. A private-key string is also accepted when the caller already manages it inside a trusted process. User-owned mode rejects builder credentials, nonzero builder codes, and credentials owned by another wallet. It supports EOA signers and EOA-controlled Safe or deposit wallets; legacy POLY_PROXY and Magic/DID signers are not supported in the first release. Normal CLOB authentication and Polymarket rate limits still apply.

UserOwnedClobTransport.DIRECT is the default. Integrations configured for UserOwnedClobTransport.PROXY must select it explicitly; the SDK never changes transport or falls back between paths automatically. Fee-authenticated orders are not available in user-owned mode, and any positive effective fee_bps is rejected before an order is signed or submitted.

For browser-wallet integrations, begin authorization on the trusted backend with the trader's configured Polynode key. Keep the complete challenge in one-time backend state and return only its public fields:

async def begin_wallet_authorization(trader, session, pending_authorizations):
    challenge = await trader.begin_user_relayer_authorization(
        session.wallet_address
    )
    await pending_authorizations.put_once(
        challenge.challenge_id,
        challenge,
        expires_at=challenge.expires_at,
    )
    return {
        "challengeId": challenge.challenge_id,
        "address": challenge.address,
        "expiresAt": challenge.expires_at,
        "signatureType": challenge.signature_type,
        "message": challenge.message,
    }

The connected wallet signs the exact message without reconstructing it:

const [address] = await window.ethereum.request({
  method: "eth_requestAccounts",
});
if (address.toLowerCase() !== challenge.address.toLowerCase()) {
  throw new Error("Connected wallet changed");
}
const signature = await window.ethereum.request({
  method: "personal_sign",
  params: [challenge.message, address],
});

Atomically take the original challenge and complete it against the wallet bound to the authenticated application session:

async def complete_wallet_authorization(
    trader, session, browser_result, pending_authorizations
):
    challenge = await pending_authorizations.take_once(
        browser_result.challenge_id
    )
    if challenge is None:
        raise ValueError("Unknown or already-used authorization challenge")
    credentials = await trader.complete_user_relayer_authorization(
        challenge,
        browser_result.signature,
        session.wallet_address,
    )
    return credentials

Completion validates the challenge, signature shape, expected wallet, and returned credential owner, then keeps the credential only in that trader instance's memory. It does not write the signature or credential to SQLite or another store. If the account must survive the process, encrypt the returned credential in your own wallet-bound secret manager. The global begin_user_relayer_authorization() and complete_user_relayer_authorization() helpers remain available when explicit service configuration is preferable.

For long-running services, await trader.authorize_user_owned_execution(signer) provides the combined convenience flow. Backend secret-manager storage is recommended, and the wallet-owned credential can be supplied later as TraderConfig.user_relayer_credentials. Never log it, commit it, or persist it in cookies, local storage, IndexedDB, or other browser storage. Current-tab memory is the explicitly supported, higher-risk session-only option described below.

Browser wallet to submitted order

Use the split-phase order API when a browser wallet signs but your backend owns submission. The backend retains the Polynode key, wallet-owned relayer credential, and CLOB credentials. The browser receives only one short-lived EIP-712 request and returns its signature.

Create a separate user-owned trader for each active wallet context. This example uses an in-memory SDK database so decrypted credentials exist only for the process lifetime; load them from your own encrypted secret store:

from polynode.trading import (
    ExecutionMode,
    PolyNodeTrader,
    SignatureType,
    TraderConfig,
    UserRelayerCredentials,
)

trader = PolyNodeTrader(TraderConfig(
    polynode_key=server_secrets.polynode_key,
    db_path=":memory:",
    execution_mode=ExecutionMode.USER_OWNED,
    user_relayer_credentials=UserRelayerCredentials(
        key=wallet_secrets.relayer_key,
        address=wallet_address,
    ),
))
trader.link_credentials(
    wallet=wallet_address,
    funder_address=funder_address,
    signature_type=SignatureType.EOA,  # This minimal example uses an EOA account.
    api_key=wallet_secrets.clob_key,
    api_secret=wallet_secrets.clob_secret,
    api_passphrase=wallet_secrets.clob_passphrase,
)

There are two safe credential patterns:

  • Backend vault (recommended for durable accounts): store each wallet's relayer and CLOB credentials encrypted under that wallet identity, decrypt them only into the user-owned trader, and close the trader after use.
  • Session-only browser handoff (higher risk): if your frontend SDK holds a versioned user-owned bundle only in current-tab memory, send that complete bundle once to an authenticated backend endpoint over HTTPS and import it into an in-memory trader:
{
  "version": "1",
  "executionMode": "user_owned",
  "wallet": {
    "address": "0x...",
    "funderAddress": "0x...",
    "signatureType": 0
  },
  "clobCredentials": {
    "apiKey": "...",
    "apiSecret": "...",
    "apiPassphrase": "..."
  },
  "userRelayerCredentials": {
    "key": "...",
    "address": "0x..."
  }
}

signatureType is 0 for an EOA, 2 for an EOA-controlled Safe, or 3 for an EOA-controlled deposit wallet.

async def trader_from_browser_bundle(request_json):
    trader = PolyNodeTrader(TraderConfig(
        polynode_key=server_secrets.polynode_key,
        db_path=":memory:",
        execution_mode=ExecutionMode.USER_OWNED,
    ))
    await trader.import_user_owned_browser_bundle(request_json)
    return trader

import_user_owned_browser_bundle() accepts only the exact version-1 user_owned schema, validates the relayer owner plus wallet/funder/signature-type binding, redacts the model representation, and refuses any database other than :memory:. The CLOB API secret may use canonical standard Base64 or Base64url, padded or unpadded; malformed padding, whitespace, empty values, and noncanonical encodings are rejected before the trader is mutated. Treat the request body as a secret: exclude it from access logs, traces, error reports, analytics, and replay queues. Do not retain it after the session.

When your application receives a validated order intent, prepare it without submitting:

from polynode.trading import OrderParams

async def prepare_order(trader, order_intent, prepared_orders):
    prepared = await trader.prepare_user_owned_order(OrderParams(
        token_id=order_intent.token_id,
        side="BUY",
        price=0.52,
        size=10,
        type="GTC",
    ))

    # Save the complete object in an application-owned, backend-only one-time store.
    await prepared_orders.put_once(
        prepared.signing_request.request_id,
        prepared,
        expires_at=prepared.signing_request.expires_at,
    )

    # This is the only value returned to the browser.
    return prepared.signing_request.to_dict()

The browser request has one language-neutral shape: version, requestId, address, Unix-seconds expiresAt, typedData, and order. The credential-free order preview includes the canonical positive token ID, side, tick-rounded price, two-decimal round-down size, order type, post-only and expiration controls, maker, signer, makerAmount, and takerAmount. Those are the exact values used for signing; show them to the user, but never accept a browser-edited copy as submission state.

For a BUY, preparation reads the returned preview's maker (the active funder) and requires its PolyUSD balance to cover the exact canonical makerAmount before returning anything for wallet signature. This check never moves or wraps funds. ensure_ready() deploys/configures the wallet but does not create collateral, so your platform must fund or wrap into that funder first and prepare a new order after any balance change.

Require an authenticated application session for both endpoints, bind that session to the expected wallet on the backend, validate that the user may place the requested order, and apply normal CSRF protection when using cookies. A wallet address supplied by the browser is not application authentication.

Verify the connected address and sign the exact typedData object in the browser. Do not rebuild or edit it:

const signingRequest = await fetch("/api/orders/prepare", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify(orderIntent),
}).then((response) => response.json());

const [connectedAddress] = await window.ethereum.request({
  method: "eth_requestAccounts",
});
const chainId = await window.ethereum.request({ method: "eth_chainId" });
if (
  signingRequest.version !== "1"
  || !Number.isSafeInteger(signingRequest.expiresAt)
  || Math.floor(Date.now() / 1000) >= signingRequest.expiresAt
) {
  throw new Error("Order signing request is invalid or expired");
}
if (chainId.toLowerCase() !== "0x89") {
  throw new Error("Switch the wallet to Polygon");
}
if (connectedAddress.toLowerCase() !== signingRequest.address.toLowerCase()) {
  throw new Error("Connect the wallet that owns this trading account");
}

// Display signingRequest.order for confirmation before requesting the signature.

const signature = await window.ethereum.request({
  method: "eth_signTypedData_v4",
  params: [connectedAddress, JSON.stringify(signingRequest.typedData)],
});

const result = await fetch("/api/orders/submit", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    requestId: signingRequest.requestId,
    address: connectedAddress,
    signature,
  }),
}).then((response) => response.json());

On the backend, atomically take the prepared object from session state, then validate and submit it:

async def submit_order(trader, browser_result, prepared_orders):
    # `take_once` must delete atomically so two workers cannot submit the same request.
    prepared = await prepared_orders.take_once(browser_result.request_id)
    if prepared is None:
        raise ValueError("Unknown or already-used signing request")

    result = await trader.submit_prepared_user_owned_order(
        prepared,
        request_id=browser_result.request_id,
        address=browser_result.address,
        signature=browser_result.signature,
    )
    return {
        "success": result.success,
        "orderId": result.order_id,
        "error": result.error,
    }

prepare_user_owned_order() supports V2 user-owned execution only, expires after five minutes by default, forces zero builder attribution, rejects positive fee authentication, and performs no submission. GTC, FOK, and FAK orders must omit expiration (zero is accepted and canonicalized to no expiration); GTD requires a fresh Unix-seconds expiration with the 60-second safety buffer, and the signing request is clamped to that window. submit_prepared_user_owned_order() verifies the request ID, expiry, connected wallet, stored wallet/funder identity, exact typed data, and recovered signer before consuming the request. A consumed request cannot be replayed. If submission has an ambiguous network result, reconcile its status instead of preparing an automatic duplicate.

For a single-process application, a backend-only in-memory dictionary is sufficient. For multiple workers, serialize only with the SDK's trusted server-state methods and use a server-side store that can atomically take/delete by requestId:

import json
import time

# Prepare worker: expire server state with the signing request.
ttl_seconds = prepared.signing_request.expires_at - int(time.time())
if ttl_seconds <= 0:
    raise ValueError("Signing request already expired")
await server_store.put(
    prepared.signing_request.request_id,
    json.dumps(trader.export_prepared_user_owned_order(prepared)),
    ttl_seconds=ttl_seconds,
)

# Submit worker: `take_once` must atomically return and delete the value.
raw_state = await server_store.take_once(browser_result.request_id)
if raw_state is None:
    raise ValueError("Unknown or already-used signing request")
prepared = trader.import_prepared_user_owned_order(json.loads(raw_state))

The trader authenticates exported state with a domain-separated HMAC derived from its configured backend Polynode key, verifies it on import and again before submission, then strictly reconstructs the exact V2 order from the retained market inputs. Every worker that prepares, restores, or submits these requests must use the same key. The serialized tag never contains that key, and rotating the key intentionally invalidates outstanding prepared requests. Accept exported state only from your own authenticated server-side store; never accept it from a browser. The object contains no credentials, but it contains submission controls and must remain one-time.

Never serialize the complete prepared object to the browser; only serialize prepared.signing_request.to_dict(). Never place the Polynode key, wallet-owned relayer credential, CLOB credentials, or authenticated submission headers in frontend code, cookies, browser storage, analytics, or logs.

ensure_ready() is the one-call onboarding path for user-owned Safe and deposit-wallet accounts: it deploys the selected wallet when needed, applies the base trading approvals, verifies both results, and only then reports the account ready. New deposit-wallet integrations must resolve the current address asynchronously:

from polynode.trading import resolve_deposit_wallet_address

funder = await resolve_deposit_wallet_address("0xYourEOA...")

The synchronous derive_deposit_wallet_address() helper is deprecated and derives only the legacy UUPS address; do not use it to bind a new or live deposit-wallet account. For the same reason, synchronous link_credentials() and import_wallet() reject deposit wallets in user-owned mode; use await link_wallet() or await ensure_ready() so the current address is resolved before anything is stored.

trader.split(SplitParams(...)) and trader.merge(MergeParams(...)) preserve the synchronous build-only API and return a TransactionRequest without signing or submitting anything. In user-owned mode, await trader.execute_split(SplitParams(...)) and await trader.execute_merge(MergeParams(...)) execute the corresponding gasless operation for EOA-controlled Safe and deposit-wallet accounts. Supply either an explicit neg_risk boolean or a token_id for fail-closed execution routing; V2 uses the appropriate collateral adapter automatically. Each executed operation batches only the additional permission it needs; split allowance is limited to the exact split amount.

await trader.wrap_to_polyusd(...) and await trader.unwrap_from_polyusd(...) also use the account's wallet-specific gasless path for Safe and deposit-wallet accounts. Caller-controlled browser or HSM signers remain supported; these smart-wallet operations do not require handing a private key to the SDK.

Documentation

Full docs at docs.polynode.dev

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polynode-0.14.0.tar.gz (121.3 kB view details)

Uploaded Source

Built Distribution

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

polynode-0.14.0-py3-none-any.whl (132.9 kB view details)

Uploaded Python 3

File details

Details for the file polynode-0.14.0.tar.gz.

File metadata

  • Download URL: polynode-0.14.0.tar.gz
  • Upload date:
  • Size: 121.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for polynode-0.14.0.tar.gz
Algorithm Hash digest
SHA256 2591ef779ead2ed885e069b1533abf54755d1b0e135d6a66c6eae499941599e2
MD5 672d13dcd3132bc96093520908f93ac9
BLAKE2b-256 9b6630f8a25c172c54b4039d31deaaf2957d337d18aa1856c7d74ac3e9df0b68

See more details on using hashes here.

File details

Details for the file polynode-0.14.0-py3-none-any.whl.

File metadata

  • Download URL: polynode-0.14.0-py3-none-any.whl
  • Upload date:
  • Size: 132.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for polynode-0.14.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e5fc28418ba8965dc4940fa903959268bde9b16eabe03f6b592f34558535e916
MD5 09a202796e0619f495411861774cff8f
BLAKE2b-256 6a539a56ee331579095d043dae8d895eae39275a666678a37045b36b2834c1c5

See more details on using hashes here.

Release history Release notifications | RSS feed

0.14.1

2 files

This release

0.14.0 This release

2 files

0.13.0

2 files

0.12.2

2 files

0.12.1

2 files

0.12.0

2 files

0.11.0

2 files

0.10.8

2 files

0.10.7

2 files

0.10.6

2 files

0.10.5

2 files

0.10.4

2 files

0.10.3

2 files

0.10.2

2 files

0.10.1

2 files

0.10.0

2 files

0.9.3

2 files

0.9.2

2 files

0.9.1

1 file

0.9.0

1 file

0.8.0

1 file

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.3

2 files

0.6.2

2 files

0.6.1

2 files

0.6.0

2 files

0.5.5

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page