Skip to content

Commit a7b94ce

Browse files
committed
accept dates in string format for UUIDTmeRange
1 parent 8897224 commit a7b94ce

File tree

3 files changed

+80
-68
lines changed

3 files changed

+80
-68
lines changed

nbs/00_vector.ipynb

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,46 @@
296296
"source": [
297297
"#| export\n",
298298
"class UUIDTimeRange:\n",
299-
" def __init__(self, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, time_delta: Optional[timedelta] = None, start_inclusive=True, end_inclusive=False):\n",
299+
" \n",
300+
" @staticmethod\n",
301+
" def _parse_datetime(input_datetime: Union[datetime, str]):\n",
302+
" \"\"\"\n",
303+
" Parse a datetime object or string representation of a datetime.\n",
304+
"\n",
305+
" Args:\n",
306+
" input_datetime (datetime or str): Input datetime or string.\n",
307+
"\n",
308+
" Returns:\n",
309+
" datetime: Parsed datetime object.\n",
310+
"\n",
311+
" Raises:\n",
312+
" ValueError: If the input cannot be parsed as a datetime.\n",
313+
" \"\"\"\n",
314+
" if input_datetime is None or input_datetime == \"None\":\n",
315+
" return None\n",
316+
" \n",
317+
" if isinstance(input_datetime, datetime):\n",
318+
" # If input is already a datetime object, return it as is\n",
319+
" return input_datetime\n",
320+
"\n",
321+
" if isinstance(input_datetime, str):\n",
322+
" try:\n",
323+
" # Attempt to parse the input string into a datetime\n",
324+
" return datetime.fromisoformat(input_datetime)\n",
325+
" except ValueError:\n",
326+
" raise ValueError(\"Invalid datetime string format: {}\".format(input_datetime))\n",
327+
"\n",
328+
" raise ValueError(\"Input must be a datetime object or string\")\n",
329+
"\n",
330+
" def __init__(self, start_date: Optional[Union[datetime, str]] = None, end_date: Optional[Union[datetime, str]] = None, time_delta: Optional[timedelta] = None, start_inclusive=True, end_inclusive=False):\n",
300331
" \"\"\"\n",
301332
" A UUIDTimeRange is a time range predicate on the UUID Version 1 timestamps. \n",
302333
" \n",
303334
" Note that naive datetime objects are interpreted as local time on the python client side and converted to UTC before being sent to the database.\n",
304335
" \"\"\"\n",
336+
" start_date = UUIDTimeRange._parse_datetime(start_date)\n",
337+
" end_date = UUIDTimeRange._parse_datetime(end_date)\n",
338+
"\n",
305339
" if start_date is not None and end_date is not None:\n",
306340
" if start_date > end_date:\n",
307341
" raise Exception(\"start_date must be before end_date\")\n",
@@ -726,36 +760,6 @@
726760
" raise ValueError(\"Unknown filter type: {filter_type}\".format(filter_type=type(filter)))\n",
727761
"\n",
728762
" return (where, params)\n",
729-
" \n",
730-
" def _parse_datetime(self, input_datetime):\n",
731-
" \"\"\"\n",
732-
" Parse a datetime object or string representation of a datetime.\n",
733-
"\n",
734-
" Args:\n",
735-
" input_datetime (datetime or str): Input datetime or string.\n",
736-
"\n",
737-
" Returns:\n",
738-
" datetime: Parsed datetime object.\n",
739-
"\n",
740-
" Raises:\n",
741-
" ValueError: If the input cannot be parsed as a datetime.\n",
742-
" \"\"\"\n",
743-
" if input_datetime is None:\n",
744-
" return None\n",
745-
" \n",
746-
" if isinstance(input_datetime, datetime):\n",
747-
" # If input is already a datetime object, return it as is\n",
748-
" return input_datetime\n",
749-
"\n",
750-
" if isinstance(input_datetime, str):\n",
751-
" try:\n",
752-
" # Attempt to parse the input string into a datetime\n",
753-
" return datetime.fromisoformat(input_datetime)\n",
754-
" except ValueError:\n",
755-
" raise ValueError(\"Invalid datetime string format\")\n",
756-
"\n",
757-
" raise ValueError(\"Input must be a datetime object or string\")\n",
758-
"\n",
759763
"\n",
760764
" def search_query(\n",
761765
" self, \n",
@@ -785,8 +789,8 @@
785789
" if self.infer_filters:\n",
786790
" if uuid_time_filter is None and isinstance(filter, dict):\n",
787791
" if \"__start_date\" in filter or \"__end_date\" in filter:\n",
788-
" start_date = self._parse_datetime(filter.get(\"__start_date\"))\n",
789-
" end_date = self._parse_datetime(filter.get(\"__end_date\"))\n",
792+
" start_date = UUIDTimeRange._parse_datetime(filter.get(\"__start_date\"))\n",
793+
" end_date = UUIDTimeRange._parse_datetime(filter.get(\"__end_date\"))\n",
790794
" \n",
791795
" uuid_time_filter = UUIDTimeRange(start_date, end_date)\n",
792796
" \n",
@@ -1506,6 +1510,8 @@
15061510
" #using uuid_time_filter\n",
15071511
" rec = await vec.search([1.0, 2.0], limit=4, uuid_time_filter=UUIDTimeRange(start_date, end_date))\n",
15081512
" assert len(rec) == expected\n",
1513+
" rec = await vec.search([1.0, 2.0], limit=4, uuid_time_filter=UUIDTimeRange(str(start_date), str(end_date)))\n",
1514+
" assert len(rec) == expected\n",
15091515
" \n",
15101516
" #using filters\n",
15111517
" filter = {}\n",
@@ -2248,6 +2254,8 @@
22482254
" #using uuid_time_filter\n",
22492255
" rec = vec.search([1.0, 2.0], limit=4, uuid_time_filter=UUIDTimeRange(start_date, end_date))\n",
22502256
" assert len(rec) == expected\n",
2257+
" rec = vec.search([1.0, 2.0], limit=4, uuid_time_filter=UUIDTimeRange(str(start_date), str(end_date)))\n",
2258+
" assert len(rec) == expected\n",
22512259
" \n",
22522260
" #using filters\n",
22532261
" filter = {}\n",

timescale_vector/_modidx.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@
7878
'timescale_vector/client.py'),
7979
'timescale_vector.client.QueryBuilder._get_embedding_index_name': ( 'vector.html#querybuilder._get_embedding_index_name',
8080
'timescale_vector/client.py'),
81-
'timescale_vector.client.QueryBuilder._parse_datetime': ( 'vector.html#querybuilder._parse_datetime',
82-
'timescale_vector/client.py'),
8381
'timescale_vector.client.QueryBuilder._quote_ident': ( 'vector.html#querybuilder._quote_ident',
8482
'timescale_vector/client.py'),
8583
'timescale_vector.client.QueryBuilder._where_clause_for_filter': ( 'vector.html#querybuilder._where_clause_for_filter',
@@ -153,6 +151,8 @@
153151
'timescale_vector/client.py'),
154152
'timescale_vector.client.UUIDTimeRange.__str__': ( 'vector.html#uuidtimerange.__str__',
155153
'timescale_vector/client.py'),
154+
'timescale_vector.client.UUIDTimeRange._parse_datetime': ( 'vector.html#uuidtimerange._parse_datetime',
155+
'timescale_vector/client.py'),
156156
'timescale_vector.client.UUIDTimeRange.build_query': ( 'vector.html#uuidtimerange.build_query',
157157
'timescale_vector/client.py'),
158158
'timescale_vector.client.uuid_from_time': ( 'vector.html#uuid_from_time',

timescale_vector/client.py

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,46 @@ def create_index_query(self, table_name_quoted:str, column_name_quoted: str, ind
200200

201201
# %% ../nbs/00_vector.ipynb 11
202202
class UUIDTimeRange:
203-
def __init__(self, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, time_delta: Optional[timedelta] = None, start_inclusive=True, end_inclusive=False):
203+
204+
@staticmethod
205+
def _parse_datetime(input_datetime: Union[datetime, str]):
206+
"""
207+
Parse a datetime object or string representation of a datetime.
208+
209+
Args:
210+
input_datetime (datetime or str): Input datetime or string.
211+
212+
Returns:
213+
datetime: Parsed datetime object.
214+
215+
Raises:
216+
ValueError: If the input cannot be parsed as a datetime.
217+
"""
218+
if input_datetime is None or input_datetime == "None":
219+
return None
220+
221+
if isinstance(input_datetime, datetime):
222+
# If input is already a datetime object, return it as is
223+
return input_datetime
224+
225+
if isinstance(input_datetime, str):
226+
try:
227+
# Attempt to parse the input string into a datetime
228+
return datetime.fromisoformat(input_datetime)
229+
except ValueError:
230+
raise ValueError("Invalid datetime string format: {}".format(input_datetime))
231+
232+
raise ValueError("Input must be a datetime object or string")
233+
234+
def __init__(self, start_date: Optional[Union[datetime, str]] = None, end_date: Optional[Union[datetime, str]] = None, time_delta: Optional[timedelta] = None, start_inclusive=True, end_inclusive=False):
204235
"""
205236
A UUIDTimeRange is a time range predicate on the UUID Version 1 timestamps.
206237
207238
Note that naive datetime objects are interpreted as local time on the python client side and converted to UTC before being sent to the database.
208239
"""
240+
start_date = UUIDTimeRange._parse_datetime(start_date)
241+
end_date = UUIDTimeRange._parse_datetime(end_date)
242+
209243
if start_date is not None and end_date is not None:
210244
if start_date > end_date:
211245
raise Exception("start_date must be before end_date")
@@ -615,36 +649,6 @@ def _where_clause_for_filter(self, params: List, filter: Optional[Union[Dict[str
615649
raise ValueError("Unknown filter type: {filter_type}".format(filter_type=type(filter)))
616650

617651
return (where, params)
618-
619-
def _parse_datetime(self, input_datetime):
620-
"""
621-
Parse a datetime object or string representation of a datetime.
622-
623-
Args:
624-
input_datetime (datetime or str): Input datetime or string.
625-
626-
Returns:
627-
datetime: Parsed datetime object.
628-
629-
Raises:
630-
ValueError: If the input cannot be parsed as a datetime.
631-
"""
632-
if input_datetime is None:
633-
return None
634-
635-
if isinstance(input_datetime, datetime):
636-
# If input is already a datetime object, return it as is
637-
return input_datetime
638-
639-
if isinstance(input_datetime, str):
640-
try:
641-
# Attempt to parse the input string into a datetime
642-
return datetime.fromisoformat(input_datetime)
643-
except ValueError:
644-
raise ValueError("Invalid datetime string format")
645-
646-
raise ValueError("Input must be a datetime object or string")
647-
648652

649653
def search_query(
650654
self,
@@ -674,8 +678,8 @@ def search_query(
674678
if self.infer_filters:
675679
if uuid_time_filter is None and isinstance(filter, dict):
676680
if "__start_date" in filter or "__end_date" in filter:
677-
start_date = self._parse_datetime(filter.get("__start_date"))
678-
end_date = self._parse_datetime(filter.get("__end_date"))
681+
start_date = UUIDTimeRange._parse_datetime(filter.get("__start_date"))
682+
end_date = UUIDTimeRange._parse_datetime(filter.get("__end_date"))
679683

680684
uuid_time_filter = UUIDTimeRange(start_date, end_date)
681685

0 commit comments

Comments
 (0)