Build interactive data web apps in pure Python
Project description
spyre2
Build interactive data web apps in pure Python — no HTML, CSS, or JavaScript required.
Spyre2 is a ground-up rewrite of spyre using a modern stack: FastAPI, Alpine.js, and native support for matplotlib, Plotly, and Altair.
Install
pip install spyre2
pip install spyre2[matplotlib] # + matplotlib
pip install spyre2[plotly] # + plotly
pip install spyre2[all] # everything
Quickstart
import numpy as np
import matplotlib.pyplot as plt
import spyre2
class SineApp(spyre2.App):
title = "Sine Wave"
inputs = [
spyre2.Slider("frequency", label="Frequency", min=1, max=20, default=5),
spyre2.Dropdown("color", label="Color",
options=["steelblue", "crimson", "seagreen"]),
]
outputs = [
spyre2.Plot("sine_plot"),
]
def sine_plot(self, frequency, color):
fig, ax = plt.subplots(figsize=(8, 4))
x = np.linspace(0, 2 * np.pi, 500)
ax.plot(x, np.sin(frequency * x), color=color)
return fig
SineApp().launch()
Open http://127.0.0.1:8000.
Inputs
| Class | Description |
|---|---|
Slider(id, min, max, step, default) |
Numeric range slider |
Dropdown(id, options, default) |
Select dropdown |
RadioButtons(id, options, default) |
Radio button group |
CheckboxGroup(id, options, default) |
Multi-select checkboxes |
TextInput(id, default, placeholder) |
Free-text input |
FileUpload(id, accept) |
File picker |
All inputs accept a label keyword argument. If omitted, the label is inferred from the id.
Outputs
| Class | Handler return type |
|---|---|
Plot(id) |
matplotlib.figure.Figure or plotly.Figure or altair.Chart |
Table(id) |
pandas.DataFrame |
HTML(id) |
str (HTML) |
Download(id) |
(filename: str, content: str | bytes) |
The handler method name must match the output id:
outputs = [spyre2.Plot("my_plot")]
def my_plot(self, **kwargs): # method name = output id
...
return fig
Layouts
Sidebar (default)
Controls on the left, outputs stacked on the right. No configuration needed.
Grid
from spyre2 import Layout
class MyApp(spyre2.App):
layout = Layout.grid([
["controls", "controls" ],
["plot_a", "plot_b" ],
["big_table", "big_table" ],
])
Repeat an ID across adjacent cells to span columns. "controls" is a reserved name for the input panel.
Tabs
layout = Layout.tabs({
"Overview": ["trend_plot"],
"Detail": ["data_table", "bar_chart"],
})
Multiple chart libraries
The chart library is detected automatically from the return type — no configuration needed.
# matplotlib
def my_plot(self, x):
fig, ax = plt.subplots()
ax.plot(...)
return fig # → rendered as SVG
# Plotly
import plotly.express as px
def my_plot(self, x):
return px.scatter(df, x="a", y="b") # → rendered via Plotly.js
# Altair
import altair as alt
def my_plot(self, x):
return alt.Chart(df).mark_line()... # → rendered via Vega-Embed
Jupyter notebooks
app.launch() detects when it's running inside a Jupyter kernel and automatically starts the server in a background thread and displays an inline IFrame.
SineApp().launch(port=8765) # displays inline in the notebook
Migrating from spyre v1
Use the included CLI tool to mechanically convert a v1 app:
spyre2-migrate myapp.py # preview conversion
spyre2-migrate myapp.py -o new.py # write to new file
spyre2-migrate myapp.py --in-place # overwrite (creates .bak backup)
The tool converts imports, inputs/outputs list-of-dicts, and renames getPlot/getTable etc., leaving # TODO comments where manual cleanup is needed.
What changes:
| spyre v1 | spyre2 |
|---|---|
from spyre import server |
import spyre2 |
class App(server.App) |
class App(spyre2.App) |
inputs = [{"type": "slider", "key": "x", ...}] |
inputs = [spyre2.Slider("x", ...)] |
def getPlot(self, params): x = params["freq"] |
def my_plot(self, freq): |
| CherryPy on port 9093 | uvicorn on port 8000 |
For apps that can't be fully migrated yet, spyre2.compat.App accepts the old dict-based syntax (deprecated, will be removed in a future release).
Examples
| File | Demonstrates |
|---|---|
examples/sine_example.py |
Sidebar layout, matplotlib, slider + dropdown |
examples/grid_example.py |
Grid layout, matplotlib, multiple outputs + table |
examples/plotly_example.py |
Tabs layout, Plotly, scatter + histogram |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spyre2-0.1.0.tar.gz.
File metadata
- Download URL: spyre2-0.1.0.tar.gz
- Upload date:
- Size: 108.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f309f5ebaa55f6b2465cd06148e5ba0423abc87effe905bedc9c801231f98514
|
|
| MD5 |
60f482ce64d7f99213942398e3537735
|
|
| BLAKE2b-256 |
9323631bccdc7d84fb2ab72b30984cafba7ac9bb2258bfc4fe3c87e2adfc9804
|
File details
Details for the file spyre2-0.1.0-py3-none-any.whl.
File metadata
- Download URL: spyre2-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec0925221d63f3115f3a11a7b27ddee18888a7def5f0aea1b0a7570eda5f10cf
|
|
| MD5 |
c17d4ec4e0fefcf713a1b5628b2b6d9f
|
|
| BLAKE2b-256 |
d92d4fdb6bf8cee4a086f7201434e645a17ee75fb718582ca99886b0b24e9d1c
|