Skip to content

copy_scenario

copy_scenario

Service for copying scenarios.

Classes

CopyScenarioRunner

Bases: BaseRunner[Dict[str, Any]]

Runner for copying an existing scenario.

POST /api/v3/scenarios

Functions
run staticmethod
run(client, scenario_id, overrides=None, **kwargs)

Copy an existing scenario with optional attribute overrides.

Parameters:

Name Type Description Default
client BaseClient

The HTTP client to use

required
scenario_id int

ID of the scenario to copy

required
overrides Optional[Dict[str, Any]]

Optional dictionary of scenario attributes to override

None
**kwargs Any

Additional arguments passed to the request

{}
Example usage

result = CopyScenarioRunner.run( client=client, scenario_id=123456, overrides={ "title": "Copy of my scenario", "private": True } )

Source code in src/pyetm/services/scenario_runners/copy_scenario.py
@staticmethod
def run(
    client: BaseClient,
    scenario_id: int,
    overrides: Optional[Dict[str, Any]] = None,
    **kwargs: Any,
) -> ServiceResult[Dict[str, Any]]:
    """
    Copy an existing scenario with optional attribute overrides.

    Args:
        client: The HTTP client to use
        scenario_id: ID of the scenario to copy
        overrides: Optional dictionary of scenario attributes to override
        **kwargs: Additional arguments passed to the request

    Example usage:
        result = CopyScenarioRunner.run(
            client=client,
            scenario_id=123456,
            overrides={
                "title": "Copy of my scenario",
                "private": True
            }
        )
    """
    # Start with the scenario_id as base
    scenario_data = {"scenario_id": scenario_id}

    warnings = []

    # Merge in any overrides
    if overrides:
        filtered_overrides = {
            key: value
            for key, value in overrides.items()
            if key in CopyScenarioRunner.ALLOWED_OVERRIDE_KEYS
        }

        # Warn about ignored keys
        filtered_keys = set(overrides.keys()) - set(filtered_overrides.keys())
        for key in filtered_keys:
            warnings.append(f"Ignoring invalid field for scenario copy: {key!r}")

        scenario_data.update(filtered_overrides)

    # Transform template_id → preset_scenario_id for ETEngine API
    if "template_id" in scenario_data:
        scenario_data["preset_scenario_id"] = scenario_data.pop("template_id")

    payload = {"scenario": scenario_data}

    result = CopyScenarioRunner._make_request(
        client=client,
        method="post",
        path="/scenarios",
        payload=payload,
    )

    if result.success and warnings:
        # Merge our warnings with any from the API call
        combined_errors = list(result.errors) + warnings
        assert result.data is not None, "Success result must have data"
        return ServiceResult.ok(data=result.data, errors=combined_errors)

    return result