Skip to content

Commit

Permalink
Renaming and refactoring methods from AwsCronite class
Browse files Browse the repository at this point in the history
  • Loading branch information
siddarth-patil committed Dec 30, 2024
1 parent c98cdf0 commit a9fe1d5
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 39 deletions.
35 changes: 14 additions & 21 deletions src/aws_croniter/aws_croniter.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,63 +169,57 @@ def __parse_one_rule(rule, min_value, max_value):
allows.sort()
return allows

@staticmethod
def get_next_n_schedule(n, from_date, cron):
def get_next(self, from_date, n=1, inclusive=False):
"""
Returns a list with the n next datetime(s) that match the aws cron expression from the provided start date.
:param n: Int of the n next datetime(s)
:param from_date: datetime with the start date
:param cron: str of aws cron to be parsed
:param n: Int of the n next datetime(s), defaults to 1
:param inclusive: If True, include the from_date time if it matches a valid execution.
:return: list of datetime objects
"""
schedule_list = list()
if not isinstance(from_date, datetime.datetime):
raise ValueError(
"Invalid from_date. Must be of type datetime.datetime" " and have tzinfo = datetime.timezone.utc"
"Invalid from_date. Must be of type datetime.datetime and have tzinfo = datetime.timezone.utc"
)
else:
cron_iterator = AwsCroniter(cron)
schedule_list = list()
for i in range(n):
from_date = cron_iterator.occurrence(from_date).next()
from_date = self.occurrence(from_date).next(inclusive=(inclusive and i == 0))
schedule_list.append(from_date)

return schedule_list

@staticmethod
def get_prev_n_schedule(n, from_date, cron):
def get_prev(self, from_date, n=1, inclusive=False):
"""
Returns a list with the n prev datetime(s) that match the aws cron expression
from the provided start date.
:param n: Int of the n next datetime(s)
:param from_date: datetime with the start date
:param cron: str of aws cron to be parsed
:param n: Int of the n next datetime(s), defaults to 1
:param inclusive: If True, include the from_date time if it matches a valid execution.
:return: list of datetime objects
"""
schedule_list = list()
if not isinstance(from_date, datetime.datetime):
raise ValueError(
"Invalid from_date. Must be of type datetime.datetime" " and have tzinfo = datetime.timezone.utc"
)
else:
cron_iterator = AwsCroniter(cron)
schedule_list = list()
for i in range(n):
from_date = cron_iterator.occurrence(from_date).prev()
from_date = self.occurrence(from_date).prev(inclusive=(inclusive and i == 0))
schedule_list.append(from_date)

return schedule_list

@staticmethod
def get_all_schedule_bw_dates(from_date, to_date, cron, exclude_ends=False):
def get_all_schedule_bw_dates(self, from_date, to_date, exclude_ends=False):
"""
Get all datetimes from from_date to to_date matching the given cron expression.
Get all datetime(s) from from_date to to_date matching the given cron expression.
If the cron expression matches either 'from_date' and/or 'to_date',
those times will be returned as well unless 'exclude_ends=True' is passed.
:param from_date: datetime object from where the schedule will start with tzinfo in utc.
:param to_date: datetime object to where the schedule will end with tzinfo in utc.
:param cron: str of aws cron to be parsed
:param exclude_ends: bool defaulted to False, to not exclude the end date
:return: list of datetime objects
"""
Expand All @@ -244,12 +238,11 @@ def get_all_schedule_bw_dates(from_date, to_date, cron, exclude_ends=False):
)
else:
schedule_list = []
cron_iterator = AwsCroniter(cron)
start = from_date.replace(second=0, microsecond=0) - datetime.timedelta(seconds=1)
stop = to_date.replace(second=0, microsecond=0)

while start is not None and start <= stop:
start = cron_iterator.occurrence(start).next()
start = self.occurrence(start).next()
if start is None or start > stop:
break
schedule_list.append(start)
Expand Down
12 changes: 6 additions & 6 deletions src/aws_croniter/occurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,31 +142,31 @@ def __find_prev_once(self, parsed, datetime_from: datetime):

return datetime.datetime(year, month, day_of_month, hour, minute, tzinfo=datetime.timezone.utc)

def next(self, datetime_inclusive=False):
def next(self, inclusive=False):
"""
Generate the next occurrence after the current time.
:param datetime_inclusive: If True, include the current time if it matches a valid execution.
:param inclusive: If True, include the current time if it matches a valid execution.
:return: The next occurrence as a datetime object.
"""
self.iter = 0
from_epoch = (math.floor(TimeUtils.datetime_to_millisec(self.utc_datetime) / 60000.0) + 1) * 60000
if datetime_inclusive:
if inclusive:
# Do not add extra minute, include current time
from_epoch = math.floor(TimeUtils.datetime_to_millisec(self.utc_datetime) / 60000.0) * 60000
dt = datetime.datetime.fromtimestamp(from_epoch / 1000.0, tz=datetime.timezone.utc)
return self.__find_once(self.cron, dt)

