openstef 3.4.17__py3-none-any.whl → 3.4.18__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openstef/app_settings.py +17 -0
- openstef/feature_engineering/data_preparation.py +7 -0
- openstef/feature_engineering/general.py +14 -0
- openstef/feature_engineering/weather_features.py +7 -0
- openstef/metrics/reporter.py +7 -0
- openstef/model/confidence_interval_applicator.py +7 -0
- openstef/model/model_creator.py +7 -0
- openstef/model/serializer.py +7 -0
- openstef/monitoring/teams.py +8 -0
- openstef/pipeline/create_basecase_forecast.py +7 -0
- openstef/pipeline/create_component_forecast.py +8 -1
- openstef/pipeline/create_forecast.py +8 -0
- openstef/pipeline/optimize_hyperparameters.py +8 -1
- openstef/pipeline/train_model.py +6 -2
- openstef/postprocessing/postprocessing.py +7 -0
- openstef/settings.py +15 -0
- openstef/tasks/calculate_kpi.py +14 -6
- openstef/tasks/create_components_forecast.py +7 -0
- openstef/tasks/split_forecast.py +7 -0
- openstef/tasks/utils/taskcontext.py +7 -0
- openstef/validation/validation.py +22 -0
- {openstef-3.4.17.dist-info → openstef-3.4.18.dist-info}/METADATA +2 -1
- {openstef-3.4.17.dist-info → openstef-3.4.18.dist-info}/RECORD +26 -24
- {openstef-3.4.17.dist-info → openstef-3.4.18.dist-info}/LICENSE +0 -0
- {openstef-3.4.17.dist-info → openstef-3.4.18.dist-info}/WHEEL +0 -0
- {openstef-3.4.17.dist-info → openstef-3.4.18.dist-info}/top_level.txt +0 -0
openstef/app_settings.py
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
|
5
|
+
from pydantic import Field
|
6
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
7
|
+
|
8
|
+
|
9
|
+
class AppSettings(BaseSettings):
|
10
|
+
"""Global app settings."""
|
11
|
+
|
12
|
+
# Logging settings.
|
13
|
+
log_level: str = Field("INFO", description="Log level used for logging statements.")
|
14
|
+
|
15
|
+
model_config = SettingsConfigDict(
|
16
|
+
env_prefix="openstef_", env_file=".env", extra="ignore"
|
17
|
+
)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Alliander N.V. <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from abc import ABC, abstractmethod
|
5
6
|
from datetime import timedelta
|
6
7
|
from typing import Optional
|
@@ -20,6 +21,7 @@ from openstef.feature_engineering.general import (
|
|
20
21
|
)
|
21
22
|
from openstef.model.regressors.regressor import OpenstfRegressor
|
22
23
|
from openstef.pipeline.utils import generate_forecast_datetime_range
|
24
|
+
from openstef.settings import Settings
|
23
25
|
|
24
26
|
|
25
27
|
class AbstractDataPreparation(ABC):
|
@@ -120,6 +122,11 @@ class ARDataPreparation(AbstractDataPreparation):
|
|
120
122
|
def prepare_forecast_data(
|
121
123
|
self, data: pd.DataFrame
|
122
124
|
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
125
|
+
structlog.configure(
|
126
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
127
|
+
logging.getLevelName(Settings.log_level)
|
128
|
+
)
|
129
|
+
)
|
123
130
|
logger = structlog.get_logger(__name__)
|
124
131
|
self.check_model()
|
125
132
|
# Prep forecast input by selecting only the forecast datetime interval (this is much smaller than the input range)
|
@@ -3,10 +3,14 @@
|
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
"""This modelu contains various helper functions."""
|
5
5
|
|
6
|
+
import logging
|
7
|
+
|
6
8
|
import numpy as np
|
7
9
|
import pandas as pd
|
8
10
|
import structlog
|
9
11
|
|
12
|
+
from openstef.settings import Settings
|
13
|
+
|
10
14
|
|
11
15
|
def add_missing_feature_columns(
|
12
16
|
input_data: pd.DataFrame, features: list[str]
|
@@ -30,6 +34,11 @@ def add_missing_feature_columns(
|
|
30
34
|
Input dataframe with missing columns filled with ``np.N=nan``.
|
31
35
|
|
32
36
|
"""
|
37
|
+
structlog.configure(
|
38
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
39
|
+
logging.getLevelName(Settings.log_level)
|
40
|
+
)
|
41
|
+
)
|
33
42
|
logger = structlog.get_logger(__name__)
|
34
43
|
|
35
44
|
if features is None:
|
@@ -61,6 +70,11 @@ def remove_non_requested_feature_columns(
|
|
61
70
|
Model input data with features.
|
62
71
|
|
63
72
|
"""
|
73
|
+
structlog.configure(
|
74
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
75
|
+
logging.getLevelName(Settings.log_level)
|
76
|
+
)
|
77
|
+
)
|
64
78
|
logger = structlog.get_logger(__name__)
|
65
79
|
|
66
80
|
if requested_features is None:
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
|
5
5
|
"""This module contains all wheather related functions used for feature engineering."""
|
6
|
+
import logging
|
6
7
|
from typing import Union
|
7
8
|
|
8
9
|
import numpy as np
|
@@ -12,7 +13,13 @@ import structlog
|
|
12
13
|
from pvlib.location import Location
|
13
14
|
|
14
15
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
16
|
+
from openstef.settings import Settings
|
15
17
|
|
18
|
+
structlog.configure(
|
19
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
20
|
+
logging.getLevelName(Settings.log_level)
|
21
|
+
)
|
22
|
+
)
|
16
23
|
logger = structlog.get_logger(__name__)
|
17
24
|
|
18
25
|
|
openstef/metrics/reporter.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
"""Defines reporter class."""
|
5
|
+
import logging
|
5
6
|
import os
|
6
7
|
import warnings
|
7
8
|
from dataclasses import dataclass
|
@@ -16,6 +17,7 @@ from plotly.graph_objects import Figure
|
|
16
17
|
from openstef.metrics import figure
|
17
18
|
from openstef.metrics.metrics import bias, mae, nsme, r_mae, rmse
|
18
19
|
from openstef.model.regressors.regressor import OpenstfRegressor
|
20
|
+
from openstef.settings import Settings
|
19
21
|
|
20
22
|
|
21
23
|
@dataclass
|
@@ -167,6 +169,11 @@ class Reporter:
|
|
167
169
|
def write_report_to_disk(report: Report, report_folder: str):
|
168
170
|
"""Write report to disk; e.g. for viewing report of latest models using grafana."""
|
169
171
|
# Initialize logger and serializer
|
172
|
+
structlog.configure(
|
173
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
174
|
+
logging.getLevelName(Settings.log_level)
|
175
|
+
)
|
176
|
+
)
|
170
177
|
logger = structlog.get_logger(__name__)
|
171
178
|
if report_folder:
|
172
179
|
# create path if does not exist
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from datetime import datetime
|
5
6
|
|
6
7
|
import numpy as np
|
@@ -11,12 +12,18 @@ from sklearn.base import RegressorMixin
|
|
11
12
|
|
12
13
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
13
14
|
from openstef.exceptions import ModelWithoutStDev
|
15
|
+
from openstef.settings import Settings
|
14
16
|
|
15
17
|
|
16
18
|
class ConfidenceIntervalApplicator:
|
17
19
|
def __init__(self, model: RegressorMixin, forecast_input_data: pd.DataFrame):
|
18
20
|
self.model = model
|
19
21
|
self.forecast_input_data = forecast_input_data
|
22
|
+
structlog.configure(
|
23
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
24
|
+
logging.getLevelName(Settings.log_level)
|
25
|
+
)
|
26
|
+
)
|
20
27
|
self.logger = structlog.get_logger(self.__class__.__name__)
|
21
28
|
|
22
29
|
def add_confidence_interval(
|
openstef/model/model_creator.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from typing import Union
|
5
6
|
|
6
7
|
import structlog
|
@@ -13,7 +14,13 @@ from openstef.model.regressors.linear import LinearOpenstfRegressor
|
|
13
14
|
from openstef.model.regressors.regressor import OpenstfRegressor
|
14
15
|
from openstef.model.regressors.xgb import XGBOpenstfRegressor
|
15
16
|
from openstef.model.regressors.xgb_quantile import XGBQuantileOpenstfRegressor
|
17
|
+
from openstef.settings import Settings
|
16
18
|
|
19
|
+
structlog.configure(
|
20
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
21
|
+
logging.getLevelName(Settings.log_level)
|
22
|
+
)
|
23
|
+
)
|
17
24
|
logger = structlog.get_logger(__name__)
|
18
25
|
|
19
26
|
valid_model_kwargs = {
|
openstef/model/serializer.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
import json
|
5
|
+
import logging
|
5
6
|
import os
|
6
7
|
import shutil
|
7
8
|
from datetime import datetime
|
@@ -20,10 +21,16 @@ from xgboost import XGBModel # Temporary for backward compatibility
|
|
20
21
|
from openstef.data_classes.model_specifications import ModelSpecificationDataClass
|
21
22
|
from openstef.metrics.reporter import Report
|
22
23
|
from openstef.model.regressors.regressor import OpenstfRegressor
|
24
|
+
from openstef.settings import Settings
|
23
25
|
|
24
26
|
|
25
27
|
class MLflowSerializer:
|
26
28
|
def __init__(self, mlflow_tracking_uri: str):
|
29
|
+
structlog.configure(
|
30
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
31
|
+
logging.getLevelName(Settings.log_level)
|
32
|
+
)
|
33
|
+
)
|
27
34
|
self.logger = structlog.get_logger(self.__class__.__name__)
|
28
35
|
mlflow.set_tracking_uri(mlflow_tracking_uri)
|
29
36
|
self.logger.debug(f"MLflow tracking uri at init= {mlflow_tracking_uri}")
|
openstef/monitoring/teams.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from typing import Union
|
5
6
|
|
6
7
|
import pandas as pd
|
@@ -8,6 +9,8 @@ import pymsteams
|
|
8
9
|
import structlog
|
9
10
|
from pymsteams import cardsection
|
10
11
|
|
12
|
+
from openstef.settings import Settings
|
13
|
+
|
11
14
|
|
12
15
|
def post_teams(
|
13
16
|
msg: Union[str, dict],
|
@@ -38,6 +41,11 @@ def post_teams(
|
|
38
41
|
Note:
|
39
42
|
This function is namespace-specific.
|
40
43
|
"""
|
44
|
+
structlog.configure(
|
45
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
46
|
+
logging.getLevelName(Settings.log_level)
|
47
|
+
)
|
48
|
+
)
|
41
49
|
logger = structlog.get_logger(__name__)
|
42
50
|
# If no url is passed, give warning and don't send teams message
|
43
51
|
if url is None:
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from pathlib import Path
|
5
6
|
|
6
7
|
import pandas as pd
|
@@ -18,6 +19,7 @@ from openstef.postprocessing.postprocessing import (
|
|
18
19
|
add_components_base_case_forecast,
|
19
20
|
add_prediction_job_properties_to_forecast,
|
20
21
|
)
|
22
|
+
from openstef.settings import Settings
|
21
23
|
from openstef.validation import validation
|
22
24
|
|
23
25
|
MODEL_LOCATION = Path(".")
|
@@ -42,6 +44,11 @@ def create_basecase_forecast_pipeline(
|
|
42
44
|
NoRealisedLoadError: When no realised load for given datetime range.
|
43
45
|
|
44
46
|
"""
|
47
|
+
structlog.configure(
|
48
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
49
|
+
logging.getLevelName(Settings.log_level)
|
50
|
+
)
|
51
|
+
)
|
45
52
|
logger = structlog.get_logger(__name__)
|
46
53
|
|
47
54
|
logger.info("Preprocessing data for basecase forecast")
|
@@ -2,6 +2,8 @@
|
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
4
|
|
5
|
+
import logging
|
6
|
+
|
5
7
|
import joblib
|
6
8
|
import numpy as np
|
7
9
|
import pandas as pd
|
@@ -12,6 +14,7 @@ from openstef import PROJECT_ROOT
|
|
12
14
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
13
15
|
from openstef.enums import ForecastType
|
14
16
|
from openstef.model.regressors.dazls import Dazls
|
17
|
+
from openstef.settings import Settings
|
15
18
|
|
16
19
|
# Set the path for the Dazls stored model
|
17
20
|
DAZLS_STORED = str(
|
@@ -95,6 +98,11 @@ def create_components_forecast_pipeline(
|
|
95
98
|
"algtype"
|
96
99
|
|
97
100
|
"""
|
101
|
+
structlog.configure(
|
102
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
103
|
+
logging.getLevelName(Settings.log_level)
|
104
|
+
)
|
105
|
+
)
|
98
106
|
logger = structlog.get_logger(__name__)
|
99
107
|
logger.info("Make components prediction", pid=pj["id"])
|
100
108
|
|
@@ -124,7 +132,6 @@ def create_components_forecast_pipeline(
|
|
124
132
|
dazls_model.target_columns = joblib.load(DAZLS_STORED + "target.z")
|
125
133
|
dazls_model.target_scaler = joblib.load(DAZLS_STORED + "target_scaler.z")
|
126
134
|
|
127
|
-
logger = structlog.get_logger(__name__)
|
128
135
|
logger.info("DAZLS model loaded", dazls_model=str(dazls_model))
|
129
136
|
|
130
137
|
# Use the predict function of Dazls model
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
5
|
+
|
4
6
|
import pandas as pd
|
5
7
|
import structlog
|
6
8
|
|
@@ -18,6 +20,7 @@ from openstef.postprocessing.postprocessing import (
|
|
18
20
|
add_prediction_job_properties_to_forecast,
|
19
21
|
sort_quantiles,
|
20
22
|
)
|
23
|
+
from openstef.settings import Settings
|
21
24
|
from openstef.validation import validation
|
22
25
|
|
23
26
|
|
@@ -85,6 +88,11 @@ def create_forecast_pipeline_core(
|
|
85
88
|
InputDataOngoingZeroFlatlinerError: When all recent load measurements are zero.
|
86
89
|
|
87
90
|
"""
|
91
|
+
structlog.configure(
|
92
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
93
|
+
logging.getLevelName(Settings.log_level)
|
94
|
+
)
|
95
|
+
)
|
88
96
|
logger = structlog.get_logger(__name__)
|
89
97
|
|
90
98
|
fallback_strategy = "extreme_day" # this can later be expanded
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
import os
|
5
|
-
from typing import Any
|
6
|
+
from typing import Any
|
6
7
|
|
7
8
|
import optuna
|
8
9
|
import pandas as pd
|
@@ -26,11 +27,17 @@ from openstef.pipeline.train_model import (
|
|
26
27
|
DEFAULT_TRAIN_HORIZONS_HOURS,
|
27
28
|
train_model_pipeline_core,
|
28
29
|
)
|
30
|
+
from openstef.settings import Settings
|
29
31
|
from openstef.validation import validation
|
30
32
|
|
31
33
|
optuna.logging.enable_propagation() # Propagate logs to the root logger.
|
32
34
|
optuna.logging.disable_default_handler() # Stop showing logs in sys.stderr.
|
33
35
|
|
36
|
+
structlog.configure(
|
37
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
38
|
+
logging.getLevelName(Settings.log_level)
|
39
|
+
)
|
40
|
+
)
|
34
41
|
logger = structlog.get_logger(__name__)
|
35
42
|
|
36
43
|
# See https://optuna.readthedocs.io/en/stable/reference/generated/optuna.study.Study.html#optuna.study.Study.optimize
|
openstef/pipeline/train_model.py
CHANGED
@@ -23,6 +23,7 @@ from openstef.model.regressors.regressor import OpenstfRegressor
|
|
23
23
|
from openstef.model.serializer import MLflowSerializer
|
24
24
|
from openstef.model.standard_deviation_generator import StandardDeviationGenerator
|
25
25
|
from openstef.model_selection.model_selection import split_data_train_validation_test
|
26
|
+
from openstef.settings import Settings
|
26
27
|
from openstef.validation import validation
|
27
28
|
|
28
29
|
DEFAULT_TRAIN_HORIZONS_HOURS: list[float] = [0.25, 47.0]
|
@@ -31,6 +32,11 @@ MAXIMUM_MODEL_AGE: int = 7
|
|
31
32
|
DEFAULT_EARLY_STOPPING_ROUNDS: int = 10
|
32
33
|
PENALTY_FACTOR_OLD_MODEL: float = 1.2
|
33
34
|
|
35
|
+
structlog.configure(
|
36
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
37
|
+
logging.getLevelName(Settings.log_level)
|
38
|
+
)
|
39
|
+
)
|
34
40
|
logger = structlog.get_logger(__name__)
|
35
41
|
|
36
42
|
|
@@ -180,8 +186,6 @@ def train_model_pipeline_core(
|
|
180
186
|
- Datasets (tuple[pd.DataFrmae, pd.DataFrame, pd.Dataframe): The train, validation and test sets
|
181
187
|
|
182
188
|
"""
|
183
|
-
logger = structlog.get_logger(__name__)
|
184
|
-
|
185
189
|
# Call common pipeline
|
186
190
|
(
|
187
191
|
model,
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
from enum import Enum
|
5
6
|
|
6
7
|
import numpy as np
|
@@ -10,6 +11,7 @@ import structlog
|
|
10
11
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
11
12
|
from openstef.enums import ForecastType
|
12
13
|
from openstef.feature_engineering import weather_features
|
14
|
+
from openstef.settings import Settings
|
13
15
|
|
14
16
|
# this is the default for "Lagerwey100"
|
15
17
|
TURBINE_DATA = {
|
@@ -219,6 +221,11 @@ def add_prediction_job_properties_to_forecast(
|
|
219
221
|
Dataframe with added metadata.
|
220
222
|
|
221
223
|
"""
|
224
|
+
structlog.configure(
|
225
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
226
|
+
logging.getLevelName(Settings.log_level)
|
227
|
+
)
|
228
|
+
)
|
222
229
|
logger = structlog.get_logger(__name__)
|
223
230
|
|
224
231
|
logger.info("Postproces in preparation of storing")
|
openstef/settings.py
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
|
5
|
+
from functools import lru_cache
|
6
|
+
|
7
|
+
from openstef.app_settings import AppSettings
|
8
|
+
|
9
|
+
|
10
|
+
@lru_cache
|
11
|
+
def _get_app_settings() -> AppSettings:
|
12
|
+
return AppSettings()
|
13
|
+
|
14
|
+
|
15
|
+
Settings = _get_app_settings()
|
openstef/tasks/calculate_kpi.py
CHANGED
@@ -18,6 +18,8 @@ Example:
|
|
18
18
|
$ python calculate_kpi.py
|
19
19
|
|
20
20
|
"""
|
21
|
+
import logging
|
22
|
+
|
21
23
|
# Import builtins
|
22
24
|
from datetime import datetime, timedelta
|
23
25
|
from pathlib import Path
|
@@ -30,6 +32,7 @@ from openstef.data_classes.prediction_job import PredictionJobDataClass
|
|
30
32
|
from openstef.enums import MLModelType
|
31
33
|
from openstef.exceptions import NoPredictedLoadError, NoRealisedLoadError
|
32
34
|
from openstef.metrics import metrics
|
35
|
+
from openstef.settings import Settings
|
33
36
|
from openstef.tasks.utils.predictionjobloop import PredictionJobLoop
|
34
37
|
from openstef.tasks.utils.taskcontext import TaskContext
|
35
38
|
from openstef.validation import validation
|
@@ -153,7 +156,12 @@ def calc_kpi_for_specific_pid(
|
|
153
156
|
COMPLETENESS_REALISED_THRESHOLDS = 0.7
|
154
157
|
COMPLETENESS_PREDICTED_LOAD_THRESHOLD = 0.7
|
155
158
|
|
156
|
-
|
159
|
+
structlog.configure(
|
160
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
161
|
+
logging.getLevelName(Settings.log_level)
|
162
|
+
)
|
163
|
+
)
|
164
|
+
logger = structlog.get_logger(__name__)
|
157
165
|
|
158
166
|
# If predicted is empty
|
159
167
|
if len(predicted_load) == 0:
|
@@ -187,9 +195,9 @@ def calc_kpi_for_specific_pid(
|
|
187
195
|
|
188
196
|
# Raise exception in case of constant load
|
189
197
|
if combined.load.nunique() == 1:
|
190
|
-
|
198
|
+
logger.warning(
|
191
199
|
"The load is constant! KPIs will still be calculated, but relative metrics"
|
192
|
-
" will be nan"
|
200
|
+
" will be nan."
|
193
201
|
)
|
194
202
|
|
195
203
|
# Define output dictonary
|
@@ -206,7 +214,7 @@ def calc_kpi_for_specific_pid(
|
|
206
214
|
date = pd.to_datetime(end_time)
|
207
215
|
|
208
216
|
# Calculate model metrics and add them to the output dictionary
|
209
|
-
|
217
|
+
logger.info("Start calculating kpis")
|
210
218
|
for hor_cols in hor_list:
|
211
219
|
t_ahead_h = hor_cols[0].split("_")[1]
|
212
220
|
fc = combined[hor_cols[0]] # load predictions
|
@@ -265,7 +273,7 @@ def calc_kpi_for_specific_pid(
|
|
265
273
|
)
|
266
274
|
|
267
275
|
if completeness_realised < COMPLETENESS_REALISED_THRESHOLDS:
|
268
|
-
|
276
|
+
logger.warning(
|
269
277
|
"Completeness realised load too low",
|
270
278
|
prediction_id=pid,
|
271
279
|
start_time=start_time,
|
@@ -275,7 +283,7 @@ def calc_kpi_for_specific_pid(
|
|
275
283
|
)
|
276
284
|
set_incomplete_kpi_to_nan(kpis, t_ahead_h)
|
277
285
|
if completeness_predicted_load.any() < COMPLETENESS_PREDICTED_LOAD_THRESHOLD:
|
278
|
-
|
286
|
+
logger.warning(
|
279
287
|
"Completeness predicted load of specific horizon too low",
|
280
288
|
prediction_id=pid,
|
281
289
|
horizon=t_ahead_h,
|
@@ -21,6 +21,7 @@ Example:
|
|
21
21
|
$ python create_components_forecast.py
|
22
22
|
|
23
23
|
"""
|
24
|
+
import logging
|
24
25
|
from datetime import datetime, timedelta, timezone
|
25
26
|
from pathlib import Path
|
26
27
|
|
@@ -33,6 +34,7 @@ from openstef.exceptions import ComponentForecastTooShortHorizonError
|
|
33
34
|
from openstef.pipeline.create_component_forecast import (
|
34
35
|
create_components_forecast_pipeline,
|
35
36
|
)
|
37
|
+
from openstef.settings import Settings
|
36
38
|
from openstef.tasks.utils.predictionjobloop import PredictionJobLoop
|
37
39
|
from openstef.tasks.utils.taskcontext import TaskContext
|
38
40
|
|
@@ -56,6 +58,11 @@ def create_components_forecast_task(
|
|
56
58
|
(less than 30 minutes in advance)
|
57
59
|
|
58
60
|
"""
|
61
|
+
structlog.configure(
|
62
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
63
|
+
logging.getLevelName(Settings.log_level)
|
64
|
+
)
|
65
|
+
)
|
59
66
|
logger = structlog.get_logger(__name__)
|
60
67
|
if pj["train_components"] == 0:
|
61
68
|
context.logger.info(
|
openstef/tasks/split_forecast.py
CHANGED
@@ -22,6 +22,7 @@ Example:
|
|
22
22
|
$ python split_forecast.py
|
23
23
|
|
24
24
|
"""
|
25
|
+
import logging
|
25
26
|
from datetime import datetime
|
26
27
|
from pathlib import Path
|
27
28
|
|
@@ -33,6 +34,7 @@ import structlog
|
|
33
34
|
import openstef.monitoring.teams as monitoring
|
34
35
|
from openstef.data_classes.prediction_job import PredictionJobDataClass
|
35
36
|
from openstef.enums import MLModelType
|
37
|
+
from openstef.settings import Settings
|
36
38
|
from openstef.tasks.utils.predictionjobloop import PredictionJobLoop
|
37
39
|
from openstef.tasks.utils.taskcontext import TaskContext
|
38
40
|
|
@@ -70,6 +72,11 @@ def split_forecast_task(
|
|
70
72
|
Energy splitting coefficients.
|
71
73
|
|
72
74
|
"""
|
75
|
+
structlog.configure(
|
76
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
77
|
+
logging.getLevelName(Settings.log_level)
|
78
|
+
)
|
79
|
+
)
|
73
80
|
logger = structlog.get_logger(__name__)
|
74
81
|
|
75
82
|
logger.info("Start splitting energy", pid=pj["id"])
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
import traceback
|
5
6
|
from typing import Callable
|
6
7
|
|
@@ -9,6 +10,7 @@ import structlog
|
|
9
10
|
from openstef.exceptions import PredictionJobException
|
10
11
|
from openstef.monitoring.performance_meter import PerformanceMeter
|
11
12
|
from openstef.monitoring.teams import post_teams
|
13
|
+
from openstef.settings import Settings
|
12
14
|
|
13
15
|
|
14
16
|
class TaskContext:
|
@@ -62,6 +64,11 @@ class TaskContext:
|
|
62
64
|
self.database = database
|
63
65
|
|
64
66
|
def __enter__(self):
|
67
|
+
structlog.configure(
|
68
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
69
|
+
logging.getLevelName(Settings.log_level)
|
70
|
+
)
|
71
|
+
)
|
65
72
|
self.logger = structlog.get_logger(__name__).bind(task=self.name)
|
66
73
|
|
67
74
|
self.perf_meter = PerformanceMeter(self.logger)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# SPDX-FileCopyrightText: 2017-2023 Contributors to the OpenSTEF project <korte.termijn.prognoses@alliander.com> # noqa E501>
|
2
2
|
#
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
4
|
+
import logging
|
4
5
|
import math
|
5
6
|
from datetime import datetime, timedelta
|
6
7
|
from typing import Union
|
@@ -12,6 +13,7 @@ import structlog
|
|
12
13
|
from openstef.exceptions import InputDataOngoingZeroFlatlinerError
|
13
14
|
from openstef.model.regressors.regressor import OpenstfRegressor
|
14
15
|
from openstef.preprocessing.preprocessing import replace_repeated_values_with_nan
|
16
|
+
from openstef.settings import Settings
|
15
17
|
|
16
18
|
|
17
19
|
def validate(
|
@@ -41,6 +43,11 @@ def validate(
|
|
41
43
|
InputDataOngoingZeroFlatlinerError: If all recent load measurements are zero.
|
42
44
|
|
43
45
|
"""
|
46
|
+
structlog.configure(
|
47
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
48
|
+
logging.getLevelName(Settings.log_level)
|
49
|
+
)
|
50
|
+
)
|
44
51
|
logger = structlog.get_logger(__name__)
|
45
52
|
|
46
53
|
if not isinstance(data.index, pd.DatetimeIndex):
|
@@ -84,6 +91,11 @@ def validate(
|
|
84
91
|
|
85
92
|
|
86
93
|
def drop_target_na(data: pd.DataFrame) -> pd.DataFrame:
|
94
|
+
structlog.configure(
|
95
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
96
|
+
logging.getLevelName(Settings.log_level)
|
97
|
+
)
|
98
|
+
)
|
87
99
|
logger = structlog.get_logger(__name__)
|
88
100
|
len_original = len(data)
|
89
101
|
# Remove where load is NA, NaN features are preserved
|
@@ -122,6 +134,11 @@ def is_data_sufficient(
|
|
122
134
|
else:
|
123
135
|
weights = model.feature_importance_dataframe
|
124
136
|
|
137
|
+
structlog.configure(
|
138
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
139
|
+
logging.getLevelName(Settings.log_level)
|
140
|
+
)
|
141
|
+
)
|
125
142
|
logger = structlog.get_logger(__name__)
|
126
143
|
# Set output variable
|
127
144
|
is_sufficient = True
|
@@ -254,6 +271,11 @@ def calc_completeness_dataframe(
|
|
254
271
|
Dataframe with fraction of completeness per column
|
255
272
|
|
256
273
|
"""
|
274
|
+
structlog.configure(
|
275
|
+
wrapper_class=structlog.make_filtering_bound_logger(
|
276
|
+
logging.getLevelName(Settings.log_level)
|
277
|
+
)
|
278
|
+
)
|
257
279
|
logger = structlog.get_logger(__name__)
|
258
280
|
|
259
281
|
if homogenise and isinstance(df.index, pd.DatetimeIndex) and len(df) > 0:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: openstef
|
3
|
-
Version: 3.4.
|
3
|
+
Version: 3.4.18
|
4
4
|
Summary: Open short term energy forecaster
|
5
5
|
Home-page: https://github.com/OpenSTEF/openstef
|
6
6
|
Author: Alliander N.V
|
@@ -27,6 +27,7 @@ Requires-Dist: pandas ~=2.2.0
|
|
27
27
|
Requires-Dist: plotly ~=5.18
|
28
28
|
Requires-Dist: pvlib ==0.9.4
|
29
29
|
Requires-Dist: pydantic ~=2.4
|
30
|
+
Requires-Dist: pydantic-settings ~=2.2.1
|
30
31
|
Requires-Dist: pymsteams ~=0.2.2
|
31
32
|
Requires-Dist: scikit-learn ~=1.3
|
32
33
|
Requires-Dist: scipy ~=1.10
|
@@ -1,7 +1,9 @@
|
|
1
1
|
openstef/__init__.py,sha256=93UM6m0LLQhO69-mSqLuUy73jgs4W7Iuxfo3Lm8c98g,419
|
2
2
|
openstef/__main__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
3
|
+
openstef/app_settings.py,sha256=d1jqBz53JZbNeNp9IoFCQuzB2zZ_GZjEvvtSV7Hu1Yk,544
|
3
4
|
openstef/enums.py,sha256=f3Gw-HlNXeqMZahIAEYSZkPKtKWeNt3tfOJBL45Z2fM,629
|
4
5
|
openstef/exceptions.py,sha256=fVqjyrVMBiSGxcoZ3JfTcgZjIur1cPennZpfwqgc9qY,1992
|
6
|
+
openstef/settings.py,sha256=nSgkBqFxuqB3w7Rwo60i8j37c5ngDbt6vpjHS6QtJXQ,354
|
5
7
|
openstef/data/dutch_holidays_2020-2022.csv,sha256=pS-CjE0igYXd-2dG-MlqyvR2fgYgXkbNmgCKyTjmwxs,23704
|
6
8
|
openstef/data/dutch_holidays_2020-2022.csv.license,sha256=AxxHusqwIXU5RHl5ZMU65LyXmgtbj6QlcnFaOEN4kEE,145
|
7
9
|
openstef/data/pv_single_coefs.csv,sha256=jadIEYdHvl1lnV_06X_FASkJZ6C3Hecs5xZnH1gPMvI,24779
|
@@ -31,25 +33,25 @@ openstef/data_classes/prediction_job.py,sha256=lORSocNT8wkq4JhPFsDM8A3EDRi2Pyx28
|
|
31
33
|
openstef/data_classes/split_function.py,sha256=ljQIQQu1t1Y_CVWGAy25jrM6wG9odIVVQVimrT1n-1s,3358
|
32
34
|
openstef/feature_engineering/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
33
35
|
openstef/feature_engineering/apply_features.py,sha256=-3fyisOVj9ckIkRe2iYfWutbXSX8iqBkcvt8AYr-gmE,3906
|
34
|
-
openstef/feature_engineering/data_preparation.py,sha256=
|
36
|
+
openstef/feature_engineering/data_preparation.py,sha256=htca9LBO3ZN1D-iX4vXf0UN1fw_rRO7y6N3AuYVMpfk,5628
|
35
37
|
openstef/feature_engineering/feature_adder.py,sha256=aSqDl_gUrB3H2TD3cNvU5JniY_KOb4u4a2A6J7zB2BQ,6835
|
36
38
|
openstef/feature_engineering/feature_applicator.py,sha256=DR7jayrEMlra4BFL1Ps5WV2fxbkQ6VaOTa5RIKM-YNk,7447
|
37
|
-
openstef/feature_engineering/general.py,sha256=
|
39
|
+
openstef/feature_engineering/general.py,sha256=tgU4_1stag9jJmaQAfWCMhfBscznVuQvW5hPK_z9_9g,4438
|
38
40
|
openstef/feature_engineering/holiday_features.py,sha256=3Ff4Lkm26h8wJVoBplUewt4HfsvOUS9zj0x0MxewIm8,7842
|
39
41
|
openstef/feature_engineering/lag_features.py,sha256=Dr6qS8UhdgEHPZZSe-w6ibtjl_lcbcQohhqdZN9fqEU,5652
|
40
|
-
openstef/feature_engineering/weather_features.py,sha256=
|
42
|
+
openstef/feature_engineering/weather_features.py,sha256=Lr9DItyHvJ2CpWQ1r6A83tJKtR2k_Wwn32FdFTGblO0,15750
|
41
43
|
openstef/metrics/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
42
44
|
openstef/metrics/figure.py,sha256=KDoezYem9wdS13kUx7M7FOy-4u88Sg3OX1DuhNT6kgQ,9751
|
43
45
|
openstef/metrics/metrics.py,sha256=t2BIqflvmwzfa6UqS5jpAtNvailpDgD0J09bxjvGlMc,13341
|
44
|
-
openstef/metrics/reporter.py,sha256=
|
46
|
+
openstef/metrics/reporter.py,sha256=w1Q6xWoYGmvnjwjXik-Gz7_gnb0lOeJMep-whEV5mNk,7897
|
45
47
|
openstef/model/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
46
48
|
openstef/model/basecase.py,sha256=caI6Q-8y0ymlxGK9Js_H3Vh0q6ruNHlGD5RG0_kE5M0,2878
|
47
|
-
openstef/model/confidence_interval_applicator.py,sha256=
|
49
|
+
openstef/model/confidence_interval_applicator.py,sha256=XAk3m4gPhneCoQJlOmyEcoeI0sdHNC-ch4T1CWWHPrQ,8934
|
48
50
|
openstef/model/fallback.py,sha256=VV9ehgnoMZtWzqKk9H1t8wnERFh5CyC4TvDIuRP_ZDI,2861
|
49
|
-
openstef/model/model_creator.py,sha256
|
51
|
+
openstef/model/model_creator.py,sha256=q8gGsFvxcV4DUtlaUaAsJCD3Em4UA9k6CkL76gzwd_E,4979
|
50
52
|
openstef/model/objective.py,sha256=eqNBYGfhEVGegOm0PbizowuFImKblRqHgxkp9lgaKQc,13500
|
51
53
|
openstef/model/objective_creator.py,sha256=Rjd2YF1Ie9Z-au_v4fOuR63IcM69EEeoe_5Hj_Dz8-E,1970
|
52
|
-
openstef/model/serializer.py,sha256=
|
54
|
+
openstef/model/serializer.py,sha256=IUiiAWvoGVoWzmS-akI6LC7jHRY5Ln_vOCBZy1LnESY,17238
|
53
55
|
openstef/model/standard_deviation_generator.py,sha256=Od9bzXi2TLb1v8Nz-VhBMZHSopWH6ssaDe8gYLlqO1I,2911
|
54
56
|
openstef/model/metamodels/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
55
57
|
openstef/model/metamodels/grouped_regressor.py,sha256=yMN_a6TnQSyFaqlB_6Nifq-ydpb5hs6w_b97IaBbHj4,8337
|
@@ -67,37 +69,37 @@ openstef/model_selection/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYl
|
|
67
69
|
openstef/model_selection/model_selection.py,sha256=R34tJBecZo6IiUwCCRLeBI2ZCX6GP8W7FDBlGFWtmG8,11167
|
68
70
|
openstef/monitoring/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
69
71
|
openstef/monitoring/performance_meter.py,sha256=6aCGjJFXFq-7qwaJyBkF3MLqjgVK6FMFVcO-bcLLUb4,2803
|
70
|
-
openstef/monitoring/teams.py,sha256=
|
72
|
+
openstef/monitoring/teams.py,sha256=V62KEGUT_jxa9iIfm6-2NiVoSeYia_CP4E23lsoHP9g,6611
|
71
73
|
openstef/pipeline/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
72
|
-
openstef/pipeline/create_basecase_forecast.py,sha256=
|
73
|
-
openstef/pipeline/create_component_forecast.py,sha256=
|
74
|
-
openstef/pipeline/create_forecast.py,sha256=
|
75
|
-
openstef/pipeline/optimize_hyperparameters.py,sha256=
|
74
|
+
openstef/pipeline/create_basecase_forecast.py,sha256=YkpiqohETTAETb4GiVlK_btw5dpixJy2LmFZdm10iaI,4623
|
75
|
+
openstef/pipeline/create_component_forecast.py,sha256=A0dmILy_BuAAf2U_9i2FOj6KItIdZdGzi6hNDk-da4Q,6416
|
76
|
+
openstef/pipeline/create_forecast.py,sha256=F09civdIumNQwJq2hraea5QTQx7DgvEliXKs4Y3f8Mc,5689
|
77
|
+
openstef/pipeline/optimize_hyperparameters.py,sha256=qcwbNyTEpp2ncH1-j8LimE_ISFvn7JLUUFukW07Y-wg,11018
|
76
78
|
openstef/pipeline/train_create_forecast_backtest.py,sha256=7uNeY8dKtJLha_LkwroyU76oB54R9p3zRlTJAJj4OoI,6048
|
77
|
-
openstef/pipeline/train_model.py,sha256=
|
79
|
+
openstef/pipeline/train_model.py,sha256=wIiIt2iDd4juhmzBJ-lyq0cEi5oEXmPL8BBvsGBVrAs,19625
|
78
80
|
openstef/pipeline/utils.py,sha256=23mB31p19FoGWelLJzxNmqlzGwEr3fCDBEA37V2kpYY,2167
|
79
81
|
openstef/postprocessing/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
80
|
-
openstef/postprocessing/postprocessing.py,sha256=
|
82
|
+
openstef/postprocessing/postprocessing.py,sha256=vJZ57TZ3MbG4c78P2cq8Sxs6VHl6kjFvt_bie5dNK7U,9324
|
81
83
|
openstef/preprocessing/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
82
84
|
openstef/preprocessing/preprocessing.py,sha256=bM_cSSSb2vGTD79RGzUrI6KoELbzlCyJwc7jqQGNEsE,1454
|
83
85
|
openstef/tasks/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
84
|
-
openstef/tasks/calculate_kpi.py,sha256
|
86
|
+
openstef/tasks/calculate_kpi.py,sha256=oDru-mjtYnKz6ludzwkMBYvxTwbB9Ab5MIYnKDi47cQ,11788
|
85
87
|
openstef/tasks/create_basecase_forecast.py,sha256=Hk9fDljXvo5TfeS3nWHrerWi7y-lQzoJEaqWbqaxHOs,3852
|
86
|
-
openstef/tasks/create_components_forecast.py,sha256=
|
88
|
+
openstef/tasks/create_components_forecast.py,sha256=cvgtYqJ7kCTdEfpLEyrAyIsHfWxR17M2rPYdkZKsEU8,5869
|
87
89
|
openstef/tasks/create_forecast.py,sha256=FPILsCqt2lT2QIjseXyKjViZG6SVRoGCxoj9tPiozIg,5575
|
88
90
|
openstef/tasks/create_solar_forecast.py,sha256=bTr7NThTF6Yj405qAqRaJmlBUrL7HATqVVzsi9hMdMw,15049
|
89
91
|
openstef/tasks/create_wind_forecast.py,sha256=RhshkmNSyFWx4Y6yQn02GzHjWTREbN5A5GAeWv0JpcE,2907
|
90
92
|
openstef/tasks/optimize_hyperparameters.py,sha256=s-z8YQJF6Lf3DdYgKHEpAdlbFJ3a-0Gj0Ahsqj1DErc,4758
|
91
|
-
openstef/tasks/split_forecast.py,sha256=
|
93
|
+
openstef/tasks/split_forecast.py,sha256=1MBi1kKYR6R3H-NMo4At_0SdpVamWnT5sUXffRX84dI,9327
|
92
94
|
openstef/tasks/train_model.py,sha256=3-7QzyOFQ2jK_RHd7ISpFRnn0V9yEHCWQN3O8qLglqc,7475
|
93
95
|
openstef/tasks/utils/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
94
96
|
openstef/tasks/utils/dependencies.py,sha256=Jy9dtV_G7lTEa5Cdy--wvMxJuAb0adb3R0X4QDjVteM,3077
|
95
97
|
openstef/tasks/utils/predictionjobloop.py,sha256=Ysy3zF5lzPMz_asYDKeF5m0qgVT3tCtwSPihqMjnI5Q,9580
|
96
|
-
openstef/tasks/utils/taskcontext.py,sha256=
|
98
|
+
openstef/tasks/utils/taskcontext.py,sha256=L9K14ycwgVxbIVUjH2DIn_QWbnu-OfxcGtQ1K9T6sus,5630
|
97
99
|
openstef/validation/__init__.py,sha256=bIyGTSA4V5VoOLTwdaiJJAnozmpSzvQooVYlsf8H4eU,163
|
98
|
-
openstef/validation/validation.py,sha256=
|
99
|
-
openstef-3.4.
|
100
|
-
openstef-3.4.
|
101
|
-
openstef-3.4.
|
102
|
-
openstef-3.4.
|
103
|
-
openstef-3.4.
|
100
|
+
openstef/validation/validation.py,sha256=628xaDbAm8B4AYtFOAn8_SXLjejNfULGCfX3hVf_mU0,11119
|
101
|
+
openstef-3.4.18.dist-info/LICENSE,sha256=7Pm2fWFFHHUG5lDHed1vl5CjzxObIXQglnYsEdtjo_k,14907
|
102
|
+
openstef-3.4.18.dist-info/METADATA,sha256=bNqXKO-cH_fBcVXGvDILZ5hBNgpfDa9KDlumyEV4Qew,8166
|
103
|
+
openstef-3.4.18.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
104
|
+
openstef-3.4.18.dist-info/top_level.txt,sha256=kD0H4PqrQoncZ957FvqwfBxa89kTrun4Z_RAPs_HhLs,9
|
105
|
+
openstef-3.4.18.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|