Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,14 @@ If the bug involves code or configuration, please provide a minimal, reproducibl
import my_library

# Setup or initialization
config = {
"setting_a": "value",
"setting_b": 123
}
config = {'setting_a': 'value', 'setting_b': 123}
processor = my_library.Processor(**config)

# Action that triggers the bug
try:
processor.process_data(invalid_data)
except Exception as e:
print(f"Error: {e}")
print(f'Error: {e}')
```

## Error Message / Stack Trace
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
repos:
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.12.5
rev: 0.12.7
hooks:
# Dependency management
- id: uv-lock
Expand Down Expand Up @@ -47,7 +47,7 @@ repos:
# Python Linting & Formatting with Ruff
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: "v0.16.4"
rev: "v0.16.5"
hooks:
- id: ruff
name: ruff (linter)
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@ from temoa import TemoaModel, TemoaConfig, TemoaMode

# Create configuration
config = TemoaConfig(
scenario="my_scenario",
scenario='my_scenario',
scenario_mode=TemoaMode.PERFECT_FORESIGHT,
input_database=Path("path/to/input.db"),
output_database=Path("path/to/output.db"),
output_path=Path("path/to/output"),
solver_name="appsi_highs"
input_database=Path('path/to/input.db'),
output_database=Path('path/to/output.db'),
output_path=Path('path/to/output'),
solver_name='appsi_highs',
)

# Build and solve model
Expand All @@ -172,9 +172,9 @@ result = model.run() # Equivalent to: temoa run tutorial_config.toml

# Check if run was successful
if result:
print("Model solved successfully!")
print('Model solved successfully!')
else:
print("Model failed to solve")
print('Model failed to solve')
```

## Database Setup
Expand Down
60 changes: 34 additions & 26 deletions temoa/data_io/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ This is the most common case, for a component that maps directly to a database t
# temoa/data_io/component_manifest.py

# ... inside the manifest list
LoadItem(
component=M.MyNewParam,
table='MyNewParamTableName',
columns=['region', 'tech', 'value'],
# Optional: Add validation if this component should be filtered
# by the source-trace analysis.
validator_name='viable_rt',
validation_map=(0, 1), # Corresponds to 'region' and 'tech' columns
),
(
LoadItem(
component=M.MyNewParam,
table='MyNewParamTableName',
columns=['region', 'tech', 'value'],
# Optional: Add validation if this component should be filtered
# by the source-trace analysis.
validator_name='viable_rt',
validation_map=(0, 1), # Corresponds to 'region' and 'tech' columns
),
)
# ...
```

Expand All @@ -60,13 +62,15 @@ If a component is optional and should have a default value if its table is missi
```python
# temoa/data_io/component_manifest.py

LoadItem(
component=M.MyOptionalSet,
table='MyOptionalSetTable',
columns=['some_value'],
is_table_required=False, # Mark the table as optional
fallback_data=[('A',), ('B',)] # Provide default data
),
(
LoadItem(
component=M.MyOptionalSet,
table='MyOptionalSetTable',
columns=['some_value'],
is_table_required=False, # Mark the table as optional
fallback_data=[('A',), ('B',)], # Provide default data
),
)
```

### Case 3: Adding a Component with Complex Logic
Expand All @@ -85,12 +89,14 @@ If a component requires logic that doesn't fit the standard pattern (e.g., aggre
# temoa/data_io/hybrid_loader.py

# ... inside the HybridLoader class, in the custom loaders section
def _load_my_complex_param(self, data: dict, raw_data: Sequence[tuple], filtered_data: Sequence[tuple]):
def _load_my_complex_param(
self, data: dict, raw_data: Sequence[tuple], filtered_data: Sequence[tuple]
):
"""Custom loader for MyComplexParam."""
M = TemoaModel()
# --- Add your custom logic here ---
# For example, perform a special query or transform the data.
final_data_to_load = [(r, t, v * 2) for r, t, v in filtered_data] # Example transformation
final_data_to_load = [(r, t, v * 2) for r, t, v in filtered_data] # Example transformation

# Use the standard helper to load the final data
self._load_component_data(data, M.MyComplexParam, final_data_to_load)
Expand All @@ -102,14 +108,16 @@ If a component requires logic that doesn't fit the standard pattern (e.g., aggre
```python
# temoa/data_io/component_manifest.py

LoadItem(
component=M.MyComplexParam,
table='MyComplexParamTable', # Can be a real table or a placeholder
columns=['region', 'tech', 'value'],
# Point to your new method
custom_loader_name='_load_my_complex_param',
is_table_required=False # Usually False if the loader has complex logic
),
(
LoadItem(
component=M.MyComplexParam,
table='MyComplexParamTable', # Can be a real table or a placeholder
columns=['region', 'tech', 'value'],
# Point to your new method
custom_loader_name='_load_my_complex_param',
is_table_required=False, # Usually False if the loader has complex logic
),
)
```

This pattern keeps the main engine clean while providing unlimited flexibility to handle any data loading scenario.
Loading