Florent VanDeMoortele
12/18/2025, 11:03 AMMarvin
12/18/2025, 11:03 AMMarvin
12/18/2025, 11:07 AMfrom typing import Literal
from prefect import flow
@flow
def my_flow(
environment: Literal["dev", "staging", "prod"] = "dev",
log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR"] = "INFO",
):
print(f"{environment=} {log_level=}")
- The UI sees the Literal values and shows a select with those options.
- The default you set is preselected.
Option 2: enum.Enum (handy if you want named members)
from enum import Enum
from prefect import flow
class Environment(Enum):
DEV = "dev"
STAGING = "staging"
PROD = "prod"
@flow
def my_flow(environment: Environment = Environment.DEV):
print(f"{environment.value=}")
- The UI renders a dropdown using the enum values (e.g., "dev", "staging", "prod").
Notes and tips:
- Optional dropdowns: you can use Optional with a default of None, e.g. Optional[Literal["a","b"]] = None. The UI will allow leaving it blank (None).
- Ordering: parameters appear in the UI in your function’s argument order.
- Validation: passing a value not in the enum will be rejected at run creation time.
- Dynamic dropdowns (fetching options at runtime) are not supported in Prefect 2; the schema used by the UI is static from your flow signature at deployment time. Common workaround: include a sentinel like "AUTO" in your Literal/Enum and compute the real value at runtime.
If you want, share your current parameter signature and I can confirm exactly how it will render in the Launch modal.Florent VanDeMoortele
12/24/2025, 2:26 PMMarvin
12/24/2025, 2:26 PMMarvin
12/24/2025, 2:30 PMDeployment.build_from_flow() and prefect deployment build
- Use either:
- Python: flow.deploy() or flow.from_source(...).deploy(...)
- CLI + YAML: prefect.yaml + prefect deploy
- Storage blocks for code are replaced by from_source(...) (Git, GCS, S3, local, etc.)
Minimal examples
- Deploy from local code
from prefect import flow
@flow
def my_flow():
...
if __name__ == "__main__":
my_flow.deploy(
name="my-deployment",
work_pool_name="my-pool",
image="<http://gcr.io/your-proj/prefect:latest|gcr.io/your-proj/prefect:latest>" # recommended for GCP
)
- Deploy from GitHub (public or auth via GitHub App/token)
from prefect import flow
if __name__ == "__main__":
flow.from_source(
source="<https://github.com/owner/repo.git>",
entrypoint="flows/hello.py:my_flow" # path/to/file.py:flow_func
).deploy(
name="my-gh-deployment",
work_pool_name="my-pool",
)
- CLI with YAML (interactive init, then deploy)
prefect init
prefect deploy -n my-deployment
Poetry-managed dependencies (pyproject.toml + poetry.lock)
- Best practice: bake dependencies into a Docker image (so workers don’t rely on runtime pip installs). With Poetry, either:
- Use your own Dockerfile and point the deployment to the built image
- Or use prefect.yaml build steps (docker) and provide a Dockerfile that uses Poetry
Example Dockerfile that respects Poetry lock:
FROM python:3.12-slim
# System deps for Poetry
RUN apt-get update && apt-get install -y curl build-essential git && rm -rf /var/lib/apt/lists/*
# Install Poetry
ENV POETRY_VERSION=1.8.3
RUN curl -sSL <https://install.python-poetry.org> | python3 - && \
ln -s /root/.local/bin/poetry /usr/local/bin/poetry
WORKDIR /app
# Copy only dependency files first for better caching
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root
# Now copy the rest of your code
COPY . .
# Optionally install your package if it has a project name
# RUN poetry install --no-interaction --no-ansi
Then reference the image in your deployment:
my_flow.deploy(
name="my-deployment",
work_pool_name="gke-pool", # if using Kubernetes on GKE
image="<http://gcr.io/your-proj/prefect:latest|gcr.io/your-proj/prefect:latest>",
)
GCP-focused tips
- Work pools: most common on GCP are Kubernetes (GKE) or Docker on a GCE VM. Build and push your Poetry image to GCR/Artifact Registry and set it on the deployment.
- Remote code: you can reference GitHub or GCS. Example for GCS:
flow.from_source(
source="<gs://my-bucket/my-project>",
entrypoint="flows/hello.py:my_flow",
).deploy(name="gcs-deployment", work_pool_name="gke-pool")
Docs and references
- Deploy via Python (flow.deploy, from_source): Deploy with Python
- Define with YAML (prefect.yaml): prefect.yaml guide
- Create deployments overview: Create deployments
- Store flow code (Git/GCS/etc.): Store flow code
- CLI reference (deploy): CLI: deploy
Want me to draft a prefect.yaml and Dockerfile tailored to your repo (GitHub or GCS), entrypoint, and your GCP work pool (GKE or Docker)? If you share:
- repo URL or GCS path
- flow entrypoint
- work pool name/type
- target image name (GCR/Artifact Registry)Marvin
12/24/2025, 2:30 PM