Skip to main content
Version: 12 - TBD

Shared Python Modules

A Python module is a workspace resource that holds reusable Python code — functions, classes and constants — which your flow scripts import with a plain import. Use it to share helper code across many flows in a bundle instead of copying the same snippet into every flow script.

This is different from the pre-installed third-party Python modules: those are libraries shipped with the engine, while a Python module is code you author in your own workspace.

Authoring a Python module

A Python module resource has a name and a script. The script is an ordinary Python source file: define functions, classes and module-level constants at the top level.

The module's name is its import name, so it must be a valid Python identifier — letters, digits and underscores, not starting with a digit. Use underscores, not hyphens.

For example, a module named string_helpers with this script:

GREETING = "hello"


def greet(name):
return f"{GREETING}, {name}!"


def add(a, b):
return a + b

When your workspace is synced to a bundle git repository, a Python module is stored as a file pair:

string_helpers.python_module.yaml
string_helpers.python_module-script.py

The .yaml file holds the resource metadata and the -script.py file holds the module source, the same file-pair convention used for flows.

Importing a module from a flow script

Import a Python module by its name and call its functions inline — there is no extra execution hop:

import string_helpers


def handler(system, this, inputs):
message = string_helpers.greet("world")
total = string_helpers.add(2, 3)
this.save(message=f"{message} ({total})")

Only the modules a flow imports (and the modules those import, see below) are made available to it, so importing an unknown name raises a clean ModuleNotFoundError.

Modules importing other modules

A Python module may import another Python module. The whole transitive set of imported modules is resolved and made available together:

# module: geometry_base
BASE = 10


def double(value):
return value * 2
# module: geometry
import geometry_base


def scaled(value):
return geometry_base.double(value) + geometry_base.BASE

A flow that imports only geometry can call geometry.scaled(...); geometry_base is pulled in automatically.

Interacting with the calling execution

Module code has no implicit access to the running flow. To let a helper interact with the execution, pass this to it explicitly. Calls such as this.save(...) then affect the calling flow's execution:

# module: progress_helpers
def step(this, label):
this.save(message=f"step: {label}")
import progress_helpers


def handler(system, this, inputs):
progress_helpers.step(this, "starting")
# ... work ...
progress_helpers.step(this, "done")

This keeps a helper's progress messages visible on the flow that called it.

State is per execution

Module-level state lives for the duration of a single execution. Mutations to a module global persist while that execution runs, and each new execution starts from the module's initial state — state is never shared between executions.

# module: counter
_calls = []


def record(tag):
_calls.append(tag)
return list(_calls)

Within one execution, repeated counter.record(...) calls accumulate; a separate execution sees an empty _calls again.

caution

Do not use module globals to share data between executions. For data that must outlive or cross executions, use settings, records, or files.

Module references held in local variables also survive a flow savepoint and resume — for example across a this.sleep(...) — so you can keep using an imported function after the flow pauses and continues.

Python modules are libraries, not flows

A Python module is imported by flows rather than executed on its own: it has no handler entry point and is not an execution target. Put runnable logic in a flow, and shared helper code in a Python module that the flow imports.

note

Contact us at info@cloudomation.com with any questions about shared Python modules.