Skip to content

Commit

Permalink
style(cli.utils): renaming function.
Browse files Browse the repository at this point in the history
style(cli.utils): changing return type.
style(cli.utils): improving docstring.
style(cli.utils): using utils functions.
style(cli.data_add): moving validation of inputs to CLI function.
  • Loading branch information
victorgarcia98 committed May 4, 2023
1 parent bb045cd commit fe9f3f5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 49 deletions.
41 changes: 18 additions & 23 deletions flexmeasures/cli/data_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
from flexmeasures.utils.time_utils import server_now
from flexmeasures.utils.unit_utils import convert_units, ur
from flexmeasures.data.utils import save_to_db
from flexmeasures.cli.utils import get_timerange_from_flags
from flexmeasures.cli.utils import get_timerange_from_flag
from flexmeasures.data.models.reporting import Reporter
from timely_beliefs import BeliefsDataFrame

Expand Down Expand Up @@ -1175,11 +1175,6 @@ def add_schedule_for_storage(
help="Path to the output file of the results of the report."
"Use the `.csv` suffix to save the results as Comma Separated Values and `.xlsx` to export them as Excel sheets.",
)
@click.option(
"--timezone",
"timezone_optional",
help="timezone as string, e.g. 'UTC' or 'Europe/Amsterdam' (defaults to FLEXMEASURES_TIMEZONE config setting)",
)
@click.option(
"--last-hour",
"last_hour",
Expand Down Expand Up @@ -1230,31 +1225,31 @@ def add_report(
last_week: bool = False,
last_month: bool = False,
last_year: bool = False,
timezone_optional: Optional[str] = None,
):
"""
Create a new report using the Reporter class and save the results
to the database or export them as csv or excel file.
"""

check_timezone(timezone_optional)
# check that only 1 flag is provided
last_x_flags = [last_hour, last_day, last_week, last_month, last_year]
last_x_flag_given = last_x_flags.count(True) == 1

tz = pytz.timezone(
zone=timezone_optional
if timezone_optional
else app.config.get("FLEXMEASURES_TIMEZONE", "UTC")
)
if ((start is None) or (end is None)) and not last_x_flag_given:
click.secho(
"Either --start and --end or any of the --last-X flags should be provided.",
**MsgStyle.ERROR,
)
raise click.Abort()

start, end = get_timerange_from_flags(
start,
end,
tz,
last_hour=last_hour,
last_day=last_day,
last_week=last_week,
last_month=last_month,
last_year=last_year,
)
if last_x_flag_given:
start, end = get_timerange_from_flag(
last_hour=last_hour,
last_day=last_day,
last_week=last_week,
last_month=last_month,
last_year=last_year,
)

click.echo(f"Report scope:\n\tstart={start}\n\tend={end}")

Expand Down
1 change: 0 additions & 1 deletion flexmeasures/cli/tests/test_data_add.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ def test_add_reporter(app, db, setup_dummy_data, reporter_config_raw):
"reporter": "PandasReporter",
"start": "2023-04-10T00:00:00 00:00",
"end": "2023-04-10T10:00:00 00:00",
"timezone": "UTC",
"output_file": "test.csv",
}

Expand Down
61 changes: 36 additions & 25 deletions flexmeasures/cli/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import Tuple, Mapping, Optional
from typing import Tuple, Mapping
from datetime import datetime, timedelta


import click
from click_default_group import DefaultGroup

from flexmeasures.utils.time_utils import get_most_recent_hour


class MsgStyle(object):
"""Stores the text styles for the different events
Expand Down Expand Up @@ -65,42 +67,51 @@ def get_command(self, ctx, cmd_name):
return super().get_command(ctx, cmd_name)


def get_timerange_from_flags(
start: Optional[datetime], end: Optional[datetime], timezone, **kwargs
) -> Tuple[Optional[datetime], Optional[datetime]]:

flags = ["last_hour", "last_day", "last_week", "last_month", "last_year"]
def get_timerange_from_flag(
last_hour: bool = False,
last_day: bool = False,
last_week: bool = False,
last_month: bool = False,
last_year: bool = False,
) -> Tuple[datetime, datetime]:
"""This function returns a time range [start,end] of the last-X period.
See input parameters for more details.
:param bool last_hour: flag to get the time range of the last finished hour.
:param bool last_day: flag to get the time range for yesterday.
:param bool last_week: flag to get the time range of the previous 7 days.
:param bool last_month: flag to get the time range of last calendar month
:param bool last_year: flag to get the last completed calendar year
:returns: start:datetime, end:datetime
"""

# if any of the flag in `flags` is passed in kwargs
if len([kwarg for kwarg in kwargs if kwarg in flags]) > 0:
end = datetime.now(tz=timezone).replace(microsecond=0, second=0, minute=0)
else:
return start, end
current_hour = get_most_recent_hour()

""" Handle different flags """
if kwargs.get("last_hour"): # last finished hour
end = end
start = end - timedelta(hours=1)
if last_hour: # last finished hour
end = current_hour
start = current_hour - timedelta(hours=1)

if kwargs.get("last_day"): # yesterday
end = end.replace(hour=0)
start = end - timedelta(days=1)
if last_day: # yesterday
end = current_hour.replace(hour=0)
start = current_hour - timedelta(days=1)

if kwargs.get("last_week"): # last finished 7 week period.
end = end.replace(hour=0)
if last_week: # last finished 7 week period.
end = current_hour.replace(hour=0)
start = end - timedelta(days=7)

if kwargs.get("last_month"):
end = end.replace(hour=0) - timedelta(
if last_month:
end = current_hour.replace(hour=0) - timedelta(
days=end.day
) # to get the last day of the previous month
start = end - timedelta(
days=end.day - 1
) # equivalent to start.day = end.day-end.day +1

if kwargs.get("last_year"):
end = end.replace(hour=0) - timedelta(
if last_year: # last calendar year
end = current_hour.replace(hour=0) - timedelta(
days=end.day
) # to get the last day of the previous month
) # to get the last day of the previous year

start = end.replace(day=1, month=1)

return start, end

0 comments on commit fe9f3f5

Please sign in to comment.