Skip to main content

spaday-perspective

Perspective for spaday

Build Status codecov License PyPI

Overview

spaday-perspective moves the existing PerspectivePanel integration out of spaday core. Its self-contained <perspective-panel> bundle includes Perspective's client, viewer (the multi-panel workspace element since Perspective 5), datagrid, themes, and viewer WASM.

Documentation

Quick example

This complete app serves a live Perspective table. Add trade streams a new row into the grid, the select switches between flat and grouped layouts, and the checkbox changes the viewer theme.

import perspective
from perspective.handlers.starlette import PerspectiveStarletteHandler
from starlette.responses import JSONResponse
from starlette.routing import Route, WebSocketRoute
from starlette.websockets import WebSocket

from spaday import CallEndpoint, cond, element, eq, field, obj
from spaday.backends.starlette import serve
from spaday_perspective import PerspectivePanel

server = perspective.Server()
client = server.new_local_client()
trades = client.table(
    [
        {"id": 1, "symbol": "AAPL", "side": "buy", "price": 211.10},
        {"id": 2, "symbol": "MSFT", "side": "sell", "price": 503.02},
    ],
    name="trades",
)
next_id = 2


async def add_trade(_request):
    global next_id
    next_id += 1
    trades.update(
        [
            {
                "id": next_id,
                "symbol": "AAPL" if next_id % 2 else "MSFT",
                "side": "buy" if next_id % 2 else "sell",
                "price": 210 + next_id,
            }
        ]
    )
    return JSONResponse({"id": next_id})


async def perspective_socket(websocket: WebSocket):
    await PerspectiveStarletteHandler(perspective_server=server, websocket=websocket).run()


def layout(*, grouped=False):
    viewer = {"table": "trades", "plugin": "Datagrid", "columns": ["symbol", "side", "price"]}
    if grouped:
        viewer.update({"group_by": ["symbol"], "columns": ["price"], "aggregates": {"price": "avg"}})
    return {
        "layout": {"type": "tab-layout", "tabs": ["trades"]},
        "panels": {"trades": viewer},
    }


panel = (
    PerspectivePanel()
    .compute("theme", cond(field("dark"), "dark", "light"))
    .compute(
        "config",
        obj(
            {
                "ws_url": "/perspective",
                "tables": ["trades"],
                "layout": cond(eq(field("view"), "grouped"), layout(grouped=True), layout()),
            }
        ),
    )
    .style(display="block", height="70vh", margin_top="1rem")
)

view = element("select").bind("value", "view", mode="two-way").child(
    element("option", "Blotter", value="blotter"),
    element("option", "Average by symbol", value="grouped"),
)
dark = element("input", type="checkbox").bind("checked", "dark", mode="two-way")
page = (
    element("main")
    .style(margin="1rem", font_family="system-ui")
    .child(element("button").text("Add trade").on("click", CallEndpoint("POST", "/api/trades")))
    .child(view)
    .child(element("label").child(dark, " Dark theme"))
    .child(panel)
)

app = serve(
    page,
    packages=["perspective"],
    store={"view": "blotter", "dark": False},
    routes=[
        Route("/api/trades", add_trade, methods=["POST"]),
        WebSocketRoute("/perspective", perspective_socket),
    ],
)

Save this as app.py, then run pip install spaday-perspective perspective-python starlette uvicorn and uvicorn app:app. Open http://127.0.0.1:8000.

This keeps Perspective's bulk data on its native websocket. A spaday/transports model only needs to carry the small serializable connection/layout config. Replacing config reconnects when ws_url changes and restores changed layouts; theme accepts light, dark, or a Perspective theme name.

Installing this project registers the perspective entry point with spaday. The equivalent explicit forms are packages=[spaday_perspective.package] and packages=["spaday_perspective:package"].

Run the local example

python -m pip install -e ".[examples]"
python -m spaday_perspective.example

Open http://127.0.0.1:8015 to inspect the complete market-monitor example: live native Perspective streaming, flat and grouped layouts, server-authoritative order submission, reactive metrics, and light/dark themes. It passes the local package descriptor directly, so it does not install or resolve the integration from GitHub.

[!NOTE] This library was generated using copier from the Base Python Project Template repository.

Download files

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

Source Distribution

spaday_perspective-0.4.6.tar.gz (4.6 MB view details)

Uploaded Source

Built Distribution

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

spaday_perspective-0.4.6-py3-none-any.whl (4.5 MB view details)

Uploaded Python 3

File details

Details for the file spaday_perspective-0.4.6.tar.gz.

File metadata

  • Download URL: spaday_perspective-0.4.6.tar.gz
  • Upload date:
  • Size: 4.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.13

File hashes

Hashes for spaday_perspective-0.4.6.tar.gz
Algorithm Hash digest
SHA256 32f3731edd651592dd0ccf2e410e83b330c85dce277cd89253be78b043f6909a
MD5 064170d2935145bc1507214fdaf810ea
BLAKE2b-256 9a3d34cf8d5d279dd0ddccf80e70690ad95404a75085ed8ad54551425fd16893

See more details on using hashes here.

File details

Details for the file spaday_perspective-0.4.6-py3-none-any.whl.

File metadata

File hashes

Hashes for spaday_perspective-0.4.6-py3-none-any.whl
Algorithm Hash digest
SHA256 a23f2ba191845143b45d361bb1bf803955a6ed721729a1c9f92e2167b182766d
MD5 cf84eaac00576ded63ed5113ecd531ec
BLAKE2b-256 699a73bd061a3d25e42262c8de125db876086b908553d4c129720eaf983f5742

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.0

2 files

This release

0.4.6 This release

2 files

0.4.5

2 files

0.4.4

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 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