Skip to content

Commit 7360299

Browse files
fix: add default console url value (#490)
1 parent 9b60fa3 commit 7360299

File tree

6 files changed

+64
-21
lines changed

6 files changed

+64
-21
lines changed

src/galileo/__future__/configuration.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from galileo.__future__.shared.exceptions import ConfigurationError
99
from galileo.config import GalileoPythonConfig
10+
from galileo.constants import DEFAULT_CONSOLE_URL
1011
from galileo.utils.log_config import enable_console_logging as _enable_console_logging
1112
from galileo.utils.log_config import get_logger
1213

@@ -76,7 +77,10 @@ def parse_log_level(value: str) -> str:
7677
sensitive=True,
7778
),
7879
ConfigKey(
79-
name="console_url", env_var="GALILEO_CONSOLE_URL", description="URL of the Galileo console", required=True
80+
name="console_url",
81+
env_var="GALILEO_CONSOLE_URL",
82+
description="URL of the Galileo console",
83+
default=DEFAULT_CONSOLE_URL,
8084
),
8185
ConfigKey(
8286
name="openai_api_key",
@@ -379,11 +383,6 @@ def connect(cls) -> None:
379383
"""Validate configuration and connect to Galileo."""
380384
cls._load_env_file()
381385

382-
if not cls.console_url:
383-
raise ConfigurationError(
384-
"Galileo console URL is required. Set Configuration.console_url or GALILEO_CONSOLE_URL."
385-
)
386-
387386
if not cls.galileo_api_key:
388387
raise ConfigurationError(
389388
"Galileo API key is required. Set Configuration.galileo_api_key or GALILEO_API_KEY."

src/galileo/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44

55
from pydantic_core import Url
66

7+
from galileo.constants import DEFAULT_CONSOLE_URL
78
from galileo_core.schemas.base_config import GalileoConfig
89

910

1011
class GalileoPythonConfig(GalileoConfig):
1112
# Config file for this project.
1213
config_filename: str = "galileo-python-config.json"
13-
console_url: Url = "https://app.galileo.ai"
14+
console_url: Url = DEFAULT_CONSOLE_URL
1415

1516
_instance: ClassVar[Optional["GalileoPythonConfig"]] = None
1617

src/galileo/constants/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
DEFAULT_MODE = "batch"
66

77
DEFAULT_API_URL = "https://api.galileo.ai/"
8+
DEFAULT_CONSOLE_URL = "https://app.galileo.ai/"
89

910
# HTTP header prefix for all Galileo headers
1011
GALILEO_HEADER_PREFIX = "X-Galileo"
@@ -14,6 +15,7 @@
1415

1516
__all__ = (
1617
"DEFAULT_API_URL",
18+
"DEFAULT_CONSOLE_URL",
1719
"DEFAULT_LOG_STREAM_NAME",
1820
"DEFAULT_MODE",
1921
"DEFAULT_PROJECT_NAME",

src/galileo/experiments.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def run(
144144

145145
_logger.debug(f"job: {job}")
146146

147-
link = f"{self.config.console_url}/project/{project_obj.id}/experiments/{experiment_obj.id}"
147+
link = f"{str(self.config.console_url).rstrip('/')}/project/{project_obj.id}/experiments/{experiment_obj.id}"
148148
message = f"Experiment {experiment_obj.name} has started and is currently processing. Results will be available at {link}"
149149
_logger.info(message)
150150

@@ -208,7 +208,7 @@ def logged_process_func(row: DatasetRecord) -> Callable:
208208

209209
_logger.info(f" {len(results)} rows processed for experiment {experiment_obj.name}.")
210210

211-
link = f"{self.config.console_url}/project/{project_obj.id}/experiments/{experiment_obj.id}"
211+
link = f"{str(self.config.console_url).rstrip('/')}/project/{project_obj.id}/experiments/{experiment_obj.id}"
212212
message = f"Experiment {experiment_obj.name} has completed and results are available at {link}"
213213
_logger.info(message)
214214

tests/future/test_configuration.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -281,25 +281,29 @@ def test_connect_succeeds_with_valid_configuration(
281281
assert "Validating Galileo configuration" in logs
282282
assert "Successfully connected to Galileo" in logs
283283

284-
def test_connect_fails_without_console_url(
285-
self, monkeypatch: pytest.MonkeyPatch, reset_configuration: None, capture_logs: tuple[logging.Logger, StringIO]
284+
def test_connect_passes_without_console_url(
285+
self,
286+
mock_api_endpoints: MagicMock,
287+
monkeypatch: pytest.MonkeyPatch,
288+
reset_configuration: None,
289+
capture_logs: tuple[logging.Logger, StringIO],
286290
) -> None:
287-
"""Test connect() raises ConfigurationError when console URL is missing."""
291+
"""Test successful connection with valid API key and should default to default console URL."""
288292
_, log_stream = capture_logs
289293

290-
# Set only API key
294+
# Set valid configuration
291295
monkeypatch.setenv("GALILEO_API_KEY", "valid-key")
292296

293-
# Should raise ConfigurationError
294-
with pytest.raises(ConfigurationError) as exc_info:
295-
Configuration.connect()
297+
# Connect should succeed without raising
298+
Configuration.connect()
296299

297-
# Verify error message provides helpful guidance
298-
assert "console url is required" in str(exc_info.value).lower()
299-
assert "configuration.console_url" in str(exc_info.value).lower()
300+
# Verify logging occurred (no print statements)
301+
logs = log_stream.getvalue()
302+
assert "Validating Galileo configuration" in logs
303+
assert "Successfully connected to Galileo" in logs
300304

301-
# Note: Early validation failures don't produce logs since they occur
302-
# before the logger.info call in connect()
305+
# Verify console URL is set to default
306+
assert Configuration.console_url == "https://app.galileo.ai/"
303307

304308
def test_connect_fails_without_api_key(
305309
self, monkeypatch: pytest.MonkeyPatch, reset_configuration: None, capture_logs: tuple[logging.Logger, StringIO]

tests/test_experiments.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,43 @@ def test_run_experiment_without_metrics(
572572
prompt_settings=ANY,
573573
)
574574

575+
@pytest.mark.parametrize("console_url", ["http://localtest:8088", "http://localtest:8088/"])
576+
@travel(datetime(2012, 1, 1), tick=False)
577+
@patch.object(galileo.datasets.Datasets, "get")
578+
@patch.object(galileo.jobs.Jobs, "create")
579+
@patch.object(galileo.experiments.Experiments, "create", return_value=experiment_response())
580+
@patch.object(galileo.experiments.Experiments, "get", return_value=experiment_response())
581+
@patch.object(galileo.experiments.Projects, "get_with_env_fallbacks", return_value=project())
582+
def test_run_experiment_link_no_double_slash(
583+
self,
584+
mock_get_project: Mock,
585+
mock_get_experiment: Mock,
586+
mock_create_experiment: Mock,
587+
mock_create_job: Mock,
588+
mock_get_dataset: Mock,
589+
console_url: str,
590+
dataset_content: DatasetContent,
591+
) -> None:
592+
# Given: a console_url with or without a trailing slash
593+
mock_create_job.return_value = MagicMock()
594+
mock_config = MagicMock()
595+
mock_config.console_url = console_url
596+
597+
# When: running an experiment
598+
with patch("galileo.experiments.GalileoPythonConfig.get", return_value=mock_config):
599+
result = run_experiment(
600+
"test_experiment",
601+
project="awesome-new-project",
602+
dataset_id=str(UUID(int=0)),
603+
prompt_template=prompt_template(),
604+
)
605+
606+
# Then: the link does not contain double slashes after the protocol
607+
assert result is not None
608+
link = result["link"]
609+
assert "//project" not in link
610+
assert f"/project/{project().id}/experiments/{experiment_response().id}" in link
611+
575612
@travel(datetime(2012, 1, 1), tick=False)
576613
@patch.object(galileo.datasets.Datasets, "get")
577614
@patch.object(galileo.jobs.Jobs, "create")

0 commit comments

Comments
 (0)