I have a flow where some of my steps has the @kube...
# ask-metaflow
t
I have a flow where some of my steps has the @kubernetes decorator to specify disk, memory and taints. But sometimes when I debug I just want to run it locally. I find myself having to comment out and comment back in all the @kubernetes decorators. What is the recommended way to solve the simple local/kubernetes switching? (Ps. I don’t wan’t to use
--with kubernetes
since this affects all steps.)
1
m
Not sure on the official best practice, but this issue discusses this point. The last post shows how I currently handle this within our company. Maybe it is helpful to you.
among us party 1
❤️ 1
c
We have solved this issue by creating a custom step decorator, that works in the inverse way: it checks to see whether the kubernetes decorator is attached to a step, and if so modifies it to add the required attributes: in step_init
Copy code
for deco in decos:
    if deco.name != "kubernetes":
        continue

    deco.attributes["gpu"] = self.attributes["gpu"]
    deco.attributes["tolerations"] = self.attributes["tolerations"]
    [...]
Has the advantage of retaining the default behaviour of attaching
@kubernetes
, though I can see that the solution by @mammoth-rainbow-82717 is more elegant.
🙏 1
t
Some good ideas there! Thanks 🙏
Okay guys.. Here is what I ended up with.
Copy code
# previously in our code
@kubernetes(disk=5 * 1024, tmpfs="/something")

# now in our code
@kubernetes_with_toggle(disk=5 * 1024, tmpfs="/something")
Using this custom decorator will allow you to run eg.
python flow.py run --without kubernetes
To achieve this,
kubernetes_with_toggle
is defined like so:
Copy code
class kubernetes_with_toggle:
    arg_pairs = list(zip(sys.argv, sys.argv[1:]))
    try:
        idx = arg_pairs.index(("--without", "kubernetes"))
    except ValueError:
        run_with_k8s = True
    else:
        run_with_k8s = False
        del sys.argv[idx]  # "--without"
        del sys.argv[idx]  # "kubernetes"

    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs

    def __call__(self, func):
        if self.run_with_k8s:
            return kubernetes(*self.args, **self.kwargs)(func)
        return func
Another idea could be to define your own custom
@adaptable_resources
decorator which allows for arguments like
tmpfs
, and the having it morph into a
kubernetes
decorator at runtime if
"argo-workflow"
or
"kubernetes"
is found in
sys.argv
.