Skip to main content
wicket

Which waiting job may start now?

Fair admission of work to shared capacity, for asyncio Python:
priority, fairness between tenants, and limits that hold across every process.

PyPI Python CI License: MIT

Quick start · PostgreSQL · Decisions · Changelog

alice asks for 6 reports, bob for 2, carol for 1. In a plain queue carol starts last, 9th; with wicket she starts 3rd

Why wicket

One tenant submits a thousand jobs, another submits one. A plain queue makes the second wait behind the first thousand. wicket sits beside the queue you already have and tells your workers what to take next.

  • Fair from the first grant. Tenants get their turns by Start-time Fair Queuing; one who comes back after a break gets no burst of turns.
  • Priority you can read. A weighted sum of factors: whose turn it is, a trait such as the plan tier, how long the job has waited.
  • Limits across processes. Concurrency and rate hold for any number of workers: every grant is a compare-and-swap on the pool's version.
  • Safe when a worker dies. Its lease ends and the job is delivered again; a fencing token rejects the old worker's late write.
  • Small. One dependency, msgspec. An in-memory store, and a PostgreSQL one that commits a job in your own transaction.

wicket does not run the work, retry it or keep its status. It decides what starts.

Quick start

pip install wicket
import asyncio
from datetime import timedelta

from wicket import (
    Concurrency,
    FairShare,
    MemoryBacklog,
    MemoryLedger,
    MemoryState,
    Pool,
    Priority,
    Ticket,
)


async def main() -> None:
    state = MemoryState()
    backlog, ledger = MemoryBacklog(state), MemoryLedger(state)

    # alice floods the queue first, bob asks once
    for n in range(3):
        await backlog.submit("reports", Ticket(id=f"alice-{n}", tenant="alice"))
    await backlog.submit("reports", Ticket(id="bob-0", tenant="bob"))

    pool = Pool(
        ledger,
        "reports",
        priority=Priority((FairShare(), 1)),
        limits=(Concurrency(2),),
        lease=timedelta(seconds=30),
        poll=timedelta(milliseconds=50),
    )

    async def worker() -> None:
        async with pool.permit() as permit:  # waits for its turn, keeps the lease while it runs
            print("started", permit.waiting.ticket.id)
            await asyncio.sleep(0.1)  # the work

    await asyncio.gather(*(worker() for _ in range(4)))


asyncio.run(main())
started alice-0
started bob-0
started alice-1
started alice-2

Bob submitted last and starts second. Only a block that ends normally releases its ticket; after an error the ticket comes back once its lease ends.

Priority and limits

Factors score tickets in 0..1 and are weighted; limits hold together:

from wicket import Age, Rate, Trait, TraitFactor

pool = Pool(
    ledger,
    "materials",
    priority=Priority(
        (FairShare(), 4),
        (TraitFactor("tier"), 2),
        (Age(full_after=timedelta(minutes=30)), 1),
    ),
    limits=(Concurrency(4), Rate(10, per=timedelta(minutes=1))),
    lease=timedelta(minutes=2),
    poll=timedelta(seconds=1),
)

ticket = Ticket("task-1", "alice", traits=(Trait("tier", 1.0), Trait("urgent", 0.5)))

Trait(name, value) is an immutable number in 0..1 on a ticket. TraitFactor(name) scores tickets by that named value, or 0 when absent. A ticket takes a tuple of traits with unique names; neither the tuple nor its traits can change. Tickets encode and decode with msgspec without hooks.

PostgreSQL

The extra brings SQLAlchemy; bring your driver, asyncpg or psycopg.

pip install "wicket[postgres]"
from wicket.postgres import PostgresBacklog, PostgresLedger, metadata

# in your Alembic env.py: target_metadata = [your_metadata, metadata]

async with session.begin():  # your transaction: the row and its ticket commit together
    session.add(row)
    await session.flush()  # the row gets its id
    await PostgresBacklog(session).submit("materials", Ticket(id=str(row.id), tenant=str(user_id)))

ledger = PostgresLedger(engine, retention=timedelta(hours=1))  # the same retention in every process

Upgrading from 0.1.0 to 0.2.0

This release changes ticket traits and the Ledger contract. Upgrade all producers, workers and custom adapters sharing a pool together. Existing databases need the submission ID migration before using the updated adapters; follow its stop, migrate and upgrade instructions before resuming work.

Status

wicket is pre-alpha: the API may change before 1.0, and every change is in the changelog.

Documentation

Contributing

Issues and pull requests are welcome. Read CONTRIBUTING.md first, and follow the Code of Conduct. Report vulnerabilities privately, as the security policy says.

License

MIT

Metadata

Release files for wicket 0.2.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 wicket 0.2.0
File Size Uploaded Provenance Actions
wicket-0.2.0.tar.gz 16.4 kB With provenance Details for wicket-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wicket 0.2.0
File Interpreter ABI Platform Actions
wicket-0.2.0-py3-none-any.whl Python 3 none any Details for wicket-0.2.0-py3-none-any.whl

Total release size: 36.3 kB

Release files / wicket-0.2.0.tar.gz

Download URL wicket-0.2.0.tar.gz
Size 16.4 kB
Tags Source
SHA-256 checksum
How to use checksums
4f92ce910f695efa25f0f7519dd6861e3f2992d769fbb2530af57a4469907f46
BLAKE2b-256 checksum
How to use checksums
1cbaccb15033f8788f9abe43ad1c1aa6dc4f6adc016407321e38e134310785c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 25, 2026.

Transparency log

Release files / wicket-0.2.0-py3-none-any.whl

Download URL wicket-0.2.0-py3-none-any.whl
Size 19.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98b1e43d23cb951d9e3c34163e1518e0191d617d8ce9d0eebd9c426dfd16e544
BLAKE2b-256 checksum
How to use checksums
a9a92b52c564396e26d254f18a856a66c8ae2c0d6d6cfbeb1dc7a6dcdbcef792
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 25, 2026.

Transparency log

Security for wicket 0.2.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for wicket-0.2.0.tar.gz

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 25, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

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