diff --git a/src/hdf5_reader_service/model.py b/src/hdf5_reader_service/model.py index d0d6795..ad74b4b 100644 --- a/src/hdf5_reader_service/model.py +++ b/src/hdf5_reader_service/model.py @@ -3,7 +3,6 @@ import h5py as h5 from pydantic import BaseModel -from pydantic.generics import GenericModel class DatasetMacroStructure(BaseModel): @@ -55,7 +54,7 @@ class ShapeMetadata(BaseModel): T = TypeVar("T") -class ValidNode(GenericModel, Generic[T]): +class ValidNode(BaseModel, Generic[T]): contents: T subnodes: List["DataTree"] = [] @@ -69,10 +68,10 @@ class InvalidNode(BaseModel): reason: InvalidNodeReason -class DataTree(GenericModel, Generic[T]): +class DataTree(BaseModel, Generic[T]): name: str valid: bool node: Union[InvalidNode, ValidNode[T]] -ValidNode.update_forward_refs() +ValidNode.model_rebuild() diff --git a/src/hdf5_reader_service/utils.py b/src/hdf5_reader_service/utils.py index 5a1ab0e..3fa416b 100644 --- a/src/hdf5_reader_service/utils.py +++ b/src/hdf5_reader_service/utils.py @@ -33,7 +33,7 @@ def default(content): return content.decode("utf-8") elif isinstance(content, BaseModel): # Handle the pydantic model case - return content.dict() + return content.model_dump() raise TypeError # Not all numpy dtypes are supported by orjson. diff --git a/tests/test_boilerplate_removed copy.py b/tests/test_boilerplate_removed copy.py deleted file mode 100644 index 59fafed..0000000 --- a/tests/test_boilerplate_removed copy.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -This file checks that all the example boilerplate text has been removed. -It can be deleted when all the contained tests pass -""" -import configparser -from pathlib import Path - -import pytest - -ROOT = Path(__file__).parent.parent - - -def skeleton_check(check: bool, text: str): - if ROOT.name == "dls-python3-skeleton": - # In the skeleton module the check should fail - check = not check - text = f"Skeleton didn't raise: {text}" - if check: - raise AssertionError(text) - - -def assert_not_contains_text(path: str, text: str, explanation: str): - full_path = ROOT / path - if full_path.exists(): - contents = full_path.read_text().replace("\n", " ") - skeleton_check(text in contents, f"Please change ./{path} {explanation}") - - -def assert_not_exists(path: str, explanation: str): - exists = (ROOT / path).exists() - skeleton_check(exists, f"Please delete ./{path} {explanation}") - - -# setup.cfg - - -@pytest.mark.skip("development needed") -def test_module_description(): - conf = configparser.ConfigParser() - conf.read("setup.cfg") - description = conf["metadata"]["description"] - skeleton_check( - "One line description of your module" in description, - "Please change description in ./setup.cfg " - "to be a one line description of your module", - ) - - -# README - - -@pytest.mark.skip("development needed") -def test_changed_README_intro(): - assert_not_contains_text( - "README.rst", - "This is where you should write a short paragraph", - "to include an intro on what your module does", - ) - - -@pytest.mark.skip("development needed") -def test_changed_README_body(): - assert_not_contains_text( - "README.rst", - "This is where you should put some images or code snippets", - "to include some features and why people should use it", - ) - - -# Docs -@pytest.mark.skip( - "pending https://github.com/DiamondLightSource/python-hdf5-reader-service/issues/3" -) -def test_docs_ref_api_changed(): - assert_not_contains_text( - "docs/reference/api.rst", - "You can mix verbose text with docstring and signature", - "to introduce the API for your module", - ) - - -@pytest.mark.skip( - "pending https://github.com/DiamondLightSource/python-hdf5-reader-service/issues/3" -) -def test_how_tos_written(): - assert_not_exists( - "docs/how-to/accomplish-a-task.rst", "and write some docs/how-tos" - ) - - -@pytest.mark.skip( - "pending https://github.com/DiamondLightSource/python-hdf5-reader-service/issues/3" -) -def test_explanations_written(): - assert_not_exists( - "docs/explanations/why-is-something-so.rst", "and write some docs/explanations" - ) diff --git a/tests/test_boilerplate_removed.py b/tests/test_boilerplate_removed.py deleted file mode 100644 index 931a44f..0000000 --- a/tests/test_boilerplate_removed.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -This file checks that all the example boilerplate text has been removed. -It can be deleted when all the contained tests pass -""" -import sys -from pathlib import Path - -if sys.version_info < (3, 8): - from importlib_metadata import metadata # noqa -else: - from importlib.metadata import metadata # noqa - -ROOT = Path(__file__).parent.parent - - -def skeleton_check(check: bool, text: str): - if ROOT.name == "python3-pip-skeleton" or str(ROOT) == "/project": - # In the skeleton module the check should fail - check = not check - text = f"Skeleton didn't raise: {text}" - if check: - raise AssertionError(text) - - -def assert_not_contains_text(path: str, text: str, explanation: str): - full_path = ROOT / path - if full_path.exists(): - contents = full_path.read_text().replace("\n", " ") - skeleton_check(text in contents, f"Please change ./{path} {explanation}") - - -# pyproject.toml -def test_module_summary(): - summary = metadata("hdf5-reader-service")["summary"] - skeleton_check( - "One line description of your module" in summary, - "Please change project.description in ./pyproject.toml " - "to be a one line description of your module", - ) - - -# README -def test_changed_README_intro(): - assert_not_contains_text( - "README.rst", - "This is where you should write a short paragraph", - "to include an intro on what your module does", - ) - - -def test_removed_adopt_skeleton(): - assert_not_contains_text( - "README.rst", - "This project contains template code only", - "remove the note at the start", - ) - - -def test_changed_README_body(): - assert_not_contains_text( - "README.rst", - "This is where you should put some images or code snippets", - "to include some features and why people should use it", - ) diff --git a/tests/test_system.py b/tests/test_system.py index d1a08c8..2b545ff 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -44,7 +44,7 @@ def test_read_shapes( "/shapes/", params={"path": str(test_data_path), "subpath": subpath} ) assert response.status_code == 200 - actual_shape = DataTree[ShapeMetadata].parse_obj(response.json()) + actual_shape = DataTree[ShapeMetadata].model_validate(response.json()) assert actual_shape == shape @@ -56,7 +56,7 @@ def test_read_tree( "/tree/", params={"path": str(test_data_path), "subpath": subpath} ) assert response.status_code == 200 - actual_tree = DataTree[MetadataNode].parse_obj(response.json()) + actual_tree = DataTree[MetadataNode].model_validate(response.json()) assert actual_tree == tree @@ -68,7 +68,7 @@ def test_read_info( "/info/", params={"path": str(test_data_path), "subpath": subpath} ) assert response.status_code == 200 - actual_metadata = MetadataNode.parse_obj(response.json()) + actual_metadata = MetadataNode.model_validate(response.json()) assert actual_metadata == metadata @@ -80,7 +80,7 @@ def test_read_search( "/search/", params={"path": str(test_data_path), "subpath": subpath} ) assert response.status_code == 200 - actual_children = NodeChildren.parse_obj(response.json()) + actual_children = NodeChildren.model_validate(response.json()) assert actual_children == children