feat: require date_column in training parameters and update documentation
- Made `date_column` a required field in `TrainModelParams`, ensuring it must be present in the input data. - Updated related documentation in `input-sample.md`, `README.md`, and various test scenarios to reflect the change in requirement. - Adjusted the handling of `date_format` to default to `yyyy-MM-dd HH:mm:ss` if omitted, enhancing usability. - Refined test scenarios to include new examples and ensure compliance with the updated parameter structure. These changes improve the robustness of the model training workflow and clarify the expectations for input data.
This commit is contained in:
@@ -7,7 +7,6 @@ Covers:
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from temporalio.testing import WorkflowEnvironment
|
||||
from temporalio.worker import Worker
|
||||
|
||||
@@ -15,6 +14,7 @@ from e2e.helpers import (
|
||||
assert_experiment_error,
|
||||
assert_experiment_run_name_set,
|
||||
assert_experiment_status,
|
||||
assert_no_experiment_row,
|
||||
insert_experiment_run,
|
||||
load_scenario,
|
||||
make_workflow_id,
|
||||
@@ -57,13 +57,13 @@ async def test_scenario_1_1_1_linear_regression_basic(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_2_polynomial_regression_degree2_with_scaler(
|
||||
async def test_scenario_1_1_2_linear_regression_with_scaler(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.2 – Polynomial Regression Degree 2 with Standard Scaler (cenário 03)."""
|
||||
scenario = load_scenario('03-polynomial-regression-degree2.json')
|
||||
"""Scenario 1.1.2 – Linear regression with Standard Scaler (cenário 02)."""
|
||||
scenario = load_scenario('02-linear-regression-with-scaler.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -80,13 +80,13 @@ async def test_scenario_1_1_2_polynomial_regression_degree2_with_scaler(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_3_linear_regression_with_lags(
|
||||
async def test_scenario_1_1_3_polynomial_regression_degree2_with_scaler(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.3 – Linear Regression with lag_train/lag_val per variable (cenário 05)."""
|
||||
scenario = load_scenario('05-linear-regression-with-lags.json')
|
||||
"""Scenario 1.1.3 – Polynomial Regression Degree 2 with Standard Scaler (cenário 03)."""
|
||||
scenario = load_scenario('03-polynomial-regression-degree2.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -103,13 +103,13 @@ async def test_scenario_1_1_3_linear_regression_with_lags(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_4_linear_regression_nan_interpolation(
|
||||
async def test_scenario_1_1_4_polynomial_regression_degree3_with_scaler(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.4 – nan_treatment='linear interpolation' (cenário 06)."""
|
||||
scenario = load_scenario('06-linear-regression-nan-interpolation.json')
|
||||
"""Scenario 1.1.4 – Polynomial regression degree 3 with Standard Scaler (cenário 04)."""
|
||||
scenario = load_scenario('04-polynomial-regression-degree3.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -121,17 +121,18 @@ async def test_scenario_1_1_4_linear_regression_nan_interpolation(
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_5_linear_regression_with_limits(
|
||||
async def test_scenario_1_1_5_linear_regression_with_lags(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.5 – support_filters with min/max limits per variable (cenário 08)."""
|
||||
scenario = load_scenario('08-linear-regression-with-limits.json')
|
||||
"""Scenario 1.1.5 – Linear Regression with lag_train/lag_val per variable (cenário 05)."""
|
||||
scenario = load_scenario('05-linear-regression-with-lags.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -143,17 +144,18 @@ async def test_scenario_1_1_5_linear_regression_with_limits(
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_6_polynomial_degree2_scaler_and_lags(
|
||||
async def test_scenario_1_1_6_linear_regression_nan_interpolation(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.6 – Polynomial degree 2, Standard Scaler and lags (cenário 09)."""
|
||||
scenario = load_scenario('09-polynomial-degree2-with-scaler-and-lags.json')
|
||||
"""Scenario 1.1.6 – nan_treatment='linear interpolation' (cenário 06)."""
|
||||
scenario = load_scenario('06-linear-regression-nan-interpolation.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -165,18 +167,17 @@ async def test_scenario_1_1_6_polynomial_degree2_scaler_and_lags(
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_7_static_window_removal(
|
||||
async def test_scenario_1_1_7_linear_regression_static_window_removal(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.7 – rem_static_win=true with window and static_threshold (cenário 11)."""
|
||||
scenario = load_scenario('11-linear-regression-static-threshold-custom.json')
|
||||
"""Scenario 1.1.7 – rem_static_win=true with default static_threshold (cenário 07)."""
|
||||
scenario = load_scenario('07-linear-regression-static-window-removal.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -192,16 +193,13 @@ async def test_scenario_1_1_7_static_window_removal(
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_8_polynomial_with_support_filters(
|
||||
async def test_scenario_1_1_8_linear_regression_with_limits(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.8 – Polynomial degree 4, Standard Scaler, upper/lower support filters (cenário 14)."""
|
||||
scenario = load_scenario('14-angular-test-polynomial-support-filters.json')
|
||||
# Override date range to match rows in our test CSV
|
||||
scenario['data_model_kwargs']['start_date'] = '2025-06-02 00:00:00'
|
||||
scenario['data_model_kwargs']['end_date'] = '2025-06-06 23:59:59'
|
||||
"""Scenario 1.1.8 – support_filters with min/max limits per variable (cenário 08)."""
|
||||
scenario = load_scenario('08-linear-regression-with-limits.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
@@ -215,6 +213,230 @@ async def test_scenario_1_1_8_polynomial_with_support_filters(
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_9_polynomial_degree2_scaler_and_lags(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.9 – Polynomial degree 2, Standard Scaler and lags (cenário 09)."""
|
||||
scenario = load_scenario('09-polynomial-degree2-with-scaler-and-lags.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-9'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_10_linear_regression_with_ar_opt_params(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.10 – Linear regression with include_ar in opt_params (cenário 10)."""
|
||||
scenario = load_scenario('10-linear-regression-with-ar.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-10'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_11_linear_regression_static_threshold_custom(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.11 – rem_static_win=true with custom static_threshold (cenário 11)."""
|
||||
scenario = load_scenario('11-linear-regression-static-threshold-custom.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-11'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_12_alternate_date_format_dd_mm_yyyy(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.12 – DATA column and dd/MM/yyyy format CSV (cenário 12)."""
|
||||
scenario = load_scenario('12-angular-test-date-format.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(
|
||||
postgres_engine,
|
||||
experiment_run_id,
|
||||
file_name='training_data_dd_mm_yyyy.csv',
|
||||
)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-12'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_13_alternate_csv_narrow_date_window(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.13 – Same alternate CSV as 12 with date window (cenário 13)."""
|
||||
scenario = load_scenario('13-angular-test-double-date-column.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(
|
||||
postgres_engine,
|
||||
experiment_run_id,
|
||||
file_name='training_data_dd_mm_yyyy.csv',
|
||||
)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-13'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_14_polynomial_with_support_filters(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.14 – Polynomial degree 4, Standard Scaler, line support filters (cenário 14)."""
|
||||
scenario = load_scenario('14-angular-test-polynomial-support-filters.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(postgres_engine, experiment_run_id)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-14'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_15_linear_regression_custom_target_column_name(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.15 – Target column is not named ``target``; report path uses target_variable."""
|
||||
scenario = load_scenario('15-linear-regression-custom-target-column.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(
|
||||
postgres_engine,
|
||||
experiment_run_id,
|
||||
file_name='training_data_custom_target.csv',
|
||||
)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-15'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_16_naive_timestamp_header_column(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.16 – CSV uses ``Timestamp`` header; snake_case date_column/date_format."""
|
||||
scenario = load_scenario('16-linear-regression-naive-timestamp-header.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(
|
||||
postgres_engine,
|
||||
experiment_run_id,
|
||||
file_name='training_data_timestamp_naive.csv',
|
||||
)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-16'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.integration
|
||||
async def test_scenario_1_1_17_linear_regression_blank_timestamp_row_dropped(
|
||||
temporal_test_env: WorkflowEnvironment,
|
||||
temporal_worker: Worker,
|
||||
postgres_engine,
|
||||
):
|
||||
"""Scenario 1.1.17 – CSV has one empty timestamp cell; row is dropped and training succeeds."""
|
||||
scenario = load_scenario('17-linear-regression-blank-timestamp-row.json')
|
||||
experiment_run_id = scenario['experiment_run_id']
|
||||
insert_experiment_run(
|
||||
postgres_engine,
|
||||
experiment_run_id,
|
||||
file_name='training_data_blank_timestamp_row.csv',
|
||||
)
|
||||
|
||||
await start_and_await_workflow(
|
||||
temporal_test_env.client,
|
||||
TrainModel.run,
|
||||
scenario,
|
||||
make_workflow_id('test-s1-1-17'),
|
||||
)
|
||||
|
||||
assert_experiment_status(postgres_engine, experiment_run_id, 'TRAINING_SUCCESS')
|
||||
assert_experiment_run_name_set(postgres_engine, experiment_run_id)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# 1.2 – Error paths
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -268,5 +490,4 @@ async def test_scenario_1_2_2_experiment_run_id_not_in_db(
|
||||
make_workflow_id('test-s1-2-2'),
|
||||
)
|
||||
|
||||
from e2e.helpers import assert_no_experiment_row
|
||||
assert_no_experiment_row(postgres_engine, 9999)
|
||||
|
||||
Reference in New Issue
Block a user