Skip to content

Commit 94dcc4a

Browse files
authored
Merge pull request #35 from dmaniloff/read-kube-token-as-env
feat: ability to pass in KFP token via env var.
2 parents 80a3a67 + a07cc9b commit 94dcc4a

File tree

9 files changed

+64
-30
lines changed

9 files changed

+64
-30
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ KUBEFLOW_LLAMA_STACK_URL=<your-llama-stack-url>
5353
KUBEFLOW_PIPELINES_ENDPOINT=<your-kfp-endpoint>
5454
KUBEFLOW_NAMESPACE=<your-namespace>
5555
KUBEFLOW_BASE_IMAGE=quay.io/diegosquayorg/my-ragas-provider-image:latest
56+
KUBEFLOW_PIPELINES_TOKEN=<your-pipelines-token>
5657
KUBEFLOW_RESULTS_S3_PREFIX=s3://my-bucket/ragas-results
5758
KUBEFLOW_S3_CREDENTIALS_SECRET_NAME=<secret-name>
5859
```
@@ -61,6 +62,7 @@ Where:
6162
- `KUBEFLOW_LLAMA_STACK_URL`: The URL of the llama stack server that the remote provider will use to run the evaluation (LLM generations and embeddings, etc.). If you are running Llama Stack locally, you can use [ngrok](https://ngrok.com/) to expose it to the remote provider.
6263
- `KUBEFLOW_PIPELINES_ENDPOINT`: You can get this via `kubectl get routes -A | grep -i pipeline` on your Kubernetes cluster.
6364
- `KUBEFLOW_NAMESPACE`: The name of the data science project where the Kubeflow Pipelines server is running.
65+
- `KUBEFLOW_PIPELINES_TOKEN`: Kubeflow Pipelines token with access to submit pipelines. If not provided, the token will be read from the local kubeconfig file.
6466
- `KUBEFLOW_BASE_IMAGE`: The image used to run the Ragas evaluation in the remote provider. See `Containerfile` for details. There is a public version of this image at `quay.io/diegosquayorg/my-ragas-provider-image:latest`.
6567
- `KUBEFLOW_RESULTS_S3_PREFIX`: S3 location (bucket and prefix folder) where evaluation results will be stored, e.g., `s3://my-bucket/ragas-results`.
6668
- `KUBEFLOW_S3_CREDENTIALS_SECRET_NAME`: Name of the Kubernetes secret containing AWS credentials with write access to the S3 bucket. Create with:

distribution/run-remote.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ providers:
2121
namespace: ${env.KUBEFLOW_NAMESPACE}
2222
llama_stack_url: ${env.KUBEFLOW_LLAMA_STACK_URL}
2323
base_image: ${env.KUBEFLOW_BASE_IMAGE}
24+
pipelines_token: ${env.KUBEFLOW_PIPELINES_TOKEN:=}
2425
datasetio:
2526
- provider_id: localfs
2627
provider_type: inline::localfs

docs/modules/ROOT/pages/remote-provider.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ KUBEFLOW_NAMESPACE=<your-namespace>
143143
# Container image for remote execution
144144
KUBEFLOW_BASE_IMAGE=quay.io/diegosquayorg/my-ragas-provider-image:latest
145145
146+
# Authentication token for Kubeflow Pipelines
147+
KUBEFLOW_PIPELINES_TOKEN=<your-pipelines-token>
148+
146149
# S3 configuration for storing evaluation results
147150
KUBEFLOW_RESULTS_S3_PREFIX=s3://my-bucket/ragas-results
148151
KUBEFLOW_S3_CREDENTIALS_SECRET_NAME=<secret-name>
@@ -170,6 +173,9 @@ The name of the data science project where the Kubeflow Pipelines server is runn
170173
`KUBEFLOW_BASE_IMAGE`::
171174
The container image used to run the Ragas evaluation in the remote provider. See the `Containerfile` in the repository root for details on building a custom image.
172175

176+
`KUBEFLOW_PIPELINES_TOKEN`::
177+
Kubeflow Pipelines token with access to submit pipelines. If not provided, the token will be read from the local kubeconfig file. This token is used to authenticate with the Kubeflow Pipelines API for pipeline submission and monitoring.
178+
173179
`KUBEFLOW_RESULTS_S3_PREFIX`::
174180
The S3 location (bucket and prefix) where evaluation results will be stored. This should be a folder path, e.g., `s3://my-bucket/ragas-results`. The remote provider will write evaluation outputs to this location.
175181

@@ -207,6 +213,7 @@ eval:
207213
namespace: ${env.KUBEFLOW_NAMESPACE}
208214
llama_stack_url: ${env.KUBEFLOW_LLAMA_STACK_URL}
209215
base_image: ${env.KUBEFLOW_BASE_IMAGE}
216+
pipelines_token: ${env.KUBEFLOW_PIPELINES_TOKEN:=}
210217
----
211218

