diff --git a/dva-processing/pyproject.toml b/dva-processing/pyproject.toml index 57bef18..c3667a9 100644 --- a/dva-processing/pyproject.toml +++ b/dva-processing/pyproject.toml @@ -23,6 +23,7 @@ dependencies = [ "uvicorn>=0.34.3", "validators>=0.35.0", "pydantic-yaml>=1.6.0", + "rfc3987>=1.3.8", ] classifiers = ["Private :: Do Not Upload"] diff --git a/dva-processing/src/dva_processing/engines/json_schema.py b/dva-processing/src/dva_processing/engines/json_schema.py index ffcc502..54a88d1 100644 --- a/dva-processing/src/dva_processing/engines/json_schema.py +++ b/dva-processing/src/dva_processing/engines/json_schema.py @@ -2,10 +2,12 @@ import json from typing import Any -from jsonschema import ValidationError, validate as jsvalidate +from jsonschema import ValidationError, FormatChecker, validate as jsvalidate from ..model import JSONSchemaValidationResult +#initializing the global format checker +global_format_checker = FormatChecker() def validate(data: Any, schema: str) -> JSONSchemaValidationResult: # TODO: Do we want to allow loading from arbitrary URL? @@ -13,8 +15,10 @@ def validate(data: Any, schema: str) -> JSONSchemaValidationResult: schema = json.loads(html.unescape(schema)) try: - jsvalidate(instance=data, schema=schema) + jsvalidate(instance=data, schema=schema, format_checker=global_format_checker) except ValidationError as e: - return JSONSchemaValidationResult(success=False, errors=e) + # FIX 1: Wrap 'e' in str() so Pydantic receives a string, not an object + return JSONSchemaValidationResult(success=False, errors=str(e)) - return JSONSchemaValidationResult(success=True, errors=None) + # FIX 2: Pass an empty string "" instead of None + return JSONSchemaValidationResult(success=True, errors="") diff --git a/dva-processing/uv.lock b/dva-processing/uv.lock index baff136..4b3b05c 100644 --- a/dva-processing/uv.lock +++ b/dva-processing/uv.lock @@ -16,12 +16,12 @@ resolution-markers = [ "python_full_version >= '3.13'", ] dependencies = [ - { name = "entrypoints", marker = "python_full_version >= '3.13'" }, - { name = "jinja2", marker = "python_full_version >= '3.13'" }, - { name = "jsonschema", marker = "python_full_version >= '3.13'" }, - { name = "numpy", marker = "python_full_version >= '3.13'" }, - { name = "pandas", marker = "python_full_version >= '3.13'" }, - { name = "toolz", marker = "python_full_version >= '3.13'" }, + { name = "entrypoints" }, + { name = "jinja2" }, + { name = "jsonschema" }, + { name = "numpy" }, + { name = "pandas" }, + { name = "toolz" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/bf/781b607da4c1a2a7211cd570bd7e22e0accd4deaf1074c32ac7344a09339/altair-4.2.2.tar.gz", hash = "sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5", size = 740430, upload-time = "2023-01-27T22:51:11.045Z" } wheels = [ @@ -38,11 +38,11 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "jinja2", marker = "python_full_version < '3.13'" }, - { name = "jsonschema", marker = "python_full_version < '3.13'" }, - { name = "narwhals", marker = "python_full_version < '3.13'" }, - { name = "packaging", marker = "python_full_version < '3.13'" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "jinja2" }, + { name = "jsonschema" }, + { name = "narwhals" }, + { name = "packaging" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/86/97/9a0dc61efd4f2dee29cb6d8edbbacdb789ce48cbffd98efa2b3ab145b297/altair-6.2.1.tar.gz", hash = "sha256:ca0298fa20b1a4fae22eff8847b95f74912bd90544013ad36af192119883ea64", size = 766468, upload-time = "2026-06-05T16:23:36.57Z" } wheels = [ @@ -404,6 +404,7 @@ dependencies = [ { name = "pydantic" }, { name = "pydantic-yaml" }, { name = "requests" }, + { name = "rfc3987" }, { name = "structlog" }, { name = "uvicorn" }, { name = "validators" }, @@ -434,6 +435,7 @@ requires-dist = [ { name = "pydantic", specifier = ">=2.10.6" }, { name = "pydantic-yaml", specifier = ">=1.6.0" }, { name = "requests", specifier = ">=2.32.3" }, + { name = "rfc3987", specifier = ">=1.3.8" }, { name = "rich", marker = "extra == 'logging'", specifier = ">=13.9.4" }, { name = "structlog", specifier = ">=25.1.0" }, { name = "uvicorn", specifier = ">=0.34.3" }, @@ -458,7 +460,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -489,25 +491,25 @@ resolution-markers = [ "python_full_version >= '3.13'", ] dependencies = [ - { name = "altair", version = "4.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, - { name = "cryptography", marker = "python_full_version >= '3.13'" }, - { name = "jinja2", marker = "python_full_version >= '3.13'" }, - { name = "jsonschema", marker = "python_full_version >= '3.13'" }, - { name = "marshmallow", marker = "python_full_version >= '3.13'" }, - { name = "mistune", marker = "python_full_version >= '3.13'" }, - { name = "numpy", marker = "python_full_version >= '3.13'" }, - { name = "packaging", marker = "python_full_version >= '3.13'" }, - { name = "pandas", marker = "python_full_version >= '3.13'" }, - { name = "posthog", marker = "python_full_version >= '3.13'" }, - { name = "pydantic", marker = "python_full_version >= '3.13'" }, - { name = "pyparsing", marker = "python_full_version >= '3.13'" }, - { name = "python-dateutil", marker = "python_full_version >= '3.13'" }, - { name = "requests", marker = "python_full_version >= '3.13'" }, - { name = "ruamel-yaml", marker = "python_full_version >= '3.13'" }, - { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, - { name = "tqdm", marker = "python_full_version >= '3.13'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.13'" }, - { name = "tzlocal", marker = "python_full_version >= '3.13'" }, + { name = "altair", version = "4.2.2", source = { registry = "https://pypi.org/simple" } }, + { name = "cryptography" }, + { name = "jinja2" }, + { name = "jsonschema" }, + { name = "marshmallow" }, + { name = "mistune" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "posthog" }, + { name = "pydantic" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, + { name = "requests" }, + { name = "ruamel-yaml" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" } }, + { name = "tqdm" }, + { name = "typing-extensions" }, + { name = "tzlocal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/f4/4a5e68a56fb185b135897b6429d7c48bcfedc078cb46107786318bc77487/great_expectations-1.6.4.tar.gz", hash = "sha256:21db5faba9d66a1295b8b929a0b852294d50dda3c29866d214e107071f913bed", size = 36272138, upload-time = "2025-10-01T23:54:18.763Z" } wheels = [ @@ -524,25 +526,25 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "altair", version = "6.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.13'" }, - { name = "cryptography", marker = "python_full_version < '3.13'" }, - { name = "jinja2", marker = "python_full_version < '3.13'" }, - { name = "jsonschema", marker = "python_full_version < '3.13'" }, - { name = "marshmallow", marker = "python_full_version < '3.13'" }, - { name = "mistune", marker = "python_full_version < '3.13'" }, - { name = "numpy", marker = "python_full_version < '3.13'" }, - { name = "packaging", marker = "python_full_version < '3.13'" }, - { name = "pandas", marker = "python_full_version < '3.13'" }, - { name = "pydantic", marker = "python_full_version < '3.13'" }, - { name = "pyparsing", marker = "python_full_version < '3.13'" }, - { name = "python-dateutil", marker = "python_full_version < '3.13'" }, - { name = "requests", marker = "python_full_version < '3.13'" }, - { name = "ruamel-yaml", marker = "python_full_version < '3.13'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "altair", version = "6.2.1", source = { registry = "https://pypi.org/simple" } }, + { name = "cryptography" }, + { name = "jinja2" }, + { name = "jsonschema" }, + { name = "marshmallow" }, + { name = "mistune" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "pydantic" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, + { name = "requests" }, + { name = "ruamel-yaml" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or python_full_version >= '3.13'" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and python_full_version < '3.13'" }, - { name = "tqdm", marker = "python_full_version < '3.13'" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, - { name = "tzlocal", marker = "python_full_version < '3.13'" }, + { name = "tqdm" }, + { name = "typing-extensions" }, + { name = "tzlocal" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/05/28c96fb31e2655c719f5857b9af5243768bcca9e45b0eb37684f867a1fb3/great_expectations-1.18.0.tar.gz", hash = "sha256:e01f4f4c6a71e23997f81fd805d35cdf90763aa1e05060f4ea31f2b392898f47", size = 36280151, upload-time = "2026-06-02T12:51:08.795Z" } wheels = [ @@ -923,10 +925,10 @@ name = "posthog" version = "7.18.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "backoff", marker = "python_full_version >= '3.13'" }, - { name = "distro", marker = "python_full_version >= '3.13'" }, - { name = "requests", marker = "python_full_version >= '3.13'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.13'" }, + { name = "backoff" }, + { name = "distro" }, + { name = "requests" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a6/41/d7922b23d9f3dec427286b13f8f15b12c08eea3950a6cfd53979a54aed91/posthog-7.18.0.tar.gz", hash = "sha256:560230cf9616ac1fde5e3bfba1c666ab69e8488e5417005f86f91f7c6ef74252", size = 229913, upload-time = "2026-06-05T13:56:22.577Z" } wheels = [ @@ -1254,6 +1256,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, ] +[[package]] +name = "rfc3987" +version = "1.3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/14/bb/f1395c4b62f251a1cb503ff884500ebd248eed593f41b469f89caa3547bd/rfc3987-1.3.8.tar.gz", hash = "sha256:d3c4d257a560d544e9826b38bc81db676890c79ab9d7ac92b39c7a253d5ca733", size = 20700, upload-time = "2018-07-29T17:23:47.954Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/d4/f7407c3d15d5ac779c3dd34fbbc6ea2090f77bd7dd12f207ccf881551208/rfc3987-1.3.8-py2.py3-none-any.whl", hash = "sha256:10702b1e51e5658843460b189b185c0366d2cf4cff716f13111b0ea9fd2dce53", size = 13377, upload-time = "2018-07-29T17:23:45.313Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -1612,7 +1623,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "numpy", marker = "python_full_version < '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } wheels = [ @@ -1673,7 +1684,7 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "numpy", marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [