Documentation
See it in action — browse live examples on the @skua profile page.
Installation
pip install getskuaThat's it. Skua uses your installed libraries to serialize your objects so there will never be any version conflicts or compatibility issues. Works with matplotlib, plotly, pandas, polars, numpy, PIL, PyTorch, TensorFlow, and any object with a string representation.
Quick Start
import skua
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
ax.bar(x, revenue, label="Revenue", ...)
ax.bar(x, costs, label="Costs", ...)
ax.plot(x, profit, "o-", label="Profit")
# ...
skua.snap(fig, title="Revenue vs Costs", description="...", tags=[...])
# > https://skua.dev/s/yut0cFOSzFFUShare the URL with anyone. Re-run skua.snap() with the same title to update in place — same URL, fresh results.
CLI
skua snap chart.png --title "Q3 Revenue"
skua snap data.csv --title "Sales Data" --public --tags "finance,q3"
skua snap plot.json --title "Interactive Chart"
cat report.txt | skua snap - --type text --title "Analysis"Use --json for machine-readable output:
skua snap chart.png --title "Chart" --json
# {"url": "https://skua.dev/s/abc123", "id": "abc123", "visibility": "public"}API Reference
skua.snap()
Capture and share a Python object via Skua.
objrequiredObject to snap (matplotlib/plotly figure, pandas/polars DataFrame, PIL image, PyTorch/TF tensor, list of dicts, or any object with string representation)
titlerequired, str, max 500 charsSnapshot title. Snapping with the same title updates the existing snapshot.
descriptionoptional, str, max 1000 charsShort description providing context (1-3 sentences recommended).
tagsoptional, list[str], max 20 tags, 30 chars eachTags for categorization. Empty strings are ignored, whitespace is stripped.
Returns a SnapResult object with .url and .metadata attributes. In Jupyter notebooks, displays the original object inline.
skua.configure()
Set session-wide defaults and configuration.
publicoptional, boolDefault visibility for snapshots.
api_urloptional, strBase URL for Skua API.
web_urloptional, strBase URL for Skua web app.
tokenoptional, strAuthentication token for programmatic access.
skua.login()
Open the browser to verify your email. Verified accounts get 90-day retention (vs 7 days), 50 snapshots (vs 10), and a public profile page at skua.dev/u/username.
skua.auth()
Paste the token you receive by email after skua.login().
skua.status()
Check current authentication status. Returns a dict with authenticated, email, session_id, and retention_days.
Supported Types
Matplotlib figures
Saved as high-DPI PNG images. Pass any plt.Figure object.
import skua
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(8, 5))
ax.scatter(*setosa.T, label="Setosa", alpha=0.7)
ax.scatter(*versicolor.T, label="Versicolor", alpha=0.7)
ax.scatter(*virginica.T, label="Virginica", alpha=0.7)
ax.set_xlabel("Sepal Length (cm)")
ax.set_ylabel("Sepal Width (cm)")
ax.set_title("Iris Dataset — Sepal Dimensions")
ax.legend()
skua.snap(fig, title="Iris Scatter Plot", description="...", tags=[...])
# > https://skua.dev/s/aFAsrP04QFpZPlotly figures
Rendered as fully interactive charts — zoom, pan, hover tooltips, and PNG export.
import skua
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(x=years, y=anomaly, ...))
skua.snap(fig, title="Global Temperature Anomaly", description="...", tags=[...])
# > https://skua.dev/s/IGj1D9tvjEzlPandas DataFrames
Rendered as interactive, sortable, filterable tables.
import skua
import pandas as pd
df = df.set_index("ticker")
# df = pd.DataFrame({...}) # 30 stocks
skua.snap(df, title="S&P 500 Snapshot", description="...", tags=[...])
# > https://skua.dev/s/8qwgF8I3fWyMPolars DataFrames
Same interactive table rendering. LazyFrames are collected automatically.
import skua
import polars as pl
# df = pl.DataFrame({...}) # 8 chips
skua.snap(df, title="CPU Benchmarks", description="...", tags=[...])
# > https://skua.dev/s/Jif2aMq39AMgList of dicts
Common output from HuggingFace pipelines and eval loops — rendered as a table.
import skua
# results = pipeline("sentiment-analysis")(texts)
skua.snap(results, title="Sentiment Analysis", description="...", tags=[...])
# > https://skua.dev/s/K0OT1VKeqtC4PIL Images
Any PIL.Image object, saved as PNG.
import skua
from PIL import Image
import numpy as np
w, h, max_iter = 960, 640, 80
x = np.linspace(-2.5, 1.0, w)
y = np.linspace(-1.2, 1.2, h)
C = x[np.newaxis, :] + 1j * y[:, np.newaxis]
Z = np.zeros_like(C)
M = np.zeros(C.shape, dtype=int)
for i in range(max_iter):
mask = np.abs(Z) <= 2
Z[mask] = Z[mask] ** 2 + C[mask]
M[mask] = i
t = M / max_iter
r = (np.sin(3.0 * t * np.pi) * 127 + 128).astype(np.uint8)
g = (np.sin(3.0 * t * np.pi + 0.8) * 127 + 128).astype(np.uint8)
b = (np.sin(3.0 * t * np.pi + 1.6) * 127 + 128).astype(np.uint8)
rgb = np.stack([r, g, b], axis=-1)
img = Image.fromarray(rgb)
skua.snap(img, title="Mandelbrot Set", description="...", tags=[...])
# > https://skua.dev/s/CJDwwRo2lLMTPyTorch & TensorFlow tensors
Image tensors (CHW or BCHW) are rendered as PNG. Other tensors are displayed as tables.
Text & strings
Any object with a string representation. Full Unicode support — em-dashes, accented characters, CJK, and emoji all render correctly.
import skua
skua.snap("¥127.4M", title="Q4 Revenue", description="...", tags=[...])
# > https://skua.dev/s/9f7oA3UsCVMuAnonymous Usage
No account required. Anonymous sessions have the following limits:
- Snapshots expire after 7 days
- 10 snapshots per session
- 20 uploads per hour
- 10 MB max per snapshot
Validated Accounts
Verify your email to unlock longer retention and higher limits:
- 90-day retention per snapshot — each snapshot's clock resets when you update it
- 1-year maximum retention per snapshot
- 50 snapshots per account
- 10 MB max per snapshot
Run skua.login() in your notebook to start the verification flow. You'll receive a token by email to paste back into your session.
Support
Questions or feedback? Email hello@skua.dev or open an issue on GitHub.