2424from stac_pydantic .shared import BBox
2525from stac_pydantic .utils import AutoValueEnum
2626
27- from stac_fastapi .types .rfc3339 import rfc3339_str_to_datetime , str_to_interval
27+ from stac_fastapi .types .core import DateTimeType
28+ from stac_fastapi .types .rfc3339 import str_to_interval
2829
2930# Be careful: https://github.com/samuelcolvin/pydantic/issues/1423#issuecomment-642797287
3031NumType = Union [float , int ]
@@ -58,6 +59,14 @@ def str2list(x: str) -> Optional[List]:
5859 return x .split ("," )
5960
6061
62+ def str2bbox (x : str ) -> Optional [BBox ]:
63+ """Convert string to BBox based on , delimiter."""
64+ if x :
65+ t = tuple (float (v ) for v in str2list (x ))
66+ assert len (t ) == 4
67+ return t
68+
69+
6170@attr .s # type:ignore
6271class APIRequest (abc .ABC ):
6372 """Generic API Request base class."""
@@ -73,9 +82,9 @@ class BaseSearchGetRequest(APIRequest):
7382
7483 collections : Optional [str ] = attr .ib (default = None , converter = str2list )
7584 ids : Optional [str ] = attr .ib (default = None , converter = str2list )
76- bbox : Optional [str ] = attr .ib (default = None , converter = str2list )
85+ bbox : Optional [BBox ] = attr .ib (default = None , converter = str2bbox )
7786 intersects : Optional [str ] = attr .ib (default = None , converter = str2list )
78- datetime : Optional [str ] = attr .ib (default = None )
87+ datetime : Optional [DateTimeType ] = attr .ib (default = None , converter = str_to_interval )
7988 limit : Optional [int ] = attr .ib (default = 10 )
8089
8190
@@ -96,20 +105,18 @@ class BaseSearchPostRequest(BaseModel):
96105 intersects : Optional [
97106 Union [Point , MultiPoint , LineString , MultiLineString , Polygon , MultiPolygon ]
98107 ]
99- datetime : Optional [str ]
108+ datetime : Optional [DateTimeType ]
100109 limit : Optional [conint (gt = 0 , le = 10000 )] = 10
101110
102111 @property
103112 def start_date (self ) -> Optional [datetime ]:
104113 """Extract the start date from the datetime string."""
105- interval = str_to_interval (self .datetime )
106- return interval [0 ] if interval else None
114+ return self .datetime [0 ] if self .datetime else None
107115
108116 @property
109117 def end_date (self ) -> Optional [datetime ]:
110118 """Extract the end date from the datetime string."""
111- interval = str_to_interval (self .datetime )
112- return interval [1 ] if interval else None
119+ return self .datetime [1 ] if self .datetime else None
113120
114121 @validator ("intersects" )
115122 def validate_spatial (cls , v , values ):
@@ -118,10 +125,12 @@ def validate_spatial(cls, v, values):
118125 raise ValueError ("intersects and bbox parameters are mutually exclusive" )
119126 return v
120127
121- @validator ("bbox" )
122- def validate_bbox (cls , v : BBox ) :
128+ @validator ("bbox" , pre = True )
129+ def validate_bbox (cls , v : Union [ str , BBox ]) -> BBox :
123130 """Check order of supplied bbox coordinates."""
124131 if v :
132+ if type (v ) == str :
133+ v = str2bbox (v )
125134 # Validate order
126135 if len (v ) == 4 :
127136 xmin , ymin , xmax , ymax = v
@@ -148,34 +157,11 @@ def validate_bbox(cls, v: BBox):
148157
149158 return v
150159
151- @validator ("datetime" )
152- def validate_datetime (cls , v ):
153- """Validate datetime."""
154- if "/" in v :
155- values = v .split ("/" )
156- else :
157- # Single date is interpreted as end date
158- values = [".." , v ]
159-
160- dates = []
161- for value in values :
162- if value == ".." or value == "" :
163- dates .append (".." )
164- continue
165-
166- # throws ValueError if invalid RFC 3339 string
167- dates .append (rfc3339_str_to_datetime (value ))
168-
169- if dates [0 ] == ".." and dates [1 ] == ".." :
170- raise ValueError (
171- "Invalid datetime range, both ends of range may not be open"
172- )
173-
174- if ".." not in dates and dates [0 ] > dates [1 ]:
175- raise ValueError (
176- "Invalid datetime range, must match format (begin_date, end_date)"
177- )
178-
160+ @validator ("datetime" , pre = True )
161+ def validate_datetime (cls , v : Union [str , DateTimeType ]) -> DateTimeType :
162+ """Parse datetime."""
163+ if type (v ) == str :
164+ v = str_to_interval (v )
179165 return v
180166
181167 @property
0 commit comments