Merge pull request #24 from Aignosi/fix/SIENTIAPDE-1579
Upgrade MLflow to 2.18.0 and constrain setuptools
This commit is contained in:
@@ -56,7 +56,7 @@ class ModelServing:
|
||||
# Function to list runs for a given experiment
|
||||
def search_runs_by_name(
|
||||
self, experiment_names: list[str], order_by: None | list[str] = None
|
||||
) -> pd.DataFrame:
|
||||
) -> pd.DataFrame | list:
|
||||
"""
|
||||
List runs for a specified MLflow experiment.
|
||||
|
||||
@@ -64,7 +64,7 @@ class ModelServing:
|
||||
experiment_names (list[str]): List with experiment_names to retrieve runs from.
|
||||
|
||||
Returns:
|
||||
pandas.DataFrame: A DataFrame containing run information.
|
||||
Union[pd.DataFrame, list]: A DataFrame or list containing run information.
|
||||
|
||||
Raises:
|
||||
SientiaMlException: If unable to search runs.
|
||||
@@ -73,7 +73,7 @@ class ModelServing:
|
||||
runs = mlflow.search_runs(experiment_names=experiment_names, order_by=order_by)
|
||||
except SientiaMlException as e:
|
||||
logging.error(e)
|
||||
raise SientiaMlException from e
|
||||
raise SientiaMlException(str(e)) from e
|
||||
return runs
|
||||
|
||||
def set_experiment(self, experiment_identifier: str) -> None:
|
||||
|
||||
@@ -35,9 +35,7 @@ def validate_frontend_date_format(fmt: str | None) -> None:
|
||||
return
|
||||
if fmt not in ALLOWED_FRONTEND_DATE_FORMATS:
|
||||
allowed = ', '.join(sorted(ALLOWED_FRONTEND_DATE_FORMATS))
|
||||
raise ValueError(
|
||||
f'Invalid date_format "{fmt}". Allowed formats: {allowed}'
|
||||
)
|
||||
raise ValueError(f'Invalid date_format "{fmt}". Allowed formats: {allowed}')
|
||||
|
||||
|
||||
def _frontend_date_format_to_strftime(fmt: str | None) -> str | None:
|
||||
|
||||
@@ -5,7 +5,8 @@ boto3==1.40.55
|
||||
botocore==1.40.55
|
||||
git+ssh://git@github.com/Aignosi/sientia-dataops-library.git@1.6.1
|
||||
prometheus-client==0.23.1
|
||||
mlflow==2.10.1
|
||||
mlflow==2.18.0
|
||||
setuptools<81
|
||||
evidently==0.4.21
|
||||
beautifulsoup4==4.12.3
|
||||
scikit-learn==1.4.2
|
||||
|
||||
@@ -51,6 +51,12 @@ TEST_SCENARIOS_DIR = PROJECT_ROOT / 'docs' / 'test-scenarios'
|
||||
MINIO_ALIAS = 'suse'
|
||||
MINIO_BUCKET = 'model-training'
|
||||
|
||||
# Mapeamento de CSV específico por cenário
|
||||
SCENARIO_CSV_MAPPING = {
|
||||
'12-angular-test-date-format': Path('docs/DB_CV022_WIT230.csv'),
|
||||
'13-angular-test-double-date-column': Path('docs/DB_CV022_WIT230 _double_date_column.csv'),
|
||||
}
|
||||
|
||||
POSTGRES_CONFIG = {
|
||||
'host': os.getenv('POSTGRES_HOST'),
|
||||
'port': os.getenv('POSTGRES_PORT'),
|
||||
@@ -306,6 +312,10 @@ def run_local_pipeline(
|
||||
result['error'] = str(exc)
|
||||
return result
|
||||
|
||||
# Use scenario-specific CSV if mapped, otherwise use provided csv_path
|
||||
if scenario_name in SCENARIO_CSV_MAPPING:
|
||||
csv_path = SCENARIO_CSV_MAPPING[scenario_name]
|
||||
|
||||
csv_path = _resolve_csv_path(csv_path)
|
||||
_ensure_source_file(csv_path)
|
||||
payload = _build_local_payload(request_data, csv_path)
|
||||
@@ -450,6 +460,11 @@ def run_single_scenario(scenario_name: str, csv_path: Path) -> dict:
|
||||
result['error'] = str(exc)
|
||||
return result
|
||||
|
||||
# Use scenario-specific CSV if mapped, otherwise use provided csv_path
|
||||
if scenario_name in SCENARIO_CSV_MAPPING:
|
||||
csv_path = SCENARIO_CSV_MAPPING[scenario_name]
|
||||
print(f' Using scenario-specific CSV: {csv_path}')
|
||||
|
||||
csv_path = _resolve_csv_path(csv_path)
|
||||
|
||||
# Upload CSV to MinIO
|
||||
|
||||
@@ -112,18 +112,16 @@ def test_search_runs_by_name_with_order_by(mock_search_runs, mock_set_tracking_u
|
||||
def test_search_runs_by_name_raises_exception(
|
||||
mock_logging_error, mock_search_runs, mock_set_tracking_uri
|
||||
):
|
||||
"""Test search_runs_by_name raises TypeError due to bug in line 80 of model_serving.py."""
|
||||
"""Test search_runs_by_name properly propagates SientiaMlException."""
|
||||
model_serving = ModelServing(tracking_uri='http://mlflow.example.com')
|
||||
|
||||
exception = SientiaMlException(message='Search failed')
|
||||
mock_search_runs.side_effect = exception
|
||||
|
||||
# The code has a bug on line 80: "raise SientiaMlException from e"
|
||||
# This raises TypeError because SientiaMlException requires 'message' argument
|
||||
with raises(TypeError, match="missing 1 required positional argument: 'message'"):
|
||||
with raises(SientiaMlException, match='Search failed'):
|
||||
model_serving.search_runs_by_name(['experiment1'])
|
||||
|
||||
mock_logging_error.assert_called_once()
|
||||
mock_logging_error.assert_called_once_with(exception)
|
||||
|
||||
|
||||
@patch('model_manager.sientia.model_serving.mlflow.set_tracking_uri')
|
||||
|
||||
@@ -993,7 +993,9 @@ class TestConfigureDatetimeIndex:
|
||||
assert 'var2' in result.columns
|
||||
|
||||
@pytest.mark.filterwarnings('ignore::UserWarning')
|
||||
def test_configure_datetime_index_invalid_timestamp_column(self, training_repo, datetime_params):
|
||||
def test_configure_datetime_index_invalid_timestamp_column(
|
||||
self, training_repo, datetime_params
|
||||
):
|
||||
"""Test _configure_datetime_index with invalid timestamp values."""
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
@@ -1199,10 +1201,12 @@ class TestEnsureDateColumnParsed:
|
||||
|
||||
def test_parses_column_with_format(self, date_params):
|
||||
"""When date_column and date_format set, column is parsed as datetime."""
|
||||
data = pd.DataFrame({
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
'ts': ['2023-01-01 10:00:00', '2023-06-15 14:30:00'],
|
||||
'x': [1, 2],
|
||||
})
|
||||
}
|
||||
)
|
||||
result = _ensure_date_column_parsed(data, date_params)
|
||||
assert result['ts'].dtype == 'datetime64[ns]'
|
||||
assert result['ts'].iloc[0].year == 2023
|
||||
@@ -1212,10 +1216,12 @@ class TestEnsureDateColumnParsed:
|
||||
def test_invalid_values_coerced_to_nat(self, date_params):
|
||||
"""Invalid date strings are coerced to NaT when format is set."""
|
||||
date_params.date_format = 'yyyy-MM-dd HH:mm:ss'
|
||||
data = pd.DataFrame({
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
'ts': ['2023-01-01 00:00:00', 'not-a-date', '2023-12-31 00:00:00'],
|
||||
'x': [1, 2, 3],
|
||||
})
|
||||
}
|
||||
)
|
||||
result = _ensure_date_column_parsed(data, date_params)
|
||||
assert pd.isna(result['ts'].iloc[1])
|
||||
assert result['ts'].iloc[0].year == 2023
|
||||
@@ -1256,10 +1262,12 @@ class TestApplySupportFilters:
|
||||
|
||||
def test_snake_case_upper_lower_line(self):
|
||||
"""Support filters with upper_line/lower_line (snake_case) filter rows."""
|
||||
data = pd.DataFrame({
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
'x': [1.0, 2.0, 3.0, 4.0],
|
||||
'target': [2.0, 4.0, 6.0, 8.0],
|
||||
})
|
||||
}
|
||||
)
|
||||
support_filters = {
|
||||
'x': {
|
||||
'upper_line': {'intercept': 1.0, 'angle': 50},
|
||||
@@ -1272,10 +1280,12 @@ class TestApplySupportFilters:
|
||||
|
||||
def test_camel_case_upper_lower_line(self):
|
||||
"""Support filters with upperLine/lowerLine (camelCase) are accepted."""
|
||||
data = pd.DataFrame({
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
'x': [1.0, 2.0, 3.0],
|
||||
'target': [1.0, 2.0, 3.0],
|
||||
})
|
||||
}
|
||||
)
|
||||
support_filters = {
|
||||
'x': {
|
||||
'upperLine': {'intercept': 2, 'angle': 5},
|
||||
@@ -1288,11 +1298,13 @@ class TestApplySupportFilters:
|
||||
|
||||
def test_two_variables_ands_masks(self):
|
||||
"""Two variables apply AND of both masks."""
|
||||
data = pd.DataFrame({
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
'a': [1.0, 2.0, 3.0],
|
||||
'b': [1.0, 2.0, 3.0],
|
||||
'target': [2.0, 2.0, 2.0],
|
||||
})
|
||||
}
|
||||
)
|
||||
support_filters = {
|
||||
'a': {
|
||||
'upper_line': {'intercept': 10, 'angle': 45},
|
||||
|
||||
Reference in New Issue
Block a user