1

I have a small REST API with Python and Flask, and for some GET requests I need to accept a look-behind time duration parameter, e.g. "A months, B days, C hours, D minutes".

This parameter will be parsed from a query string, but I'm a bit unsure how I should be structuring my query string for parsing. There are other fields in the query string besides the look-behind, which complicates things a bit.

There are two main options I have come up with.

  1. Accept a single field for the look-behind in the query string, e.g. "8months5days", then extend some regex solution like virhilo's here for the string passed:

    regex = re.compile(r'((?P<hours>\d+?)hr)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')
    

    after which I can construct a datetime.timedelta from the result.

  2. Accept several fields for different components of a time duration in my query string, e.g. "behind_m=8&behind_d=5". Then use urllib to get a dictionary of the full query string,

    query_d = parse_qs(request.query_string)
    

    and finally take the intersection of query_d with a dictionary like

    durations = {'behind_m': 'months', 'behind_d': 'days', 'behind_y': 'years', ...}
    

    after which I can directly construct a datetime.timedelta.

My natural inclination is to go for the second option, since I am weak with regex and I like the clarity. However, I could end up requiring multiple time durations in some query strings, which will result in enormously long query strings in some cases.

Is there a good way to accomplish this, and is that way regex? I understand that the entire task would be much simpler if there was a clean way to parse a time duration from some string format, but despite looking at datetime and dateutil I haven't found any support for duration parsing.

Community
  • 1
  • 1
Eric Hansen
  • 1,749
  • 2
  • 19
  • 39
  • I would use purely seconds and drop the other units. You could then use relative seconds or seconds since epoch – Alastair McCormack Feb 06 '17 at 16:56
  • @AlastairMcCormack Yeahh I agree actually, this makes sense. I haven't really implemented a front-end framework to communicate with the API yet and so had myself sort of fixed on having query strings someone could easily provide themselves, so that's why that didn't cross my mind. But it is sensible I think. Thank you! – Eric Hansen Feb 06 '17 at 17:07

1 Answers1

0

My tool of choice would be a comma separated list in the URI:

?behind=2,1,20,1,23,3

Resolving to:

durations = {'years': 2, 'months': 1, 'days': 20, hours: 1, minutes: 23, seconds: 3}

Based on the common use case (if you are entering more longer durations or short ones) I'd decide either to go for the format year,months,days,hours,minutes,seconds or the reverse.

To build this dict you can splitthe string and put it into the dict:

identifiers = ['years', 'months', 'days', 'hours', 'minutes', 'seconds']
components = behind.split(str=",")
duration = dict(zip(identifiers, components))
kiecodes
  • 1,642
  • 14
  • 28