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
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp

## [Unreleased] - ????-??-??

**Summary**: Type system overhaul with comprehensive type hints for better IDE support and code clarity.
**Summary**: Type system overhaul and migration to loguru for logging

If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOpt/flixOpt/releases/tag/v3.0.0) and [Migration Guide](https://flixopt.github.io/flixopt/latest/user-guide/migration-guide-v3/).

Expand All @@ -64,8 +64,13 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp
- Added `Scalar` type for scalar-only numeric values
- Added `NumericOrBool` utility type for internal use
- Type system supports scalars, numpy arrays, pandas Series/DataFrames, and xarray DataArrays
- Lazy logging evaluation - expensive log operations only execute when log level is active
- `CONFIG.Logging.verbose_tracebacks` option for detailed debugging with variable values

### 💥 Breaking Changes
- **Logging framework**: Migrated to [loguru](https://loguru.readthedocs.io/)
- Removed `CONFIG.Logging` parameters: `rich`, `Colors`, `date_format`, `format`, `console_width`, `show_path`, `show_logger_name`
- For advanced formatting, use loguru's API directly after `CONFIG.apply()`

### ♻️ Changed
- **Code structure**: Removed `commons.py` module and moved all imports directly to `__init__.py` for cleaner code organization (no public API changes)
Expand All @@ -83,13 +88,15 @@ If upgrading from v2.x, see the [v3.0.0 release notes](https://github.com/flixOp

### 📦 Dependencies
- Updated `mkdocs-material` to v9.6.23
- Replaced `rich >= 13.0.0` with `loguru >= 0.7.0` for logging

### 📝 Docs
- Enhanced documentation in `flixopt/types.py` with comprehensive examples and dimension explanation table
- Clarified Effect type docstrings - Effect types are dicts, but single numeric values work through union types
- Added clarifying comments in `effects.py` explaining parameter handling and transformation
- Improved OnOffParameters attribute documentation

- Updated getting-started guide with loguru examples
- Updated `config.py` docstrings for loguru integration

### 👷 Development
- Added test for FlowSystem resampling
Expand Down
18 changes: 18 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ For all features including interactive network visualizations and time series ag
pip install "flixopt[full]"
```

## Logging

FlixOpt uses [loguru](https://loguru.readthedocs.io/) for logging. Logging is silent by default but can be easily configured. For beginners, use our internal convenience methods. Experts can use loguru directly.

```python
from flixopt import CONFIG

# Enable console logging
CONFIG.Logging.console = True
CONFIG.Logging.level = 'INFO'
CONFIG.apply()

# Or use a preset configuration for exploring
CONFIG.exploring()
```

For more details on logging configuration, see the [`CONFIG.Logging`][flixopt.config.CONFIG.Logging] documentation.

## Basic Workflow

Working with FlixOpt follows a general pattern:
Expand Down
3 changes: 1 addition & 2 deletions examples/02_Complex/complex_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import numpy as np
import pandas as pd
from rich.pretty import pprint # Used for pretty printing

import flixopt as fx

Expand Down Expand Up @@ -188,7 +187,7 @@
flow_system.add_elements(Costs, CO2, PE, Gaskessel, Waermelast, Gasbezug, Stromverkauf, speicher)
flow_system.add_elements(bhkw_2) if use_chp_with_piecewise_conversion else flow_system.add_elements(bhkw)

pprint(flow_system) # Get a string representation of the FlowSystem
print(flow_system) # Get a string representation of the FlowSystem
try:
flow_system.start_network_app() # Start the network app
except ImportError as e:
Expand Down
4 changes: 1 addition & 3 deletions examples/05_Two-stage-optimization/two_stage_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@
While the final optimum might differ from the global optimum, the solving will be much faster.
"""

import logging
import pathlib
import timeit

import pandas as pd
import xarray as xr
from loguru import logger

import flixopt as fx

logger = logging.getLogger('flixopt')

if __name__ == '__main__':
fx.CONFIG.exploring()

Expand Down
6 changes: 2 additions & 4 deletions flixopt/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
from __future__ import annotations

import copy
import logging
import pathlib
import timeit
from typing import TYPE_CHECKING

import numpy as np
from loguru import logger

try:
import tsam.timeseriesaggregation as tsam
Expand All @@ -37,8 +37,6 @@
from .elements import Component
from .flow_system import FlowSystem

logger = logging.getLogger('flixopt')


class Aggregation:
"""
Expand Down Expand Up @@ -106,7 +104,7 @@ def cluster(self) -> None:
self.aggregated_data = self.tsam.predictOriginalData()

self.clustering_duration_seconds = timeit.default_timer() - start_time # Zeit messen:
logger.info(self.describe_clusters())
logger.opt(lazy=True).info('{result}', result=lambda: self.describe_clusters())

def describe_clusters(self) -> str:
description = {}
Expand Down
18 changes: 7 additions & 11 deletions flixopt/calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

from __future__ import annotations

import logging
import math
import pathlib
import sys
Expand All @@ -20,6 +19,7 @@
from typing import TYPE_CHECKING, Annotated, Any

import numpy as np
from loguru import logger
from tqdm import tqdm

from . import io as fx_io
Expand All @@ -39,8 +39,6 @@
from .solvers import _Solver
from .structure import FlowSystemModel

logger = logging.getLogger('flixopt')


class Calculation:
"""
Expand Down Expand Up @@ -238,7 +236,7 @@ def solve(
**solver.options,
)
self.durations['solving'] = round(timeit.default_timer() - t_start, 2)
logger.info(f'Model solved with {solver.name} in {self.durations["solving"]:.2f} seconds.')
logger.success(f'Model solved with {solver.name} in {self.durations["solving"]:.2f} seconds.')
logger.info(f'Model status after solve: {self.model.status}')

if self.model.status == 'warning':
Expand All @@ -255,12 +253,10 @@ def solve(
# Log the formatted output
should_log = log_main_results if log_main_results is not None else CONFIG.Solving.log_main_results
if should_log:
logger.info(
f'{" Main Results ":#^80}\n'
+ fx_io.format_yaml_string(
self.main_results,
compact_numeric_lists=True,
)
logger.opt(lazy=True).info(
'{result}',
result=lambda: f'{" Main Results ":#^80}\n'
+ fx_io.format_yaml_string(self.main_results, compact_numeric_lists=True),
)

self.results = CalculationResults.from_calculation(self)
Expand Down Expand Up @@ -673,7 +669,7 @@ def do_modeling_and_solve(
for key, value in calc.durations.items():
self.durations[key] += value

logger.info(f'Model solved with {solver.name} in {self.durations["solving"]:.2f} seconds.')
logger.success(f'Model solved with {solver.name} in {self.durations["solving"]:.2f} seconds.')

self.results = SegmentedCalculationResults.from_calculation(self)

Expand Down
5 changes: 1 addition & 4 deletions flixopt/color_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@

from __future__ import annotations

import logging

import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import plotly.express as px
from loguru import logger
from plotly.exceptions import PlotlyError

logger = logging.getLogger('flixopt')


def _rgb_string_to_hex(color: str) -> str:
"""Convert Plotly RGB/RGBA string format to hex.
Expand Down
4 changes: 1 addition & 3 deletions flixopt/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

from __future__ import annotations

import logging
import warnings
from typing import TYPE_CHECKING, Literal

import numpy as np
import xarray as xr
from loguru import logger

from . import io as fx_io
from .core import PlausibilityError
Expand All @@ -25,8 +25,6 @@
from .flow_system import FlowSystem
from .types import Numeric_PS, Numeric_TPS

logger = logging.getLogger('flixopt')


@register_class_for_io
class LinearConverter(Component):
Expand Down
Loading