"""The Fluksio engine, and the decorators that declare flows in your own code. Two audiences, one import name. In a research repository, ``from fluksio import Port, node, Flow`` is the authoring API: it says which of your existing functions are nodes and which nodes make up a flow, and ``fluksio sync`` uploads what it finds. Those names come from :mod:`fluksio.sdk`, which imports nothing but the standard library. Inside a node, ``import fluksio`` is not this package at all: the worker installs a reporter of its own under that name before any node code runs, so what a node gets is :mod:`fluksio_worker.worker_main`'s ``emit`` and ``save_artifact`` — and inert copies of the decorators, since a module the node imports may well declare them at its top. The stubs below stand in the same place everywhere else, and say so rather than failing as a missing attribute. Nothing is imported from the rest of the package here. Every ``from fluksio.x import y`` in the engine passes through this module, and an import cycle or a second of start-up cost would both begin here. """ import logging from importlib.metadata import PackageNotFoundError from importlib.metadata import version as _version from typing import Any from fluksio.sdk import Flow, Port, node, use try: __version__ = _version("fluksio") except PackageNotFoundError: # pragma: no cover - a checkout that was never installed __version__ = "0.0.0+unknown" __all__ = [ "Flow", "Port", "emit", "load_artifact", "node", "save_artifact", "use", ] logger = logging.getLogger(__name__) _OUTSIDE = ( "fluksio.{name}() only works inside a node: the worker running it installs " "the real one. There is nothing to {verb} out here." ) def emit(**ports: Any) -> None: """Publish values on a node's declared output ports, mid-run. Outside a node there is nowhere to publish to, and this does nothing on purpose: a node function called directly — in a test, in a notebook, under a debugger — is ordinary Python, and having it die on a progress report would defeat the point of the code staying yours. """ logger.debug("fluksio.emit(%s) outside a node", ", ".join(ports)) def save_artifact( source: Any, name: str = "", media_type: str = "application/octet-stream", volatile: bool = False, ) -> dict[str, Any]: """Put bytes in the artifact store and return a reference to them.""" raise RuntimeError(_OUTSIDE.format(name="save_artifact", verb="save to")) def load_artifact(ref: dict[str, Any]) -> str: """Fetch what an artifact reference points at, and return a path to it.""" raise RuntimeError(_OUTSIDE.format(name="load_artifact", verb="load from"))