-
Notifications
You must be signed in to change notification settings - Fork 67
Code improvements to time processing routines #1010
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
Conversation
29254b4
to
78f2bce
Compare
This is teriffic! Everything looks great, especially the changes in There might be a couple more changes w/ the
Then there are a few remaining bullets in #999...
|
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.
whoops, i had these comments pending and forgot to send them!
requirements.txt
Outdated
@@ -11,3 +11,4 @@ scipy==1.6.2 | |||
tenacity==7.0.0 | |||
newrelic | |||
epiweeks==2.1.2 | |||
typing-extensions==4.4.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.
maybe drop the version specification?
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.
Hm, isn't best practice to pin the version in case newer updates unexpectedly break?
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.
for the most part, yeah, but this is a fairly fundamental and python-authored package that i expect to "do the right thing" as it matures. pinning can also have negative consequences where you can get stuck with vulns or bugs or poor performance implementations. so... im not actually certain on what the best thing to do here, hence the "maybe" ¯_(ツ)_/¯
src/server/_params.py
Outdated
@@ -267,13 +267,13 @@ def parse_day_or_week_arg(key: str, default_value: Optional[int] = None) -> Tupl | |||
return parse_week_arg(key), False | |||
return parse_day_arg(key), True | |||
|
|||
def parse_day_or_week_range_arg(key: str) -> Tuple[Tuple[int, int], bool]: | |||
def parse_day_or_week_range_arg(key: str) -> TimePair: # Tuple[Tuple[int, int], bool]: |
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.
nice! great find & replacement :)
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 can also get rid of that comment w/ the old type hint)
@melange396 made a few more changes to the PR:
|
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.
looking good, modulo a few small details
""" | ||
if not pair: | ||
return "FALSE" |
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.
Question: is this a good code path to have? AFAICT there's an exception raised in covidcast.py:parse_time_pairs
if you don't have either: a) time=...
or b) time_type=...
and time_values=...
. So this will technically never happen in the API. So:
- Pro: function safety, can be reused in the future in other places that didn't have the same validation
- Con: confusing now, because it makes you think this is a possible code path
not super blocking, i can go either way, but curious what everyone thinks here, cc @melange396 @krivard
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.
Like you've mentioned, I'd rather have the extra failsafe for function safety so I kept this for now (but it should be trivial to remove if needed)
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.
im not actually sure what would be most correct here... it could arguably even be reasonable to return "TRUE"
-- if we are not filtering on any time, then all time values are valid.
since it is ambiguous, i think its good to leave that condition there but but also add a comment to the effect of "time values are required by the API, so this case should never be reached, but this check further ensures the desired behavior"
@dshemetov I've addressed your comments! (except for the |
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.
lgtm
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.
This is really great work, thank you for doing it. Do you feel like youve reduced the total complexity of the api server code? I feel like you did, and it makes me cringe at the api code less than before. :)
This all looks quite good to me, but i have a couple optional things you could look at; if you are getting burned out on this PR and wanna move on to something else, i can just turn them into new issues:
- We've made a bunch of changes to the type hinting stuff -- is all that still happy? Is your IDE set up to show mismatches and whatnot? I tried to run a type checker from the command line (with some limited success) and among other things i saw, it suggests it might help to change the type alias for TimePair to use List[...] instead of Sequence[...]
- Move the
*_to_ranges()
methods (and similar) to TimePair instance methods, so you can have callers be agnostic to week/day/whatever, then (for example) in_query.py:filter_time_pair()
, instead ofranges = weeks_to_ranges(pair.time_values) if pair.is_week else days_to_ranges(pair.time_values)
you can just doranges = pair.to_ranges()
andto_ranges()
does the appropriate thing for the time type of the TimePair. - Rename TimePair (and also various instances of time_pair variable names or similar) to something more appropriate. Youve done the hard work to make it better, you should get to choose a new class name.
Im gonna mark this as approved, but you should also add the comment in _params.py
, on the point Dmitry brought up.
""" | ||
if not pair: | ||
return "FALSE" |
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.
im not actually sure what would be most correct here... it could arguably even be reasonable to return "TRUE"
-- if we are not filtering on any time, then all time values are valid.
since it is ambiguous, i think its good to leave that condition there but but also add a comment to the effect of "time values are required by the API, so this case should never be reached, but this check further ensures the desired behavior"
Closes #999.
Prerequisites:
dev
branchdev
Summary
Refactors several parts of the datetime code as specified in #999. Specifically:
TimePair
objects as much as possible instead of lists of dates or individual datesguess_time_value_is_*
when absolutely necessarywhere_dates
week_value_to_week
, etc.