Bob Peers
12/29/2025, 11:54 AMMarvin
12/29/2025, 11:54 AMMarvin
12/29/2025, 11:57 AMimport os
import knime
from prefect import task, flow, get_run_logger
from prefect.schedules import Cron
FLOW_NAME: str = "Centra 08 Stock"
DEPLOYMENT: str = "Retail"
WORK_POOL_NAME: str = "local" # change to your work pool name
KNIME_BASE = "F:/Analytics/Workflows_knime/NN07/EDI/Madden Analytics/"
KNIME_FLOWS = ["Centa 08 Stock Update"]
@task(retries=2, retry_delay_seconds=15, task_run_name="{name}")
def run_knime(workflow: str, name: str):
with knime.Workflow(workflow) as wf:
wf.execute()
@flow(name=FLOW_NAME)
def knime_workflows():
logger = get_run_logger()
for f in KNIME_FLOWS:
knime_flow = os.path.join(KNIME_BASE, f)
<http://logger.info|logger.info>(f"Running {knime_flow}")
run_knime(knime_flow, name=f)
if __name__ == "__main__":
# Prefect 3.x deployment (replaces Deployment.build_from_flow(...).apply())
knime_workflows.deploy(
name=DEPLOYMENT,
work_pool_name=WORK_POOL_NAME, # must exist
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
build=False, # do not build/push an image; run local code
)
How to run it
1) Create a local process work pool (once)
prefect work-pool create "local" --type process
2) Start a worker for that pool (keep this running)
prefect worker start --pool "local"
3) Register the deployment (runs the script)
python your_script.py
Notes
- In Prefect 3.x, Deployment.build_from_flow and prefect deployment build were removed. Use flow.deploy(...).
- CronSchedule moved to a new API—use prefect.schedules.Cron(...). Passing cron="..." is supported, but use Cron(...) if you need a timezone.
- Your @task options (retries, retry_delay_seconds, task_run_name) and get_run_logger() work the same in 3.x.
Optional: local scheduler without a worker
If you prefer to run on a local scheduler (no worker), swap the deploy call for serve:
if __name__ == "__main__":
knime_workflows.serve(
name=DEPLOYMENT,
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
)
If you want me to wire this to a Docker/Kubernetes work pool instead, tell me your target environment and I’ll adjust the code and commands.Bob Peers
12/29/2025, 12:06 PMMarvin
12/29/2025, 12:06 PMMarvin
12/29/2025, 12:07 PMprefect work-pool inspect "default"
2) If it’s NOT type “process”, create a process pool and use it
prefect work-pool create "windows-process" --type process
prefect worker start --pool "windows-process"
Then deploy with no image (local code), keeping your schedule:
knime_workflows.deploy(
name=DEPLOYMENT,
work_pool_name="windows-process",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
build=False,
)
Alternative if you must use the existing “default” pool (Docker/K8s/ECS):
- Provide an image (must include Python deps + KNIME if needed) and let Prefect build/push it:
knime_workflows.deploy(
name=DEPLOYMENT,
work_pool_name="default",
image="<http://ghcr.io/your-org/knime-runner:latest|ghcr.io/your-org/knime-runner:latest>",
build=True,
push=True,
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
)
- Or provide a remote code location (e.g., Git repo) so the worker can fetch code:
flow.from_source(
source="<https://github.com/owner/repo.git>",
entrypoint="path/to/script.py:knime_workflows",
).deploy(
name=DEPLOYMENT,
work_pool_name="default",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
# still ensure the worker image/environment has your dependencies
)
Given your Windows KNIME path, I strongly recommend the process pool route on that machine.
If you share the output of:
prefect work-pool inspect "default"
I can tailor the exact deploy snippet for your setup.Bob Peers
12/29/2025, 12:16 PMMarvin
12/29/2025, 12:16 PMMarvin
12/29/2025, 12:19 PMfrom prefect import flow
from prefect.schedules import Cron
if __name__ == "__main__":
flow.from_source(
source="<https://github.com/owner/repo.git>",
entrypoint="path/to/your_script.py:knime_workflows",
).deploy(
name="Retail",
work_pool_name="default",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
)
Then run your worker:
prefect worker start --pool "default"
Option B — Use a local path as the source (works if the worker runs on the same machine and can see that path)
from pathlib import Path
from prefect import flow
from prefect.schedules import Cron
if __name__ == "__main__":
flow.from_source(
source=str(Path(__file__).parent), # folder containing this script (accessible to the worker)
entrypoint=f"{Path(__file__).name}:knime_workflows",
).deploy(
name="Retail",
work_pool_name="default",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
)
Note: The worker must be on that same machine and have the same filesystem path.
Option C — Use a module path (requires your code be importable on the worker)
Install your project as a package on the worker (pip install -e .), then:
from prefect.types.entrypoint import EntrypointType
from prefect.schedules import Cron
knime_workflows.deploy(
name="Retail",
work_pool_name="default",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
entrypoint_type=EntrypointType.MODULE_PATH, # worker will import your module
)
Optional: local-only scheduling
If you’d rather not involve the server for scheduling (runs on your machine only), use serve:
knime_workflows.serve(
name="Retail",
schedule=Cron("40 2 * * 1-6", timezone="Europe/Copenhagen"),
)
Docs: Run flows in local processes
Given your KNIME path is on Windows, Option A (Git) or Option B (local path the worker can access) are the most straightforward. Which approach would you like to use? I can tailor the exact snippet to your repo/path.