def prev(self, datetime_inclusive=False):
def prev(self, inclusive=False):
"""
Generate the prev before the occurrence date value
:param datetime_inclusive: If True, include the current time if it matches a valid execution.
:param inclusive: If True, include the current time if it matches a valid execution.
:return: The next occurrence as a datetime object.
"""
self.iter = 0
from_epoch = (math.floor(TimeUtils.datetime_to_millisec(self.utc_datetime) / 60000.0) - 1) * 60000
if datetime_inclusive:
if inclusive:
# Do not subtract extra minute, include current time
from_epoch = math.floor(TimeUtils.datetime_to_millisec(self.utc_datetime) / 60000.0) * 60000
dt = datetime.datetime.fromtimestamp(from_epoch / 1000.0, tz=datetime.timezone.utc)
Expand Down
20 changes: 12 additions & 8 deletions tests/test_awscron.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,12 @@ def test_get_all_schedule_bw_dates(from_dt, to_date, cron_expression, exclude_en
"""
Parameterized test for retrieving all schedule times between dates.
"""
result = AwsCroniter.get_all_schedule_bw_dates(from_dt, to_date, cron_expression, exclude_ends)
itr = AwsCroniter(cron_expression)
result = itr.get_all_schedule_bw_dates(from_dt, to_date, exclude_ends)
assert str(expected_list) == str(result)


def test_get_next_n_schedule():
def test_get_next():
"""Testing - retrieve n number of datetimes after start date when AWS cron expression is set to
run every 23 minutes. cron(Minutes Hours Day-of-month Month Day-of-week Year)
Where start datetime is 8/7/2021 8:30:57 UTC
Expand All @@ -295,11 +296,12 @@ def test_get_next_n_schedule():
datetime.datetime(2021, 8, 7, 11, 46, tzinfo=datetime.timezone.utc),
]
from_dt = datetime.datetime(2021, 8, 7, 8, 30, 57, tzinfo=datetime.timezone.utc)
result = AwsCroniter.get_next_n_schedule(10, from_dt, "0/23 * * * ? *")
assert str(expected_list) == str(result) # noqa: S101
itr = AwsCroniter("0/23 * * * ? *")
result = itr.get_next(from_dt, 10)
assert str(expected_list) == str(result)


def test_get_prev_n_schedule_1():
def test_get_prev_1():
"""Testing - retrieve n number of datetimes before start date when AWS cron expression is set to
run every 23 minutes. cron(Minutes Hours Day-of-month Month Day-of-week Year)
Where start datetime is 8/7/2021 11:50:57 UTC
Expand All @@ -317,11 +319,12 @@ def test_get_prev_n_schedule_1():
datetime.datetime(2021, 8, 7, 8, 46, tzinfo=datetime.timezone.utc),
]
from_dt = datetime.datetime(2021, 8, 7, 11, 50, 57, tzinfo=datetime.timezone.utc)
result = AwsCroniter.get_prev_n_schedule(10, from_dt, "0/23 * * * ? *")
itr = AwsCroniter("0/23 * * * ? *")
result = itr.get_prev(from_dt, 10)
assert str(expected_list) == str(result)


def test_get_prev_n_schedule_2():
def test_get_prev_2():
"""Testing - retrieve n number of datetimes before start date when AWS cron expression is set to
run every 5 minutes Monday through Friday between 8:00 am and 5:55 pm (UTC).
cron(Minutes Hours Day-of-month Month Day-of-week Year)
Expand All @@ -340,5 +343,6 @@ def test_get_prev_n_schedule_2():
datetime.datetime(2021, 8, 16, 8, 0, tzinfo=datetime.timezone.utc),
]
from_dt = datetime.datetime(2021, 8, 16, 8, 50, 57, tzinfo=datetime.timezone.utc)
result = AwsCroniter.get_prev_n_schedule(10, from_dt, "0/5 8-17 ? * MON-FRI *")
itr = AwsCroniter("0/5 8-17 ? * MON-FRI *")
result = itr.get_prev(from_dt, 10)
assert str(expected_list) == str(result)
8 changes: 4 additions & 4 deletions tests/test_occurrence.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from aws_croniter.aws_croniter import AwsCroniter


def test_generate_next_occurrence_with_datetime_inclusive():
def test_generate_next_occurrence_with_inclusive():
cron = "23 17 25 7 ? 2020"
expected_occurrence = "2020-07-25 17:23:00+00:00"
cron = AwsCroniter(cron)
dt = datetime.datetime(2020, 7, 25, 17, 23, 57, tzinfo=datetime.timezone.utc)
dt = cron.occurrence(dt).next(datetime_inclusive=True)
dt = cron.occurrence(dt).next(inclusive=True)
assert expected_occurrence == str(dt)


Expand Down Expand Up @@ -208,10 +208,10 @@ def test_generate_multiple_prev_occurrences1():
assert str(dt) == expected


def test_generate_prev_occurrence_with_datetime_inclusive():
def test_generate_prev_occurrence_with_inclusive():
cron = "23 17 25 7 ? 2020"
expected_occurrence = "2020-07-25 17:23:00+00:00"
cron = AwsCroniter(cron)
dt = datetime.datetime(2020, 7, 25, 17, 23, 57, tzinfo=datetime.timezone.utc)
dt = cron.occurrence(dt).prev(datetime_inclusive=True)
dt = cron.occurrence(dt).prev(inclusive=True)
assert expected_occurrence == str(dt)

0 comments on commit a9fe1d5

Please sign in to comment.