# Changelog

## 0.2.0

**Everything is now called `pyflowred`.** 0.1.0 shipped under that name on
PyPI but kept `pyred` everywhere else, which meant the distribution and the
thing you imported disagreed. This release makes them one name, and there is
no compatibility shim - upgrading means changing the names below.

| was | is |
|---|---|
| `import pyred` | `import pyflowred` |
| the `pyred` command | `pyflowred` |
| `PYRED_*` environment variables | `PYFLOWRED_*` |
| `[tool.pyred]` in `pyproject.toml` | `[tool.pyflowred]` |
| the `pyred.nodes` entry point group | `pyflowred.nodes` |
| `pyred_*` Prometheus metrics | `pyflowred_*` |
| the default user directory `~/.pyred` | `~/.pyflowred` |

Flows, credentials and project repositories are untouched: the flow file
format has not changed, so moving the user directory across is all an
existing installation needs. A node package has to re-declare its entry
point group to be found.

Also in this release:

- The Google Secret Manager provider could never have worked. The reply
  object handed to google-auth assigned `status`/`headers`/`data` in
  `__init__`, but they are abstract properties on its base class, so the
  class could not be instantiated and every token refresh raised
  `TypeError`. The path is now covered by an offline test as well as the
  one that needs a reachable Secret Manager.
- `POST /flows` with a bare array under API v2 returned an internal
  attribute error as its message. It answers 400 and names the v1 header.

## 0.1.0

- Initial port of the Node-RED 5.0.7 runtime and editor to Python.
- Palette catalogue served from PyPI, so the palette manager's Install tab
  can search for PyFlowRED node packages.
- Multiplayer: two open editors see each other's presence and cursors.
- Projects: git-backed flow storage, with the SSH key store that goes with
  it. Off unless `editorTheme.projects.enabled` is set and git is available.
- Benchmark flows and a load-test harness (`tools/benchflows.py`,
  `tools/loadtest.py`), plus the three defects they found: the HTTP Response
  node replaying an upstream response's headers, JSONata refusing to evaluate
  against an HTTP message, and the HTTP Request node ignoring its keep-alive
  setting.
- A native Prometheus endpoint at `<httpAdminRoot>metrics`: process, instance,
  per-node-type throughput, and backpressure as event loop lag, in-flight
  messages and the queue depth of the nodes that hold messages back. Flows can
  publish their own metrics through the ported `prometheus-metric-config` and
  `prometheus out` nodes, into the same registry.
- The wheel now ships the built editor. It was being excluded because the
  build output is git-ignored, so the package installed and served a blank
  page; the editor source, which is useless at runtime, was shipped instead.
  A build hook refuses to build a wheel without an editor.
- Flows can be kept on object storage. `flowStore` names a URL - GCS, S3,
  Azure, a directory - and obstore syncs to it: the store wins at start-up,
  the local file is pushed on every deploy, and the editor gains an "Object
  storage" menu to force either direction. Settings can now also come from a
  `[tool.pyred]` table in the working directory's `pyproject.toml` and from
  `PYRED_*` environment variables (renamed in 0.2.0).
- Secrets can be read at runtime from Google Secret Manager, or from a
  directory of files as Kubernetes mounts them. `${secret:NAME}` works in any
  node property - resolved when the node is built, so a broker or a Kafka
  client gets its credential at connect time and the flow file keeps the
  placeholder - and a `secret` node puts one on a message for the per-call
  case. Values are cached for `secrets.ttl`, so a rotation needs no rebuild.
- Kafka: a `kafka-broker` configuration node with `kafka in` and `kafka out`,
  the same shape as the MQTT nodes. On confluent-kafka, with any librdkafka
  setting reachable through a properties table. Values are JSON in both
  directions; a record that is not valid JSON raises an error rather than
  travelling on. `tools/kafka/compose.yml` brings up a broker to develop
  against.
- A container image, built in three stages with `uv`: Node builds the editor,
  uv resolves the environment, and the runtime image carries neither. Proxy,
  internal package index and internal npm registry are build arguments. Your
  own CA can be baked in or mounted, and reaches httpx, obstore, Python's ssl,
  certifi and librdkafka - the last of which ignores `SSL_CERT_FILE` and now
  takes its default `ssl.ca.location` from the container's bundle.
- Published on PyPI as **pyflowred**, because `pyred` there belongs to an
  unrelated project. At this version the import package and the command were
  still `pyred`; 0.2.0 renamed them to match.
- A second image. `Dockerfile` installs the released package with uv and
  carries no build tooling; `Dockerfile.source` is the previous one, which
  builds this checkout. Build arguments no longer leak into the runtime, and
  both images carry uv with a writable environment so the palette manager
  works.