212219
To run with the sample distribution:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "llama-stack-provider-ragas"
7-
version = "0.3.4"
7+
version = "0.3.5"
88
description = "Ragas evaluation as an out-of-tree Llama Stack provider"
99
readme = "README.md"
1010
requires-python = ">=3.12"

src/llama_stack_provider_ragas/config.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ class KubeflowConfig(BaseModel):
107107
description=(
108108
"Base image for Kubeflow pipeline components. "
109109
"If not provided via env var, the image name will be read from a ConfigMap specified in constants.py."
110+
"NOTE: this field is accessed via env var, but is here for completeness."
111+
),
112+
default=None,
113+
)
114+
115+
pipelines_token: str | None = Field(
116+
description=(
117+
"Kubeflow Pipelines token with access to submit pipelines. "
118+
"If not provided via env var, the token will be read from the local kubeconfig file."
110119
),
111120
default=None,
112121
)

src/llama_stack_provider_ragas/remote/kubeflow/components.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,32 @@
1+
import logging
2+
import os
13
from typing import List # noqa
24

35
from dotenv import load_dotenv
46
from kfp import dsl
7+
from kubernetes import client
8+
from kubernetes.client.exceptions import ApiException
9+
10+
from ...constants import (
11+
DEFAULT_RAGAS_PROVIDER_IMAGE,
12+
KUBEFLOW_CANDIDATE_NAMESPACES,
13+
RAGAS_PROVIDER_IMAGE_CONFIGMAP_KEY,
14+
RAGAS_PROVIDER_IMAGE_CONFIGMAP_NAME,
15+
)
16+
from .utils import _load_kube_config
517

618
load_dotenv()
19+
logger = logging.getLogger(__name__)
20+
logger.setLevel(logging.INFO)
721

822

923
def get_base_image() -> str:
1024
"""Get base image from env, fallback to k8s ConfigMap, fallback to default image."""
1125

12-
import logging
13-
import os
14-
15-
from kubernetes import client, config
16-
from kubernetes.client.exceptions import ApiException
17-
18-
from llama_stack_provider_ragas.constants import (
19-
DEFAULT_RAGAS_PROVIDER_IMAGE,
20-
KUBEFLOW_CANDIDATE_NAMESPACES,
21-
RAGAS_PROVIDER_IMAGE_CONFIGMAP_KEY,
22-
RAGAS_PROVIDER_IMAGE_CONFIGMAP_NAME,
23-
)
24-
2526
if (base_image := os.environ.get("KUBEFLOW_BASE_IMAGE")) is not None:
2627
return base_image
2728

28-
logger = logging.getLogger(__name__)
29-
logger.setLevel(logging.INFO)
30-
31-
try:
32-
config.load_incluster_config()
33-
except config.ConfigException:
34-
config.load_kube_config()
35-
29+
_load_kube_config()
3630
api = client.CoreV1Api()
3731

3832
for candidate_namespace in KUBEFLOW_CANDIDATE_NAMESPACES:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import logging
2+
3+
logger = logging.getLogger(__name__)
4+
5+
6+
def _load_kube_config():
7+
from kubernetes import config
8+
from kubernetes.client.configuration import Configuration
9+
10+
kube_config = Configuration()
11+
12+
try:
13+
config.load_incluster_config(client_configuration=kube_config)
14+
logger.info("Loaded in-cluster Kubernetes configuration")
15+
except config.ConfigException:
16+
config.load_kube_config(client_configuration=kube_config)
17+
logger.info("Loaded Kubernetes configuration from kubeconfig file")
18+
19+
return kube_config

src/llama_stack_provider_ragas/remote/ragas_remote_eval.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def kfp_client(self):
7171
try:
7272
import kfp
7373

74-
token = self._get_token()
74+
token = self._get_kfp_token()
7575
if not token:
7676
raise RagasEvaluationError(
7777
"No token found. Please run `oc login` and try again."
@@ -108,14 +108,16 @@ def kfp_client(self):
108108

109109
return self._kfp_client
110110

111-
def _get_token(self) -> str:
111+
def _get_kfp_token(self) -> str:
112+
if self.config.kubeflow_config.pipelines_token:
113+
logger.info("Using KUBEFLOW_PIPELINES_TOKEN from config")
114+
return self.config.kubeflow_config.pipelines_token
115+
112116
try:
113-
from kubernetes.client.configuration import Configuration
114-
from kubernetes.config.kube_config import load_kube_config
117+
from .kubeflow.utils import _load_kube_config
115118

116-
config = Configuration()
117-
load_kube_config(client_configuration=config)
118-
token = str(config.api_key["authorization"].split(" ")[-1])
119+
kube_config = _load_kube_config()
120+
token = str(kube_config.api_key["authorization"].split(" ")[-1])
119121
except ImportError as e:
120122
raise RagasEvaluationError(
121123
"Kubernetes client is not installed. Install with: pip install .[remote]"

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)