jsonstat-validator 0.1.5__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jsonstat_validator-0.1.5/jsonstat_validator.egg-info → jsonstat_validator-0.2.0}/PKG-INFO +3 -3
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator/__init__.py +3 -16
- jsonstat_validator-0.1.5/jsonstat_validator/validator.py → jsonstat_validator-0.2.0/jsonstat_validator/models.py +39 -27
- jsonstat_validator-0.2.0/jsonstat_validator/validator.py +70 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0/jsonstat_validator.egg-info}/PKG-INFO +3 -3
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator.egg-info/SOURCES.txt +1 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator.egg-info/requires.txt +1 -1
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/pyproject.toml +4 -4
- jsonstat_validator-0.2.0/requirements.txt +1 -0
- jsonstat_validator-0.1.5/requirements.txt +0 -1
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/LICENSE +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/MANIFEST.in +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/README.md +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator.egg-info/dependency_links.txt +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator.egg-info/top_level.txt +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/setup.cfg +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/setup.py +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/tests/test_custom.py +0 -0
- {jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/tests/test_official_samples.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jsonstat-validator
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Summary: A Python validator for the JSON-stat 2.0 standard format, based on Pydantic.
|
5
5
|
Author-email: Ahmed Hassan <ahmedhassan.ahmed@fao.org>
|
6
6
|
License: # MIT License
|
@@ -30,11 +30,11 @@ Project-URL: Bug Tracker, https://github.com/ahmed-hassan19/jsonstat-validator/i
|
|
30
30
|
Project-URL: Documentation, https://github.com/ahmed-hassan19/jsonstat-validator#readme
|
31
31
|
Keywords: json-stat,validator,json,data-engineering,pydantic,python,fao
|
32
32
|
Classifier: Programming Language :: Python :: 3
|
33
|
-
Classifier: Programming Language :: Python :: 3.8
|
34
33
|
Classifier: Programming Language :: Python :: 3.9
|
35
34
|
Classifier: Programming Language :: Python :: 3.10
|
36
35
|
Classifier: Programming Language :: Python :: 3.11
|
37
36
|
Classifier: Programming Language :: Python :: 3.12
|
37
|
+
Classifier: Programming Language :: Python :: 3.13
|
38
38
|
Classifier: License :: OSI Approved :: MIT License
|
39
39
|
Classifier: Operating System :: OS Independent
|
40
40
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
@@ -42,7 +42,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
42
42
|
Requires-Python: >=3.8
|
43
43
|
Description-Content-Type: text/markdown
|
44
44
|
License-File: LICENSE
|
45
|
-
Requires-Dist: pydantic
|
45
|
+
Requires-Dist: pydantic==2.11.2
|
46
46
|
Provides-Extra: dev
|
47
47
|
Requires-Dist: pytest>=8.1.1; extra == "dev"
|
48
48
|
Requires-Dist: build>=1.0.0; extra == "dev"
|
@@ -10,27 +10,14 @@ dimensions are organized in categories.
|
|
10
10
|
For more information on JSON-stat, see: https://json-stat.org/
|
11
11
|
"""
|
12
12
|
|
13
|
-
from jsonstat_validator.
|
14
|
-
|
15
|
-
Collection,
|
16
|
-
Dataset,
|
17
|
-
DatasetRole,
|
18
|
-
Dimension,
|
19
|
-
JSONStatSchema,
|
20
|
-
Link,
|
21
|
-
Unit,
|
22
|
-
validate_jsonstat,
|
23
|
-
)
|
13
|
+
from jsonstat_validator.models import Collection, Dataset, Dimension, JSONStatSchema
|
14
|
+
from jsonstat_validator.validator import validate_jsonstat
|
24
15
|
|
25
|
-
__version__ = "0.
|
16
|
+
__version__ = "0.2.0"
|
26
17
|
__all__ = [
|
27
18
|
"Dataset",
|
28
19
|
"Dimension",
|
29
20
|
"Collection",
|
30
|
-
"Link",
|
31
|
-
"Unit",
|
32
|
-
"Category",
|
33
|
-
"DatasetRole",
|
34
21
|
"JSONStatSchema",
|
35
22
|
"validate_jsonstat",
|
36
23
|
]
|
@@ -14,9 +14,9 @@ from typing import Any, Dict, List, Literal, Optional, Union
|
|
14
14
|
from pydantic import (
|
15
15
|
AnyUrl,
|
16
16
|
BaseModel,
|
17
|
+
ConfigDict,
|
17
18
|
Field,
|
18
19
|
RootModel,
|
19
|
-
ValidationError,
|
20
20
|
field_serializer,
|
21
21
|
field_validator,
|
22
22
|
model_validator,
|
@@ -46,6 +46,8 @@ class JSONStatBaseModel(BaseModel):
|
|
46
46
|
"""Convert AnyUrl to string, if it exists."""
|
47
47
|
return str(href) if href else None
|
48
48
|
|
49
|
+
model_config = ConfigDict(extra="forbid", serialize_by_alias=True)
|
50
|
+
|
49
51
|
|
50
52
|
class Unit(JSONStatBaseModel):
|
51
53
|
"""Unit of measurement of a dimension.
|
@@ -169,6 +171,14 @@ class Category(JSONStatBaseModel):
|
|
169
171
|
"of a dimension with a metric role."
|
170
172
|
),
|
171
173
|
)
|
174
|
+
note: Optional[Dict[str, List[str]]] = Field(
|
175
|
+
default=None,
|
176
|
+
description=(
|
177
|
+
"note allows to assign annotations to datasets (array), dimensions "
|
178
|
+
"(array) and categories (object). To assign annotations to individual "
|
179
|
+
"data, use status: https://json-stat.org/full/#status."
|
180
|
+
),
|
181
|
+
)
|
172
182
|
|
173
183
|
@model_validator(mode="after")
|
174
184
|
def validate_category(self):
|
@@ -320,8 +330,9 @@ class Dimension(JSONStatBaseModel):
|
|
320
330
|
note: Optional[List[str]] = Field(
|
321
331
|
default=None,
|
322
332
|
description=(
|
323
|
-
"
|
324
|
-
"and categories (object)."
|
333
|
+
"note allows to assign annotations to datasets (array), dimensions "
|
334
|
+
"(array) and categories (object). To assign annotations to individual "
|
335
|
+
"data, use status: https://json-stat.org/full/#status."
|
325
336
|
),
|
326
337
|
)
|
327
338
|
updated: Optional[str] = Field(
|
@@ -417,8 +428,9 @@ class DatasetDimension(JSONStatBaseModel):
|
|
417
428
|
note: Optional[List[str]] = Field(
|
418
429
|
default=None,
|
419
430
|
description=(
|
420
|
-
"
|
421
|
-
"and categories (object)."
|
431
|
+
"note allows to assign annotations to datasets (array), dimensions "
|
432
|
+
"(array) and categories (object). To assign annotations to individual "
|
433
|
+
"data, use status: https://json-stat.org/full/#status."
|
422
434
|
),
|
423
435
|
)
|
424
436
|
updated: Optional[str] = Field(
|
@@ -597,8 +609,9 @@ class Dataset(JSONStatBaseModel):
|
|
597
609
|
note: Optional[List[str]] = Field(
|
598
610
|
default=None,
|
599
611
|
description=(
|
600
|
-
"
|
601
|
-
"and categories (object)."
|
612
|
+
"note allows to assign annotations to datasets (array), dimensions "
|
613
|
+
"(array) and categories (object). To assign annotations to individual "
|
614
|
+
"data, use status: https://json-stat.org/full/#status."
|
602
615
|
),
|
603
616
|
)
|
604
617
|
extension: Optional[Dict[str, Any]] = Field(
|
@@ -707,6 +720,25 @@ class Collection(JSONStatBaseModel):
|
|
707
720
|
"(datasets, dimensions, collections)."
|
708
721
|
),
|
709
722
|
)
|
723
|
+
source: Optional[str] = Field(
|
724
|
+
default=None,
|
725
|
+
description="It contains a language-dependent short text describing the source "
|
726
|
+
"of the collection.",
|
727
|
+
)
|
728
|
+
note: Optional[List[str]] = Field(
|
729
|
+
default=None,
|
730
|
+
description=(
|
731
|
+
"note allows to assign annotations to datasets (array), dimensions "
|
732
|
+
"(array) and categories (object). To assign annotations to individual "
|
733
|
+
"data, use status: https://json-stat.org/full/#status."
|
734
|
+
),
|
735
|
+
)
|
736
|
+
extension: Optional[Dict[str, Any]] = Field(
|
737
|
+
default=None,
|
738
|
+
description="Extension allows JSON-stat to be extended for particular needs. "
|
739
|
+
"Providers are free to define where they include this property and "
|
740
|
+
"what children are allowed in each case.",
|
741
|
+
)
|
710
742
|
|
711
743
|
@field_validator("updated", mode="after")
|
712
744
|
@classmethod
|
@@ -741,23 +773,3 @@ class JSONStatSchema(RootModel):
|
|
741
773
|
def serialize_any_url(self, href: Optional[AnyUrl]) -> Optional[str]:
|
742
774
|
"""Convert AnyUrl to string, if it exists."""
|
743
775
|
return str(href) if href else None
|
744
|
-
|
745
|
-
|
746
|
-
def validate_jsonstat(data: Dict[str, Any]) -> bool:
|
747
|
-
"""
|
748
|
-
Validate a JSON-stat 2.0 object against the specification.
|
749
|
-
|
750
|
-
Args:
|
751
|
-
data: A dictionary containing JSON-stat data
|
752
|
-
|
753
|
-
Returns:
|
754
|
-
bool: True if valid, raises ValueError otherwise
|
755
|
-
|
756
|
-
Raises:
|
757
|
-
ValueError: If the data does not conform to the JSON-stat specification
|
758
|
-
"""
|
759
|
-
try:
|
760
|
-
JSONStatSchema(**data)
|
761
|
-
return True
|
762
|
-
except ValidationError as e:
|
763
|
-
raise ValueError(e) from e
|
@@ -0,0 +1,70 @@
|
|
1
|
+
from typing import Any, Dict
|
2
|
+
|
3
|
+
from pydantic import ValidationError
|
4
|
+
|
5
|
+
from jsonstat_validator.models import JSONStatSchema
|
6
|
+
|
7
|
+
|
8
|
+
def format_error_location(loc: tuple) -> str:
|
9
|
+
"""
|
10
|
+
Format error location to be more human-readable.
|
11
|
+
|
12
|
+
Args:
|
13
|
+
loc: Location tuple from ValidationError
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
str: Formatted location string
|
17
|
+
"""
|
18
|
+
parts = []
|
19
|
+
for item in loc:
|
20
|
+
if isinstance(item, int):
|
21
|
+
parts.append(f"[{item}]")
|
22
|
+
elif parts:
|
23
|
+
parts.append(f".{item}")
|
24
|
+
else:
|
25
|
+
parts.append(item)
|
26
|
+
return "".join(parts)
|
27
|
+
|
28
|
+
|
29
|
+
def format_validation_errors(e: ValidationError) -> str:
|
30
|
+
"""
|
31
|
+
Format ValidationError to be more human-readable.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
e: ValidationError instance
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
str: Formatted error message
|
38
|
+
"""
|
39
|
+
errors = []
|
40
|
+
for error in e.errors():
|
41
|
+
# Create a simplified error object without input and url fields
|
42
|
+
loc = format_error_location(error["loc"])
|
43
|
+
msg = error["msg"]
|
44
|
+
type_str = error["type"]
|
45
|
+
|
46
|
+
errors.append(f"Error at '{loc}': {msg} (type={type_str})")
|
47
|
+
|
48
|
+
return "\n".join(errors)
|
49
|
+
|
50
|
+
|
51
|
+
def validate_jsonstat(data: Dict[str, Any]) -> bool:
|
52
|
+
"""
|
53
|
+
Validate a JSON-stat 2.0 object against the specification.
|
54
|
+
|
55
|
+
Args:
|
56
|
+
data: A dictionary containing JSON-stat data
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
bool: True if valid, raises ValueError otherwise
|
60
|
+
|
61
|
+
Raises:
|
62
|
+
ValueError: If the data does not conform to the JSON-stat specification
|
63
|
+
with a user-friendly error message
|
64
|
+
"""
|
65
|
+
try:
|
66
|
+
JSONStatSchema.model_validate(data)
|
67
|
+
return True
|
68
|
+
except ValidationError as e:
|
69
|
+
error_message = format_validation_errors(e)
|
70
|
+
raise ValueError(f"JSON-stat validation failed:\n{error_message}") from None
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jsonstat-validator
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.2.0
|
4
4
|
Summary: A Python validator for the JSON-stat 2.0 standard format, based on Pydantic.
|
5
5
|
Author-email: Ahmed Hassan <ahmedhassan.ahmed@fao.org>
|
6
6
|
License: # MIT License
|
@@ -30,11 +30,11 @@ Project-URL: Bug Tracker, https://github.com/ahmed-hassan19/jsonstat-validator/i
|
|
30
30
|
Project-URL: Documentation, https://github.com/ahmed-hassan19/jsonstat-validator#readme
|
31
31
|
Keywords: json-stat,validator,json,data-engineering,pydantic,python,fao
|
32
32
|
Classifier: Programming Language :: Python :: 3
|
33
|
-
Classifier: Programming Language :: Python :: 3.8
|
34
33
|
Classifier: Programming Language :: Python :: 3.9
|
35
34
|
Classifier: Programming Language :: Python :: 3.10
|
36
35
|
Classifier: Programming Language :: Python :: 3.11
|
37
36
|
Classifier: Programming Language :: Python :: 3.12
|
37
|
+
Classifier: Programming Language :: Python :: 3.13
|
38
38
|
Classifier: License :: OSI Approved :: MIT License
|
39
39
|
Classifier: Operating System :: OS Independent
|
40
40
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
@@ -42,7 +42,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
42
42
|
Requires-Python: >=3.8
|
43
43
|
Description-Content-Type: text/markdown
|
44
44
|
License-File: LICENSE
|
45
|
-
Requires-Dist: pydantic
|
45
|
+
Requires-Dist: pydantic==2.11.2
|
46
46
|
Provides-Extra: dev
|
47
47
|
Requires-Dist: pytest>=8.1.1; extra == "dev"
|
48
48
|
Requires-Dist: build>=1.0.0; extra == "dev"
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "jsonstat-validator"
|
7
|
-
version = "0.
|
7
|
+
version = "0.2.0"
|
8
8
|
description = "A Python validator for the JSON-stat 2.0 standard format, based on Pydantic."
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [
|
@@ -13,11 +13,11 @@ authors = [
|
|
13
13
|
license = {file = "LICENSE"}
|
14
14
|
classifiers = [
|
15
15
|
"Programming Language :: Python :: 3",
|
16
|
-
"Programming Language :: Python :: 3.8",
|
17
16
|
"Programming Language :: Python :: 3.9",
|
18
17
|
"Programming Language :: Python :: 3.10",
|
19
18
|
"Programming Language :: Python :: 3.11",
|
20
19
|
"Programming Language :: Python :: 3.12",
|
20
|
+
"Programming Language :: Python :: 3.13",
|
21
21
|
"License :: OSI Approved :: MIT License",
|
22
22
|
"Operating System :: OS Independent",
|
23
23
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
@@ -26,7 +26,7 @@ classifiers = [
|
|
26
26
|
keywords = ["json-stat", "validator", "json", "data-engineering", "pydantic", "python", "fao"]
|
27
27
|
requires-python = ">=3.8"
|
28
28
|
dependencies = [
|
29
|
-
"pydantic
|
29
|
+
"pydantic==2.11.2",
|
30
30
|
]
|
31
31
|
|
32
32
|
[project.optional-dependencies]
|
@@ -55,7 +55,7 @@ testpaths = ["tests"]
|
|
55
55
|
|
56
56
|
[tool.black]
|
57
57
|
line-length = 90
|
58
|
-
target-version = ["
|
58
|
+
target-version = ["py39", "py310", "py311", "py312", "py313"]
|
59
59
|
include = '\.pyi?$'
|
60
60
|
|
61
61
|
[tool.isort]
|
@@ -0,0 +1 @@
|
|
1
|
+
pydantic==2.11.2
|
@@ -1 +0,0 @@
|
|
1
|
-
pydantic==2.*
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{jsonstat_validator-0.1.5 → jsonstat_validator-0.2.0}/jsonstat_validator.egg-info/top_level.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|