diff --git a/CHANGELOG.md b/CHANGELOG.md index ecd845d..3dd86cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. +## [0.8.4] - 2023-04-04 + +### Changed + +- Invalid datetime preset values will now throw a 406 error for `/preset` routes [#160](https://github.com/datajoint/pharus/pull/160) + ## [0.8.3] - 2023-03-24 ### Changed @@ -290,6 +296,7 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and - Support for DataJoint attribute types: `varchar`, `int`, `float`, `datetime`, `date`, `time`, `decimal`, `uuid`. - Check dependency utility to determine child table references. +[0.8.4]: https://github.com/datajoint/pharus/compare/0.8.3...0.8.4 [0.8.3]: https://github.com/datajoint/pharus/compare/0.8.2...0.8.3 [0.8.2]: https://github.com/datajoint/pharus/compare/0.8.1...0.8.2 [0.8.1]: https://github.com/datajoint/pharus/compare/0.8.0...0.8.1 diff --git a/pharus/component_interface.py b/pharus/component_interface.py index 11a5520..9d46fd7 100644 --- a/pharus/component_interface.py +++ b/pharus/component_interface.py @@ -15,6 +15,7 @@ from uuid import UUID import cv2 import base64 +from dateutil import parser class NumpyEncoder(json.JSONEncoder): @@ -246,6 +247,9 @@ def __init__(self, *args, **kwargs): for sub_m in (m.get("map", []) + [m]) } self.input_lookup = {v: k for k, v in self.destination_lookup.items()} + self.datatype_lookup = { + k: v[1] for t in self.tables for k, v in t.heading.attributes.items() + } if "presets" in self.component_config: lcls = locals() @@ -351,6 +355,14 @@ def presets_route(self): # If you have a name mapping it will be applied to each preset # Route will 404 if no preset query is defined and 500 if there is an Exception + # Helper function to convert datetime strings + def convert_datetime_string(datetime_string): + try: + dt = parser.parse(datetime_string) + return dt.strftime("%Y-%m-%d %H:%M:%S") + except ValueError: + raise ValueError("Invalid datetime string") + # Helper function to filter out fields not in the insert, # as well as apply the fields_map def filter_preset(preset: dict): @@ -367,10 +379,13 @@ def filter_preset(preset: dict): } return { ( - self.input_lookup[k.split(".").pop()] - if k.split(".").pop() in self.input_lookup - else k.split(".").pop() - ): v + self.input_lookup[a] + if (a := k.split(".").pop()) in self.input_lookup + else a + ): convert_datetime_string(v) + if a in self.datatype_lookup + and re.search(r"^date.*|time.*$", self.datatype_lookup[a]) + else v for k, v in preset_with_tables_filtered.items() } @@ -381,9 +396,16 @@ def filter_preset(preset: dict): {"Content-Type": "text/plain"}, ) - filtered_preset_dictionary = { - k: filter_preset(v) for k, v in self.presets_dict.items() - } + try: + filtered_preset_dictionary = { + k: filter_preset(v) for k, v in self.presets_dict.items() + } + except ValueError as e: + return ( + str(e), + 406, + {"Content-Type": "text/plain"}, + ) return ( NumpyEncoder.dumps(filtered_preset_dictionary), diff --git a/pharus/version.py b/pharus/version.py index 1c7f0b1..befb8ac 100644 --- a/pharus/version.py +++ b/pharus/version.py @@ -1,2 +1,2 @@ """Package metadata.""" -__version__ = "0.8.3" +__version__ = "0.8.4"