Skip to main content

Python SDK for the blockfill execution daemon

Project description

blockfill Python SDK

Python wrapper for the blockfill execution daemon. Manage exchange credentials, run the daemon, and operate tickets (place / query / cancel) over a local UDS RPC socket.

Requirements

  • Python 3.10+
  • linux-x86_64 — the daemon binary is bundled inside the wheel. PyPI publishes a manylinux2014_x86_64-tagged wheel only; macOS / Windows / arm64 hosts will be cleanly rejected by pip with "no matching distribution".

Install

pip install blockfill

The wheel ships with the executor binary pre-built. No GitHub release, no install() call — pip install is everything. The qtex endpoint and API key are also hardcoded into the binary; users never set them.

Quickstart

from blockfill import Blockfill

bf = Blockfill(data_dir="~/.blockfill")

# One-time: write exchange credentials to ~/.blockfill/config.toml
bf.set_credentials("binance-futures", api_key="...", api_secret="...", testnet=True)

# Start daemon (background, returns once UDS socket is up)
bf.start()
bf.health()  # raises DaemonNotRunning if anything is wrong

# Place a ticket
ticket = bf.place(
    exchange="binance-futures",
    symbol="btcusdt",
    strategy="maker",
    target_position=0.1,
    time_constraint_ms=300_000,
)
print(ticket.ticket_id, ticket.status)  # tkt_xxx NEW

# Query active session (in-memory)
tickets = bf.query(status="NEW")

# Query persistent history (qtex MongoDB; survives daemon restarts)
historical = bf.query(status="COMPLETE", history=True)

# Cancel
bf.cancel(ticket.ticket_id)

# Shut down daemon
bf.stop()

API Reference

Blockfill(data_dir, binary_path, timeout_s)

Parameter Default Description
data_dir ~/.blockfill Data directory (config, socket, logs, trading log)
binary_path bundled _bin/blockfill Override the bundled binary path (rarely needed)
timeout_s 10.0 Default RPC call timeout (seconds)

Version

bf.version() -> str
# Returns "blockfill 0.1.X"

Credentials

bf.set_credentials(
    exchange: str,            # "binance-futures" | "okx-swap"
    api_key: str,
    api_secret: str,
    api_passphrase: str | None = None,  # OKX only
    testnet: bool = False,
) -> None
# Writes the [exchanges.<name>] block of {data_dir}/config.toml (chmod 0600)

The qtex endpoint and API key are compiled into the binary at release time — you do not configure them.


Daemon

bf.start(wait_timeout_s=10.0, env=None) -> None
# Spawns the daemon in the background, returns once the UDS socket is bound.
# Idempotent — no-op if already running.

bf.stop(wait_timeout_s=5.0) -> None
# Graceful shutdown.

bf.restart() -> None
bf.is_running() -> bool

bf.health() -> DaemonStatus
# Raises DaemonNotRunning if the socket is missing or unreachable.

bf.run_foreground(env=None) -> None
# Blocking; for debug.

DaemonStatus fields: running, pid, exchanges, active_tickets, uptime_s, version


Tickets

bf.place(
    exchange: str,
    symbol: str,
    strategy: str = "maker",        # "maker" | "twap"
    target_position: float,          # positive = long, negative = short
    time_constraint_ms: int = 300_000,  # 60_000 .. 86_400_000
) -> Ticket

bf.query(
    status: str | None = None,       # "NEW" | "OPEN" | "COMPLETE" | "CANCEL"
    symbol: str | None = None,
    ticket_id: str | None = None,
    from_ms: int | None = None,
    to_ms: int | None = None,
    limit: int = 100,
    history: bool = False,           # False=in-memory; True=qtex MongoDB
) -> list[Ticket]

bf.cancel(ticket_id=None, symbol=None, all=False) -> None | int
# - cancel(ticket_id="tkt_...") -> None     # raises TicketNotFound if missing
# - cancel(symbol="btcusdt")    -> int      # cancel NEW+OPEN for that symbol
# - cancel(all=True)            -> int      # cancel everything active

bf.cancel_all() -> int

Ticket fields:

Field Type Notes
ticket_id str tkt_<hex>
status str NEW / OPEN / COMPLETE / CANCEL
exchange str binance-futures / okx-swap
symbol str exchange-format symbol
strategy str maker / twap
target_position float requested net position
init_position float | None exchange position at activation time
executed_position float | None actual delta filled so far
time_constraint_ms int execution time limit
start_time_ms int | None set when executor activates the ticket (NEW → OPEN)
last_update_time_ms int | None refreshed on every state change
is_expired bool flag-only; status stays OPEN until separately cancelled
cancel_reason str | None see table below

cancel_reason values: external, superseded, stale, rejected, warmup, min_notional, risk_breach, insufficient_margin, paused

Auto-supersede: placing a new ticket for the same exchange+symbol immediately cancels any existing NEW/OPEN ticket for that pair (cancel_reason="superseded"). The superseded ticket remains in query results.


Context Manager

with Blockfill() as bf:
    bf.start()
    ticket = bf.place(...)
# daemon is stopped on exit

Exceptions

Exception When
BinaryNotFound bundled binary missing — pip install --force-reinstall blockfill
DaemonNotRunning daemon socket not found or unreachable
DaemonStartTimeout start() timed out waiting for the daemon
RpcError(code, message) daemon returned a JSON-RPC error
TicketNotFound cancel(ticket_id=...) called with non-existent ticket
CredentialsError invalid exchange name in set_credentials()
InvalidApiKey qtex rejected the embedded BLOCKFILL_API_KEY (HTTP 401)

Patterns

Strategy system integration

from blockfill import Blockfill

bf = Blockfill()

if not bf.is_running():
    bf.start()
bf.health()

# On each signal
ticket = bf.place(
    exchange="binance-futures",
    symbol=symbol,
    strategy="maker",
    target_position=position,
    time_constraint_ms=300_000,
)

Check open positions

open_tickets = bf.query(status="NEW") + bf.query(status="OPEN")
for t in open_tickets:
    print(t.symbol, t.target_position, t.init_position, t.executed_position)

Audit past runs

# In-memory query only sees the current session.
# Use history=True to reach qtex MongoDB for COMPLETE / CANCEL from past sessions.
recent_completes = bf.query(status="COMPLETE", history=True, from_ms=ts_ms_24h_ago)

Directory Structure

~/.blockfill/
├── config.toml              # exchange credentials (chmod 0600)
├── runtime/
│   ├── daemon.sock          # UDS socket (SDK ↔ daemon IPC)
│   ├── daemon.pid           # PID file
│   └── daemon.log           # daemon logs
└── trading-log/             # Channel B upload retry buffer

The daemon binary lives inside the installed package (site-packages/blockfill/_bin/blockfill), not in ~/.blockfill/.


Supported Exchanges

Exchange Value
Binance Futures "binance-futures"
OKX Swap "okx-swap"

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

blockfill-0.1.3-py3-none-manylinux2014_x86_64.whl (7.5 MB view details)

Uploaded Python 3

File details

Details for the file blockfill-0.1.3-py3-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for blockfill-0.1.3-py3-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5201ce81797e2a96d3311f4f3c4106cb950b1c8a2696efe24da129ba14dd5f90
MD5 2478960fb13208de93618f184244aebd
BLAKE2b-256 546091aead2d6781c5af2bf8a43c2e640179d218d8ec6aa105c1a4bacbe478ad

See more details on using hashes here.

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