<@ULVA73B9P> If we register flows without a deploy...
# ask-marvin
s
@Marvin If we register flows without a deployment (say using an infrastructure decorator instead), how do we actually register it on the UI? It used to be done with the Python deploy-function.
m
thought for 112.6 seconds
In Prefect 3, flows are not something you “register” in the UI ahead of time unless you create a deployment. What happens without a deployment - If you just define a flow and run it directly, Prefect will automatically create the flow record when the first flow run is created. - So yes, the flow can appear in the UI after it has been run at least once. - But without a deployment, you won’t get the usual deployment-backed UI behavior like: - scheduling - manual “Run” from the UI/API as a deployment - event triggers - worker/work-pool based orchestration So the short version is: No deployment → flow shows up only once it has been run, but it is not registered as a deployment object in the UI. Deployment → flow is visible as a deployable/runnable object in the UI. If you want something to be runnable/manageable from the UI before its first run, you should create a deployment. In Prefect 3.x, the current Python options are: -
my_flow.serve(...)
-
my_flow.deploy(...)
-
flow.from_source(...).deploy(...)
Not the old 2.x deployment builder APIs. Example:
Copy code
python
from prefect import flow

@flow
def my_flow():
    print("hello")

if __name__ == "__main__":
    my_flow.deploy(
        name="my-deployment",
        work_pool_name="my-pool",
    )
If you don’t want a deployment and just want observability, you can run the flow normally and it’ll appear in the UI once executed. Relevant docs: - Deploy flows - Serve flows locally - Deployments concept If you want, I can also explain the practical difference between just running a flow,
serve()
, and
deploy()
in one table.
s
@Marvin I meant submitting flows to dynamic infrastructure. How does that work? Can we not run them from the UI? (Copy pasted from docs:
Copy code
from prefect import flow
from prefect_kubernetes.decorators import kubernetes


@kubernetes(
    work_pool="my-kubernetes-pool",
    namespace="custom-namespace"
)
@flow
def custom_namespace_flow():
    pass
)
m
thought for 131.0 seconds
Ah — yes, that’s a different feature. What you pasted is not a deployment-based pattern. The
@kubernetes(...)
decorator is for submitting a flow directly to dynamic infrastructure without creating a deployment. So the answer is: No, those flows are not run from the UI unless you also create a deployment. How it works: -
@kubernetes(...)
wraps the flow as an infrastructure-bound flow - when you call the flow in Python, Prefect submits that run to the specified work pool / infrastructure - Prefect tracks the flow run in the UI - but it does not create a deployment object So you get: - yes: observable flow runs in the UI - no: deployment page / schedule / “run from UI” controls / automations based on a deployment Using your example:
Copy code
python
from prefect import flow
from prefect_kubernetes.decorators import kubernetes


@kubernetes(
    work_pool="my-kubernetes-pool",
    namespace="custom-namespace"
)
@flow
def custom_namespace_flow():
    pass
This means: - when
custom_namespace_flow()
is called from Python, Prefect submits it to Kubernetes using that work pool - the
namespace
is passed as a job-variable override - the run will be visible in Prefect - but you still have not created a deployment So if your question is: “Can users click Run in the UI for this flow?” Then the answer is not by default. For that, you need a deployment. A useful mental model: Infrastructure decorator: - “run this flow on this infra when my Python code calls it” Deployment: - “register this flow as a managed runnable thing in Prefect so the UI/API/schedules/automations can launch it” If you want both dynamic infra and UI-triggerable runs, use a deployment on a work pool instead. Relevant docs: - Submit flows directly to dynamic infrastructure - Deployments - Deploy flows Rule of thumb - use infrastructure decorators for programmatic ad hoc submission - use deployments for UI/API-triggered, scheduled, or production-managed execution If you want, I can show the equivalent deployment-based Kubernetes setup for that exact example so you can compare them side by side.
s
@Marvin What are the usecases? If I run the flow from my machine - it is ran on my machine, no?
m
thought for 146.4 seconds
Yes — the flow call starts on your machine, but the flow body runs remotely. That’s the key distinction. With an infrastructure-bound flow like `@kubernetes(...)`:
Copy code
python
@kubernetes(work_pool="my-kubernetes-pool")
@flow
def my_flow():
    ...
when you do:
Copy code
python
my_flow()
your machine is used to submit the run, but the actual flow execution happens on Kubernetes. So, more precisely: Runs locally - creating the flow run - packaging/serializing the flow code - contacting Prefect API - submitting work to infrastructure - waiting/monitoring the run in some modes Runs remotely - the actual flow function body - tasks inside that flow - anything your flow does at runtime So no, this pattern is not “just running on your laptop”. There are basically 3 use cases/patterns: 1.
my_flow()
- submits the flow to remote infra - blocks until it finishes - useful when you want “run this on K8s, but I’m launching it from my machine/script” 2.
my_flow.submit()
- also submits to remote infra - returns immediately with a future - useful for programmatically launching many remote runs from another flow/app 3.
my_flow.submit_to_work_pool()
- submits a run for a worker to pick up - best when your machine doesn’t have direct access to the infrastructure - useful in CI/CD, control-plane style orchestration, or centralized worker setups So the main use cases are: Ad hoc remote execution - “I’m on my laptop, but this job needs K8s resources / a GPU / big memory” Programmatic orchestration - one flow or app dynamically launches other flows onto different infrastructure Infra selection per flow - e.g. CPU jobs on one pool, GPU jobs on another, special namespace/node-pool for certain workloads No deployment ceremony - useful when you want remote execution without creating a deployment for every flow Important caveat: For
my_flow()
and
my_flow.submit()
, your machine usually still needs access/credentials to submit to that infrastructure. So: - your code does not execute locally - but your machine may still need permission to launch the remote job If you want the submission to also be decoupled from your machine, that’s when
submit_to_work_pool()
is more useful: a running worker handles the infra side. A simple mental model: Deployment = “Prefect UI/API can launch this” Infrastructure decorator = “my Python code can launch this remotely” So if your goal is: - run from UI → use a deployment - run remotely from code → infrastructure decorator is a good fit Docs: - Submit flows directly to dynamic infrastructure - Deployments If you want, I can give you a concrete end-to-end example showing what happens step by step for
my_flow()
,
my_flow.submit()
, and
my_flow.submit_to_work_pool()
.