1
\$\begingroup\$

I have a method in a class that accepts either a datetime or string parameter. It is shown in the last code block (I didn't include the class). A little background is that I am defining a wrapper around an API, and I want the end user to be able to pass either a string or a date but convert that into the appropriate string for the API query.

I wrote a decorator that validates the dates, and converts the datetime to the appropriate string format for the subsequent call to the API. The decorator I wrote is defined outside of the class as a function.

  1. Should I include validate_date_helper in the scope of the wrapper?
  2. Is defining these functions outside of the class pythonic and is this a valid approach for what I am trying to accomplish?
  3. Are there other ways to accomplish validations like this?
from datetime import datetime as dt from typing import Union def validate_date_helper(date): """ validates a start date or updated after date. end """ utc_format = "%Y-%m-%dT%H:%M:%S" if isinstance(date, dt): date = date.strftime(utc_format) elif isinstance(date, str): utc_format_date = date + "T00:00:00" dt.strptime(utc_format_date, utc_format) else: raise ValueError(f"{date} must be datetime object or string") return date def validate_dates(func): def func_wrapper(self, *args, **kwargs): """ validates dates for the between function """ new_args = [] new_kwargs = {} for arg in args: arg = validate_date_helper(arg) new_args.append(arg) for key, val in kwargs.items(): if val is not None: val = validate_date_helper(val) new_kwargs[key] = val res = func(self, *new_args, **new_kwargs) return res return func_wrapper @validate_dates def between(self, start: Union[dt, str], end=None): """ sets startime and endtime for API query """ self.query["starttime"] = start # self.query is an empty dictionary at class instantiation if end is not None: self.query["endtime"] = end return self 
\$\endgroup\$
6
  • \$\begingroup\$It's not a validator if it returns new value.\$\endgroup\$
    – slepic
    CommentedNov 25, 2022 at 4:21
  • \$\begingroup\$I think that it's totally fine to declare this method outside the class. Its task is to preprocess an input, so the input adheres to some specification. The class is the user of this decorator. They aren't tightly coupled, nor necessarily belong together. But the helper function should be at least private or put inside the wrapper. And/or I would rename it to convert_date_to_string.\$\endgroup\$CommentedNov 25, 2022 at 6:11
  • 1
    \$\begingroup\$Please choose a title that describes what the app does, not the question you have. Thanks.\$\endgroup\$
    – ggorlen
    CommentedNov 25, 2022 at 6:53
  • \$\begingroup\$Welcome to Code Review! I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Please check that I haven't misrepresented your code, and correct it if I have.\$\endgroup\$CommentedNov 25, 2022 at 8:02
  • \$\begingroup\$@Green绿色 I went ahead and implemented the changed that you described. Should I make these edits in the post?\$\endgroup\$CommentedNov 27, 2022 at 0:31

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.