From 6fccf11d91182a7979e92fa3b3ab839f75366376 Mon Sep 17 00:00:00 2001 From: Michiel De Smet Date: Thu, 12 Jun 2025 16:17:35 +0800 Subject: [PATCH 1/4] feat: add credentials validation for knowledge server --- src/datapilot/core/knowledge/cli.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/datapilot/core/knowledge/cli.py b/src/datapilot/core/knowledge/cli.py index 3119a21..d506483 100644 --- a/src/datapilot/core/knowledge/cli.py +++ b/src/datapilot/core/knowledge/cli.py @@ -4,6 +4,7 @@ from datapilot.cli.decorators import auth_options +from ...clients.altimate.utils import validate_credentials from .server import KnowledgeBaseHandler @@ -23,6 +24,10 @@ def serve(token, instance_name, backend_url, port): ) raise click.Abort + if not validate_credentials(token, backend_url, instance_name): + click.echo("Error: Invalid credentials.") + raise click.Abort + # Set context data for the handler KnowledgeBaseHandler.token = token KnowledgeBaseHandler.instance_name = instance_name From 77457e51ff374046fda07cfd67c30441cd8d17a0 Mon Sep 17 00:00:00 2001 From: Michiel De Smet Date: Thu, 12 Jun 2025 16:18:49 +0800 Subject: [PATCH 2/4] fix: Only use config if no CLI arguments are provided --- src/datapilot/cli/decorators.py | 40 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/datapilot/cli/decorators.py b/src/datapilot/cli/decorators.py index 6267f4c..631b1a0 100644 --- a/src/datapilot/cli/decorators.py +++ b/src/datapilot/cli/decorators.py @@ -3,17 +3,19 @@ import re from functools import wraps from pathlib import Path +from typing import Dict +from typing import Optional import click from dotenv import load_dotenv -def load_config_from_file(): +def load_config_from_file() -> Optional[Dict]: """Load configuration from ~/.altimate/altimate.json if it exists.""" config_path = Path.home() / ".altimate" / "altimate.json" if not config_path.exists(): - return {} + return None try: with config_path.open() as f: @@ -21,7 +23,7 @@ def load_config_from_file(): return config except (OSError, json.JSONDecodeError) as e: click.echo(f"Warning: Failed to load config from {config_path}: {e}", err=True) - return {} + return None def substitute_env_vars(value): @@ -58,30 +60,22 @@ def wrapper(token, instance_name, backend_url, *args, **kwargs): # Load .env file from current directory if it exists load_dotenv() - # Load configuration from file - file_config = load_config_from_file() - file_config = process_config(file_config) - - # Apply file config first, then override with CLI arguments if provided final_token = token final_instance_name = instance_name final_backend_url = backend_url - # Use file config if CLI argument not provided - if final_token is None and "altimateApiKey" in file_config: - final_token = file_config["altimateApiKey"] - if final_instance_name is None and "altimateInstanceName" in file_config: - final_instance_name = file_config["altimateInstanceName"] - if final_backend_url == "https://api.myaltimate.com" and "altimateUrl" in file_config: - final_backend_url = file_config["altimateUrl"] - - # Set defaults if nothing was provided - if final_token is None: - final_token = None - if final_instance_name is None: - final_instance_name = None - if final_backend_url is None: - final_backend_url = "https://api.myaltimate.com" + if final_token is None and final_instance_name is None: + # Try to Load configuration from file if no CLI arguments are provided + file_config = load_config_from_file() + if file_config is not None: + # File config is provided + file_config = process_config(file_config) + if "altimateApiKey" in file_config: + final_token = file_config["altimateApiKey"] + if "altimateInstanceName" in file_config: + final_instance_name = file_config["altimateInstanceName"] + if "altimateUrl" in file_config: + final_backend_url = file_config["altimateUrl"] or final_backend_url return f(final_token, final_instance_name, final_backend_url, *args, **kwargs) From ff4afcbb066c2c8799719f4a25b34b932ce0cdf5 Mon Sep 17 00:00:00 2001 From: Michiel De Smet Date: Thu, 12 Jun 2025 16:22:35 +0800 Subject: [PATCH 3/4] refactor: reorder imports in knowledge cli module --- src/datapilot/core/knowledge/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datapilot/core/knowledge/cli.py b/src/datapilot/core/knowledge/cli.py index d506483..59cc983 100644 --- a/src/datapilot/core/knowledge/cli.py +++ b/src/datapilot/core/knowledge/cli.py @@ -3,8 +3,8 @@ import click from datapilot.cli.decorators import auth_options +from datapilot.clients.altimate.utils import validate_credentials -from ...clients.altimate.utils import validate_credentials from .server import KnowledgeBaseHandler From 2b7121f0e491e3f4bc086afeac06efd5616c74ad Mon Sep 17 00:00:00 2001 From: Michiel De Smet Date: Thu, 12 Jun 2025 16:23:11 +0800 Subject: [PATCH 4/4] fix: output invalid credentials error to stderr --- src/datapilot/core/knowledge/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/datapilot/core/knowledge/cli.py b/src/datapilot/core/knowledge/cli.py index 59cc983..6503d78 100644 --- a/src/datapilot/core/knowledge/cli.py +++ b/src/datapilot/core/knowledge/cli.py @@ -25,7 +25,7 @@ def serve(token, instance_name, backend_url, port): raise click.Abort if not validate_credentials(token, backend_url, instance_name): - click.echo("Error: Invalid credentials.") + click.echo("Error: Invalid credentials.", err=True) raise click.Abort # Set context data for the handler