Coverage for app/models.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2026-06-04 22:29 +0000

1from datetime import datetime 

2from typing import Literal 

3from zoneinfo import ZoneInfo 

4 

5from dateutil.relativedelta import relativedelta 

6from pydantic import BaseModel, computed_field 

7 

8from app.normalization import NormalizedPackageName 

9 

10TIME_RANGE_MAPPING = { 

11 "1month": dict(months=1), 

12 "3months": dict(months=3), 

13 "6months": dict(months=6), 

14 "1year": dict(years=1), 

15 "2years": dict(years=2), 

16 "5years": dict(years=5), 

17} 

18 

19PYPI_DOWNLOADS_MIN_DATE = "2016-01-01" 

20 

21TimeRangeValidValues = Literal[ 

22 "1month", 

23 "3months", 

24 "6months", 

25 "1year", 

26 "2years", 

27 "5years", 

28 "allTime", 

29 "allTimeCumulative", 

30 "allTimeCumulativeAlignTimeline", 

31] 

32 

33 

34class TimeRange(BaseModel): 

35 value: TimeRangeValidValues = "3months" 

36 

37 @computed_field # type: ignore 

38 @property 

39 def date_str(self) -> str: 

40 if self.value in [ 

41 "allTime", 

42 "allTimeCumulative", 

43 "allTimeCumulativeAlignTimeline", 

44 ]: 

45 return PYPI_DOWNLOADS_MIN_DATE 

46 

47 return ( 

48 ( 

49 datetime.now(ZoneInfo("UTC")) 

50 - relativedelta(**(TIME_RANGE_MAPPING[self.value])) # type: ignore 

51 ) 

52 .date() 

53 .isoformat() 

54 ) 

55 

56 

57class QueryParams(BaseModel): 

58 packages: list[NormalizedPackageName] = [] 

59 time_range: TimeRange = TimeRange(value="3months") 

60 show_percentage: Literal["on"] | None = None 

61 error: str | None = None