Docs / docs (push) Successful in 23s
Playwright Tests / test-playwright (1, 2) (push) Failing after 23s
Playwright Tests / test-playwright (2, 2) (push) Failing after 11s
pre-commit / pre-commit (push) Failing after 2m29s
Test Backend / test-backend (push) Failing after 2m40s
Compose Smoke Test / test-compose (push) Failing after 17s
Playwright Tests / merge-reports (push) Failing after 2m38s
217 lines
8.0 KiB
TOML
217 lines
8.0 KiB
TOML
[project]
|
|
name = "fluksio"
|
|
version = "0.1.5+dev"
|
|
description = "Node-based automation engine: flows, dashboards, batch runs"
|
|
readme = "README.md"
|
|
license = "AGPL-3.0-or-later"
|
|
license-files = ["LICENSE"]
|
|
requires-python = ">=3.12"
|
|
authors = [{ name = "Fluksio", email = "stroblme@posteo.de" }]
|
|
keywords = ["automation", "workflow", "dataflow", "experiment-tracking", "mlops"]
|
|
classifiers = [
|
|
"Development Status :: 3 - Alpha",
|
|
"Intended Audience :: Developers",
|
|
"Intended Audience :: Science/Research",
|
|
"Operating System :: MacOS",
|
|
"Operating System :: POSIX :: Linux",
|
|
"Programming Language :: Python :: 3",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Topic :: Home Automation",
|
|
"Topic :: Scientific/Engineering",
|
|
"Topic :: System :: Distributed Computing",
|
|
]
|
|
# Named because this code imports them. Four of them — python-multipart,
|
|
# email-validator, jinja2 and httpx — also arrive inside `fastapi[standard]`,
|
|
# so those lines look redundant and install nothing extra; they are here so a
|
|
# direct import does not rest on somebody else's extra keeping its contents.
|
|
dependencies = [
|
|
"fastapi[standard]<1.0.0,>=0.114.2",
|
|
"pydantic>2.0",
|
|
"pydantic-settings<3.0.0,>=2.2.1",
|
|
"sqlmodel<1.0.0,>=0.0.21",
|
|
"alembic<2.0.0,>=1.12.1",
|
|
"httpx<1.0.0,>=0.25.1",
|
|
# `Form(...)` on the OAuth token endpoint, which fastapi refuses to build
|
|
# the route without.
|
|
"python-multipart<1.0.0,>=0.0.7",
|
|
# `EmailStr` on the user model, so it is read on every start — an address
|
|
# is what a user is identified by, whether or not mail is ever sent. The
|
|
# sending itself is the `server` extra.
|
|
"email-validator<3.0.0.0,>=2.1.0.post1",
|
|
# Only the mail templates use it, and only after `send_email` — but it
|
|
# comes with `fastapi[standard]` either way, so an extra would move a line
|
|
# rather than a package.
|
|
"jinja2<4.0.0,>=3.1.4",
|
|
# Sessions, the secrets file, and the keypair an agent's token is signed
|
|
# with.
|
|
"pyjwt<3.0.0,>=2.8.0",
|
|
"pwdlib[argon2,bcrypt]>=0.3.0",
|
|
"cryptography>=44.0.0",
|
|
# The state store and the work queue, and what a panel's config is read
|
|
# through.
|
|
"redis>=7.1.0",
|
|
# Every message costs a round trip's worth of encode and decode — state,
|
|
# the journal, the worker pipe. Engine-side only: `fluksio-worker` is
|
|
# copied onto other people's machines and stays dependency-free.
|
|
"orjson>=3.10",
|
|
# The `mlp` node, which is registered at boot. Kept out of the extras
|
|
# because a data-science environment has it already.
|
|
"numpy>=2.2.6",
|
|
# The `inject` node's cron. Imported where it is used, behind a message
|
|
# that cannot fire while this line is here.
|
|
"croniter>=1.3.0",
|
|
"mcp>=1.29,<2",
|
|
"fluksio-worker>=0.1,<0.2",
|
|
# The Modules screen installs node code's packages with it, into a venv of
|
|
# the user's own. Present in the image; a pip install would otherwise have
|
|
# to find one on PATH, and quietly fall back to the engine's interpreter.
|
|
"uv>=0.5",
|
|
# `fluksio status` draws with it, and textual is built on it — named
|
|
# anyway, because a command that imports it should say so.
|
|
"rich>=13",
|
|
# `fluksio serve` opens a dashboard with it at a terminal.
|
|
"textual>=1.0",
|
|
# That dashboard subscribes to the engine's event bus over the same socket
|
|
# the browser uses. It arrives under `fastapi[standard]` either way, and is
|
|
# named here because this code imports it.
|
|
"websockets>=13",
|
|
# The encrypted-payload half of web push (RFC 8291). It brings only
|
|
# cryptography, which is already here. `pywebpush` would do the signing and
|
|
# the request too, at the cost of `requests` *and* `aiohttp` — two HTTP
|
|
# stacks beside httpx, on a machine that may be a Raspberry Pi.
|
|
"http-ece>=1.2",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
# `fluksio export --format parquet` converts the exported rows with it. An
|
|
# extra rather than a dependency: csv and jsonl need nothing, and pyarrow is
|
|
# tens of megabytes for whoever wants dtypes kept.
|
|
parquet = ["pyarrow>=17"]
|
|
# What a deployment has and a laptop does not: the device connectors, outbound
|
|
# mail and error reporting. The engine, the CLI and every python node work
|
|
# without them — `pip install fluksio` in a data-science environment is the
|
|
# case this exists for, and lxml and the aiohttp stack are most of its wait.
|
|
# Each import is guarded and names this extra. The image installs it.
|
|
server = [
|
|
"emails<1.0,>=0.6",
|
|
"sentry-sdk[fastapi]>=2.20.0",
|
|
"aiomqtt>=2.0.0",
|
|
"influxdb-client[async]>=1.40.0",
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://fluksio.com"
|
|
Documentation = "https://docs.fluksio.com"
|
|
"Getting started" = "https://docs.fluksio.com/getting-started/data-science/"
|
|
|
|
[project.scripts]
|
|
fluksio = "fluksio.cli:main"
|
|
|
|
[tool.uv.sources]
|
|
fluksio-worker = { workspace = true }
|
|
|
|
[dependency-groups]
|
|
dev = [
|
|
"pytest<8.0.0,>=7.4.3",
|
|
"mypy<2.0.0,>=1.8.0",
|
|
"ruff<1.0.0,>=0.2.2",
|
|
"prek>=0.2.24,<1.0.0",
|
|
"coverage<8.0.0,>=7.4.3",
|
|
]
|
|
|
|
[tool.hatch.build.targets.wheel]
|
|
packages = ["fluksio"]
|
|
|
|
# Named rather than excluded: this directory also holds a working tree's
|
|
# runtime data — `flow-data/` with the user venv in it — which is not source.
|
|
[tool.hatch.build.targets.sdist]
|
|
include = ["fluksio", "tests", "scripts", "alembic.ini", "pyproject.toml", "README.md"]
|
|
|
|
[build-system]
|
|
requires = ["hatchling"]
|
|
build-backend = "hatchling.build"
|
|
|
|
[tool.mypy]
|
|
strict = true
|
|
exclude = ["venv", ".venv", "alembic"]
|
|
# influxdb_client's Point builder carries no annotations; calling it is not a
|
|
# reason to stop checking the caller (fluksio/flow/nodes/influx.py).
|
|
untyped_calls_exclude = ["influxdb_client"]
|
|
|
|
# Every module is checked strictly. influxdb_client is typed but re-exports its
|
|
# names implicitly, which strict mode refuses to follow. (croniter, the other
|
|
# untyped dependency, is ignored at its two import sites.)
|
|
[[tool.mypy.overrides]]
|
|
module = ["influxdb_client"]
|
|
implicit_reexport = true
|
|
|
|
# The parquet extra. Not installed here, and the import that uses it is inside
|
|
# the try/except that says so.
|
|
[[tool.mypy.overrides]]
|
|
module = ["pyarrow", "pyarrow.*"]
|
|
ignore_missing_imports = true
|
|
|
|
# The web push payload encoder carries no annotations.
|
|
[[tool.mypy.overrides]]
|
|
module = ["http_ece"]
|
|
ignore_missing_imports = true
|
|
|
|
|
|
[tool.ruff]
|
|
target-version = "py312"
|
|
exclude = ["alembic"]
|
|
|
|
[tool.ruff.lint]
|
|
select = [
|
|
"E", # pycodestyle errors
|
|
"W", # pycodestyle warnings
|
|
"F", # pyflakes
|
|
"I", # isort
|
|
"B", # flake8-bugbear
|
|
"C4", # flake8-comprehensions
|
|
"UP", # pyupgrade
|
|
"ARG001", # unused arguments in functions
|
|
"T201", # print statements are not allowed
|
|
]
|
|
ignore = [
|
|
"E501", # line too long, handled by black
|
|
"B008", # do not perform function calls in argument defaults
|
|
"W191", # indentation contains tabs
|
|
"B904", # Allow raising exceptions without from e, for HTTPException
|
|
]
|
|
|
|
[tool.ruff.lint.per-file-ignores]
|
|
# The node API's stubs carry the real signatures and raise; unused arguments
|
|
# are what a stub is.
|
|
"fluksio/__init__.py" = ["ARG001"]
|
|
# It talks to whoever ran it; that is what a command line is.
|
|
"fluksio/cli.py" = ["T201"]
|
|
"fluksio/sdk/cli.py" = ["T201"]
|
|
# What it prints is the line left in the terminal after the dashboard closes.
|
|
"fluksio/tui/app.py" = ["T201"]
|
|
# Node functions take `params` whether or not they use it — that is the
|
|
# contract the engine calls them with.
|
|
"fluksio/flow/nodes.py" = ["ARG001", "ARG002"]
|
|
"tests/flow/*" = ["ARG001"]
|
|
# Node functions declared for a test take the ports they declare, used or not.
|
|
"tests/sdk/*" = ["ARG001"]
|
|
# Printing is what this one is about: node code is user code, and `print` is
|
|
# how it says things.
|
|
"tests/flow/test_logs.py" = ["ARG001", "T201"]
|
|
|
|
[tool.ruff.lint.pyupgrade]
|
|
# Preserve types, even if a file imports `from __future__ import annotations`.
|
|
keep-runtime-typing = true
|
|
|
|
[tool.coverage.run]
|
|
source = ["fluksio"]
|
|
dynamic_context = "test_function"
|
|
|
|
[tool.coverage.report]
|
|
show_missing = true
|
|
sort = "-Cover"
|
|
|
|
[tool.coverage.html]
|
|
show_contexts = true
|