-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Recurring time window filter #51
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 suggestions.
Comments skipped due to low confidence (1)
featuremanagement/_time_window_filter/_recurrence_validator.py:113
- The error message should specify the exact parameters for clarity, e.g., 'The Recurrence.Range.EndDate should be after the Start date'.
raise ValueError("The Recurrence.Range.EndDate should be after the Start")
sorted_days_of_week = _sort_days_of_week(pattern.days_of_week, pattern.first_day_of_week) | ||
max_day_offset = _get_passed_week_days(sorted_days_of_week[-1], pattern.first_day_of_week) | ||
min_day_offset = _get_passed_week_days(sorted_days_of_week[0], pattern.first_day_of_week) | ||
num_of_occurrences = number_of_interval * len(sorted_days_of_week) - sorted_days_of_week.index(start.weekday()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The calculation of num_of_occurrences is incorrect. It should be 'number_of_interval * len(sorted_days_of_week) + sorted_days_of_week.index(start.weekday())'.
num_of_occurrences = number_of_interval * len(sorted_days_of_week) - sorted_days_of_week.index(start.weekday()) | |
num_of_occurrences = number_of_interval * len(sorted_days_of_week) + sorted_days_of_week.index(start.weekday()) |
Copilot is powered by AI, so mistakes are possible. Review output carefully before use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure I have it correct here. https://github.com/microsoft/FeatureManagement-Dotnet/blob/325271bd622aa43d041b366c7ba2e9c30507e5a0/src/Microsoft.FeatureManagement/FeatureFilters/Recurrence/RecurrenceEvaluator.cs#L244, maybe it's the name causing an issue.
if range_data.get("EndDate") and isinstance(range_data.get("EndDate"), str): | ||
end_date_str = range_data.get("EndDate", "") | ||
self.end_date = parsedate_to_datetime(end_date_str) if end_date_str else None | ||
self.num_of_occurrences = range_data.get("NumberOfOccurrences") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed the default value. BTW, it is possible to get non number value or negative value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the default value 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python doesn't have a "Max Int" value. We could do something like math.pow(2, 63) - 1
.
raise ValueError("The interval must be greater than 0.") | ||
days_of_week = pattern_data.get("DaysOfWeek", []) | ||
for day in days_of_week: | ||
self.days_of_week.append(self.days.index(day)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You didn't initialize self.days_of_week as []
@@ -31,6 +41,8 @@ | |||
FEATURE_FILTER_NAME_KEY = "Name" | |||
IGNORE_CASE_KEY = "ignore_case" | |||
|
|||
logger = logging.getLogger(__name__) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra empty line
if recurrence: | ||
if start_time and end_time: | ||
settings = TimeWindowFilterSettings(start_time, end_time, recurrence) | ||
return is_match(settings, current_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better timewindow evaluation is
if not start and not end:
return False
if (start_time is None or start_time <= current_time) and (end_time is None or current_time < end_time):
return True
if recurrence_data:
recurrence = Recurrence(recurrence_data)
settings = TimeWindowFilterSettings(start_time, end_time, recurrence)
return is_match(settings, current_time)
return False
In is_match
, you will validate settings (which may take some time), if the current time hits the first time window (specified by start
and end
), we can save the recurrence evaluation.
""" | ||
validate_settings(settings) | ||
|
||
previous_occurrence = _get_previous_occurrence(settings, now) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about returning False directly here if now < start here
. In this way, we can save a function call (very slightly improve the performance).
pattern_type = settings.recurrence.pattern.type | ||
if pattern_type == RecurrencePatternType.DAILY: | ||
occurrence_info = _get_daily_previous_occurrence(settings, now) | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You didn't validate pattern type. Here you assume the pattern type must be either DAILY or WEEKLY. But this is not guaranteed.
How about
if pattern_type == RecurrencePatternType.DAILY:
occurrence_info = _get_daily_previous_occurrence(settings, now)
elif pattern_type == RecurrencePatternType.WEEKLY:
occurrence_info = _get_weekly_previous_occurrence(settings, now)
else:
throw
recurrence_range = settings.recurrence.range | ||
range_type = recurrence_range.type | ||
previous_occurrence = occurrence_info.previous_occurrence | ||
end_date = recurrence_range.end_date |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a string or datetime type?
|
||
def _sort_days_of_week(days_of_week: List[int], first_day_of_week: int) -> List[int]: | ||
sorted_days = sorted(days_of_week) | ||
return sorted_days[sorted_days.index(first_day_of_week) :] + sorted_days[: sorted_days.index(first_day_of_week)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What will happen if first_day_of_week
is not in the list?
from ._models import RecurrencePatternType, RecurrenceRangeType, TimeWindowFilterSettings | ||
|
||
|
||
DAYS_PER_WEEK = 7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other files, you used number 7 directly. So maybe we don't need this variable here.
for day in days_of_week: | ||
self.days_of_week.append(self.days.index(day)) | ||
first_day_of_week = pattern_data.get("FirstDayOfWeek", "Sunday") | ||
self.first_day_of_week = self.days.index(first_day_of_week) if first_day_of_week in self.days else 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from email.utils import parsedate_to_datetime
s = "Sun, 05 Jan 2025 20:00:00 GMT"
t = parsedate_to_datetime(s)
print(t.weekday())
This produced 6 on my laptop, I am using python 3.11.9.
first day of week should be Sunday by default. Sunday index is 6 and Monday is 0.
Description
Add the Recurring time window filter to python Feature Management.