Skip to content

feat(backend): Support KALE_KFP_NAMESPACE for configurable KFP server namespace#875

Open
harshhh817 wants to merge 3 commits into
kubeflow:mainfrom
harshhh817:feat/798-kale-kfp-namespace
Open

feat(backend): Support KALE_KFP_NAMESPACE for configurable KFP server namespace#875
harshhh817 wants to merge 3 commits into
kubeflow:mainfrom
harshhh817:feat/798-kale-kfp-namespace

Conversation

@harshhh817

@harshhh817 harshhh817 commented Jul 10, 2026

Copy link
Copy Markdown

What this does

Adds support for a KALE_KFP_NAMESPACE environment variable so the Kubernetes namespace used for KFP API operations is configurable without hardcoding it in Kale's server config or asking every user to hand-edit kfp_server_config.json.

Closes #798

Why

KFP is not installed in the same namespace across environments (kubeflow, kubeflow-pipelines, or custom). With the namespace hardcoded, pipeline upload/list/run operations target the wrong namespace and users hit 404s, permission errors, or empty experiment lists even when host and auth are correct. An env var is much easier to standardize fleet-wide (via PodDefault, deployment env, or CI secrets) than baking a per-cluster config file.

Changes

  • kale/config/kfp_server_config.py
    • Added a single canonical default DEFAULT_NAMESPACE and a get_default_namespace() helper that reads KALE_KFP_NAMESPACE.
    • Changed the namespace Field default to None so load_config() can distinguish "user didn't set a namespace" from "user explicitly chose the default", then resolves it via _apply_default_namespace().
  • kale/common/kfp_client_factory.py
    • Removed the duplicate hardcoded "kubeflow" fallback. load_config() now returns an already-resolved namespace; an explicit namespace= argument still wins.
  • kale/tests/unit_tests/test_kfp_server_config.py
    • Added tests for: unset env (default), env override, config-file override, config file without namespace falling back to the env var, and explicit-parameter override.

Resolution order (highest priority first)

  1. explicit namespace= argument to get_kfp_client()
  2. "namespace" in the JSON config file (KALE_CONFIG_PATH)
  3. KALE_KFP_NAMESPACE environment variable
  4. canonical in-code default (DEFAULT_NAMESPACE)

This mirrors how Kale already configures paths (KALE_CONFIG_PATH).

Testing

uv run pytest kale/tests/unit_tests/test_kfp_server_config.py -q
# 32 passed (24 existing + 8 new)
uv run ruff check   # clean

Note

The issue mentions some branches default to kubeflow-pipelines, but main currently defaults to kubeflow, so I kept kubeflow as the canonical default to avoid changing existing behavior. Happy to switch the default if maintainers prefer.

The KFP client namespace was hardcoded in two places: the KFPServerConfig
Field default and a fallback in get_kfp_client(). This made multi-cluster
deployments painful, since KFP lives in different namespaces across clusters
(kubeflow, kubeflow-pipelines, or custom) and every user had to hand-edit
their config file.

Introduce a single canonical default (DEFAULT_NAMESPACE) plus a
get_default_namespace() helper that reads the KALE_KFP_NAMESPACE environment
variable. load_config() now resolves the namespace with this precedence
(highest first): explicit namespace= argument > JSON config file >
KALE_KFP_NAMESPACE env var > canonical in-code default. The duplicate
hardcoded fallback in kfp_client_factory.py is removed.

Adds unit tests for unset env (default), env override, config-file override,
config file without namespace falling back to env, and explicit-parameter
override.

Closes kubeflow#798

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Harsh Gupta <harshgupta93198@gmail.com>
@harshhh817
harshhh817 force-pushed the feat/798-kale-kfp-namespace branch from fdd0a4c to 84e5a12 Compare July 13, 2026 05:27

@ada333 ada333 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @harshhh817 from quick look the code looks good - please also add the env var to documentation (https://github.com/kubeflow/kale/blob/main/docs/source/user-guide/running-pipelines.md?plain=1#L104)

Signed-off-by: Harsh Gupta <harshgupta93198@gmail.com>
@harshhh817

Copy link
Copy Markdown
Author

Thanks for the review @ada333! Added KALE_KFP_NAMESPACE to the environment variables table in running-pipelines.md.

@ada333 ada333 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - I tried setting up the env var and running Kale to see if the target namespace changes, thanks for working on this @harshhh817

@google-oss-prow google-oss-prow Bot added the lgtm label Jul 15, 2026

@jesuino jesuino left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello,

The changes looks good and it seems to work well. I have a possible suggestion to avoid code duplication, would you please check it?

Thanks!

Comment thread kale/config/kfp_server_config.py Outdated
if not os.path.exists(config_path):
log.debug("No KFP server config found at %s, using defaults", config_path)
return KFPServerConfig()
return _apply_default_namespace(KFPServerConfig())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see multiple calls to this method, could this be done in the _postprocess method? learn more about it in kale/config/config.py:

    Validators are useful for single-field checks. To performs post
    initialization/validation checks, over multiple fields, or postprocess the
    validated fields, override the `_validate` and `_postprocess` functions,
    respectively.

Here's a suggested solution (not tested):

    def _postprocess(self):
        """Fill in the default namespace if not explicitly set."""
        if self.namespace is None:
            self.namespace = get_default_namespace()

Move the unset-namespace fallback into KFPServerConfig._postprocess so
the resolution lives in one place, per review feedback. This removes the
_apply_default_namespace helper and its three call sites in load_config;
_postprocess runs after validation on every construction, so all callers
get a concrete namespace without repeating the fallback.

Signed-off-by: Harsh Gupta <harshgupta93198@gmail.com>
@harshhh817

Copy link
Copy Markdown
Author

Thanks @jesuino! Moved the default-namespace resolution into KFPServerConfig._postprocess, which removes the _apply_default_namespace helper and its three call sites in load_config. All config unit tests pass.

@google-oss-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from jesuino. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature(backend): Support KALE_KFP_NAMESPACE for configurable KFP server namespace in KFPServerConfig

3 participants