Files
app/backend
stroblme 5d0ea480bf Alerts: a Telegram channel, one chat or group each, connected by a one-time link
The channel sends through the Bot API with httpx only: HTML with escaped text,
cut to fit a message, silent for a warning, a short 429 waited out once, and
errors that say what to do about a blocked bot, a lost chat or a bad token and
never quote the request URL. The bot token is a stored secret: saving a
channel refuses a literal one, the card's "Store token" writes the secret and
a reference, and no endpoint returns it.

A chat id is never typed. Connect starts a ten minute code, and the chat that
sends `/start <code>` back through the bot is the one connected, so it is a
chat somebody opened a link for. The engine fetches updates only while a code
is waiting (no standing poll, no webhook, no inbound address) and ignores
everything else without a reply. Connect needs a saved form, and the form
takes the connected chat in without touching what was typed since.

The token is part of every Bot API URL, so the httpx logger gets the same
filter the request lines have, which now also masks an httpx.URL argument.
2026-10-28 13:06:58 +01:00
..

Fluksio

Turn Python functions into connected nodes, run experiments, and keep their metrics and artifacts together. Start an engine with Python 3.12 or newer on Linux or macOS:

pip install fluksio
fluksio serve

The first start prints an admin password and opens a terminal dashboard. For a browser dashboard, connect the instance to the optional portal.

For data science

Save this small experiment as study.py. No dataset or GPU needed:

import math

from fluksio import Flow, Port, node

@node(
    requires=[Port("lr", "float")],
    provides=[Port("loss", "float", stream=True), Port("final_loss", "float")],
)
def fit(lr, epochs=25):
    for epoch in range(epochs):
        loss = math.exp(-lr * (epoch + 1))
        yield {"loss": loss}
    return {"final_loss": loss}


train = Flow(
    "train",
    nodes=[fit],
    inputs=[Port("lr", "float", initial=0.01)],
    outputs=["final_loss"],
)

Matching message names connect the nodes and determine their order. After syncing the project, start a run:

fluksio sync study
fluksio run train --lr 0.05 --wait

Each yield records a point on the loss curve. Replace the toy calculation with your own training code when you're ready. For artifacts and comparisons, try the data science guide.

More to explore

  • Flows: typed messages between nodes, wired by name, edited on a canvas or declared in code. Every change is a commit in a git repository you own.
  • Runs: an experiment and a CI-style job are the same entity. Parameters, seed, result, per-node timings, artifacts and the commit it ran at.
  • Dashboards: charts and controls bound to the same messages the flows carry, with no separate metrics pipeline.
  • Remote workers: pip install fluksio-worker on the GPU box; it dials out over one websocket, so nothing there has to be reachable.

For sensors, devices and live automation, try the facility automation guide.

License

Copyright (C) 2026 Melvin Strobl - GNU Affero General Public License v3.0 or later. Running a modified version over a network obliges you to offer its users the corresponding source (AGPL §13).