<@ULVA73B9P> how can I make a dropdown with str pa...
# ask-marvin
f
@Marvin how can I make a dropdown with str parameters list in the Prefect UI flow launch popup?
m
thought for 235.3 seconds
Yes — in Prefect 2 (Cloud), the Launch Run modal will render a dropdown when a parameter’s type is an enum (typing.Literal or enum.Enum). Declare your flow parameters with one of the following patterns: Option 1: typing.Literal (simple and pythonic)
Copy code
from 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)
Copy code
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.
f
@Marvin and with prefect 3?
m
thought for 273.5 seconds
Got it — if you’re asking “how do I do this in Prefect 3?”, here’s the quick cheat sheet. If you meant a different part of your setup (workers, schedules, storage, etc.), let me know what you want to translate to 3.x and I’ll tailor it. Key changes in Prefect 3.x - Removed:
Deployment.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
Copy 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)
Copy code
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)
Copy code
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:
Copy code
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:
Copy code
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:
Copy code
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)
I’ll generate a ready-to-run setup that uses your Poetry lock.