From d3a2f1e76c8ddba7409177ee8ee188514aebfb2e Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Wed, 20 Aug 2025 00:25:02 -0300 Subject: [PATCH 1/2] (improvement): Adds More Type Formats to String Parser --- jambo/parser/string_type_parser.py | 21 +++++++++++++++------ tests/parser/test_string_type_parser.py | 11 +++++++---- tests/test_schema_converter.py | 4 ++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/jambo/parser/string_type_parser.py b/jambo/parser/string_type_parser.py index 7e94b0d..21e1fd6 100644 --- a/jambo/parser/string_type_parser.py +++ b/jambo/parser/string_type_parser.py @@ -1,10 +1,12 @@ from jambo.parser._type_parser import GenericTypeParser from jambo.types.type_parser_options import TypeParserOptions -from pydantic import EmailStr, HttpUrl, IPvAnyAddress +from pydantic import AnyUrl, EmailStr from typing_extensions import Unpack from datetime import date, datetime, time, timedelta +from ipaddress import IPv4Address, IPv6Address +from uuid import UUID class StringTypeParser(GenericTypeParser): @@ -20,15 +22,22 @@ class StringTypeParser(GenericTypeParser): } format_type_mapping = { - "email": EmailStr, - "uri": HttpUrl, - "ipv4": IPvAnyAddress, - "ipv6": IPvAnyAddress, - "hostname": str, + # 7.3.1. Dates, Times, and Duration "date": date, "time": time, "date-time": datetime, "duration": timedelta, + # 7.3.2. Email Addresses + "email": EmailStr, + # 7.3.3. Hostnames + "hostname": str, + # 7.3.4. IP Addresses + "ipv4": IPv4Address, + "ipv6": IPv6Address, + # 7.3.5. Resource Identifiers + "uri": AnyUrl, + # "iri" # Not supported by pydantic and currently not supported by jambo + "uuid": UUID, } format_pattern_mapping = { diff --git a/tests/parser/test_string_type_parser.py b/tests/parser/test_string_type_parser.py index 51a37e4..e667ad7 100644 --- a/tests/parser/test_string_type_parser.py +++ b/tests/parser/test_string_type_parser.py @@ -1,8 +1,9 @@ from jambo.parser import StringTypeParser -from pydantic import EmailStr, HttpUrl, IPvAnyAddress +from pydantic import AnyUrl, EmailStr from datetime import date, datetime, time, timedelta +from ipaddress import IPv4Address, IPv6Address from unittest import TestCase @@ -111,12 +112,14 @@ class TestStringTypeParser(TestCase): type_parsing, type_validator = parser.from_properties("placeholder", properties) - self.assertEqual(type_parsing, HttpUrl) + self.assertEqual(type_parsing, AnyUrl) def test_string_parser_with_ip_formats(self): parser = StringTypeParser() - for ip_format in ["ipv4", "ipv6"]: + formats = {"ipv4": IPv4Address, "ipv6": IPv6Address} + + for ip_format, expected_type in formats.items(): properties = { "type": "string", "format": ip_format, @@ -126,7 +129,7 @@ class TestStringTypeParser(TestCase): "placeholder", properties ) - self.assertEqual(type_parsing, IPvAnyAddress) + self.assertEqual(type_parsing, expected_type) def test_string_parser_with_time_format(self): parser = StringTypeParser() diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index 9a756c7..d30a5ad 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -1,6 +1,6 @@ from jambo import SchemaConverter -from pydantic import BaseModel, HttpUrl +from pydantic import AnyUrl, BaseModel from ipaddress import IPv4Address, IPv6Address from unittest import TestCase @@ -463,7 +463,7 @@ class TestSchemaConverter(TestCase): } model = SchemaConverter.build(schema) self.assertEqual( - model(website="https://example.com").website, HttpUrl("https://example.com") + model(website="https://example.com").website, AnyUrl("https://example.com") ) with self.assertRaises(ValueError): model(website="invalid-uri") -- 2.49.1 From 97aed6e9aacac058843c94561779f0ac90657843 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Wed, 20 Aug 2025 00:30:54 -0300 Subject: [PATCH 2/2] (improvement): Adds tests for UUID String Format --- tests/parser/test_string_type_parser.py | 13 +++++++++++++ tests/test_schema_converter.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/parser/test_string_type_parser.py b/tests/parser/test_string_type_parser.py index e667ad7..279e20f 100644 --- a/tests/parser/test_string_type_parser.py +++ b/tests/parser/test_string_type_parser.py @@ -5,6 +5,7 @@ from pydantic import AnyUrl, EmailStr from datetime import date, datetime, time, timedelta from ipaddress import IPv4Address, IPv6Address from unittest import TestCase +from uuid import UUID class TestStringTypeParser(TestCase): @@ -131,6 +132,18 @@ class TestStringTypeParser(TestCase): self.assertEqual(type_parsing, expected_type) + def test_string_parser_with_uuid_format(self): + parser = StringTypeParser() + + properties = { + "type": "string", + "format": "uuid", + } + + type_parsing, type_validator = parser.from_properties("placeholder", properties) + + self.assertEqual(type_parsing, UUID) + def test_string_parser_with_time_format(self): parser = StringTypeParser() diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index d30a5ad..cdd294d 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -4,6 +4,7 @@ from pydantic import AnyUrl, BaseModel from ipaddress import IPv4Address, IPv6Address from unittest import TestCase +from uuid import UUID def is_pydantic_model(cls): @@ -493,6 +494,22 @@ class TestSchemaConverter(TestCase): with self.assertRaises(ValueError): model(ip="invalid-ipv6") + def test_string_format_uuid(self): + schema = { + "title": "UUIDTest", + "type": "object", + "properties": {"id": {"type": "string", "format": "uuid"}}, + } + model = SchemaConverter.build(schema) + + self.assertEqual( + model(id="123e4567-e89b-12d3-a456-426614174000").id, + UUID("123e4567-e89b-12d3-a456-426614174000"), + ) + + with self.assertRaises(ValueError): + model(id="invalid-uuid") + def test_string_format_hostname(self): schema = { "title": "HostnameTest", -- 2.49.1