diff --git a/jambo/schema_converter.py b/jambo/schema_converter.py index e2f4fe9..e69d1b8 100644 --- a/jambo/schema_converter.py +++ b/jambo/schema_converter.py @@ -9,17 +9,23 @@ from typing import Type class SchemaConverter: - @staticmethod - def build(schema): - try: - Validator.check_schema(schema) - except SchemaError as e: - raise ValueError(f"Invalid JSON Schema: {e}") + """ + Converts JSON Schema to Pydantic models. - if schema["type"] != "object": - raise TypeError( - f"Invalid JSON Schema: {schema['type']}. Only 'object' can be converted to Pydantic models." - ) + This class is responsible for converting JSON Schema definitions into Pydantic models. + It validates the schema and generates the corresponding Pydantic model with appropriate + fields and types. The generated model can be used for data validation and serialization. + """ + + @staticmethod + def build(schema: dict) -> Type: + """ + Converts a JSON Schema to a Pydantic model. + :param schema: The JSON Schema to convert. + :return: A Pydantic model class. + """ + if "title" not in schema: + raise ValueError("JSON Schema must have a title.") return SchemaConverter.build_object(schema["title"], schema) @@ -27,7 +33,19 @@ class SchemaConverter: def build_object( name: str, schema: dict, - ): + ) -> Type: + """ + Converts a JSON Schema object to a Pydantic model given a name. + :param name: + :param schema: + :return: + """ + + try: + Validator.check_schema(schema) + except SchemaError as e: + raise ValueError(f"Invalid JSON Schema: {e}") + if schema["type"] != "object": raise TypeError( f"Invalid JSON Schema: {schema['type']}. Only 'object' can be converted to Pydantic models." diff --git a/jambo/types/_type_parser.py b/jambo/types/_type_parser.py index 2a76d01..a2ec13f 100644 --- a/jambo/types/_type_parser.py +++ b/jambo/types/_type_parser.py @@ -1,6 +1,8 @@ from abc import ABC, abstractmethod from typing import Generic, Self, TypeVar +from pydantic import Field + T = TypeVar("T") @@ -17,7 +19,7 @@ class GenericTypeParser(ABC, Generic[T]): @abstractmethod def from_properties( name: str, properties: dict[str, any] - ) -> tuple[type[T], dict[str, any]]: ... + ) -> tuple[type[T], Field]: ... @classmethod def get_impl(cls, type_name: str) -> Self: diff --git a/jambo/types/int_type_parser.py b/jambo/types/int_type_parser.py index 121bdd4..4fa9778 100644 --- a/jambo/types/int_type_parser.py +++ b/jambo/types/int_type_parser.py @@ -1,3 +1,5 @@ +from dataclasses import Field + from jambo.types._type_parser import GenericTypeParser @@ -8,4 +10,15 @@ class IntTypeParser(GenericTypeParser): @staticmethod def from_properties(name, properties): - return int, {} + _field_properties = dict() + + if "minimum" in properties: + _field_properties["ge"] = properties["minimum"] + + if "maximum" in properties: + _field_properties["le"] = properties["maximum"] + + if "multipleOf" in properties: + _field_properties["multiple_of"] = properties["multipleOf"] + + return int, Field(**_field_properties) diff --git a/pyproject.toml b/pyproject.toml index 33a55b6..32fc4ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ dev = [ # POE Tasks [tool.poe.tasks] create-hooks = "bash .githooks/set-hooks.sh" - +tests = "python -m unittest discover -s tests -v" # Build System [tool.hatch.version] diff --git a/tests/test_type_parser.py b/tests/test_type_parser.py index b3a1886..c96c629 100644 --- a/tests/test_type_parser.py +++ b/tests/test_type_parser.py @@ -21,9 +21,10 @@ class TestTypeParser(unittest.TestCase): def test_int_parser(self): parser = IntTypeParser() - expected_definition = (int, {}) - self.assertEqual(parser.from_properties("placeholder", {}), expected_definition) + type_parsing, type_validator = parser.from_properties("placeholder", {}) + + self.assertEqual(type_parsing, int) def test_float_parser(self): parser = FloatTypeParser()