mirror of
https://github.com/p2p-ld/numpydantic.git
synced 2025-01-09 21:44:27 +00:00
Add len method to video and hdf5 interfaces, make dunder test module to test dunder methods across all interfaces
This commit is contained in:
parent
9364cacc90
commit
b1c8d3e422
6 changed files with 73 additions and 35 deletions
|
@ -121,6 +121,10 @@ class H5Proxy:
|
||||||
else:
|
else:
|
||||||
obj[key, self.field] = value
|
obj[key, self.field] = value
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
"""self.shape[0]"""
|
||||||
|
return self.shape[0]
|
||||||
|
|
||||||
def open(self, mode: str = "r") -> "h5py.Dataset":
|
def open(self, mode: str = "r") -> "h5py.Dataset":
|
||||||
"""
|
"""
|
||||||
Return the opened :class:`h5py.Dataset` object
|
Return the opened :class:`h5py.Dataset` object
|
||||||
|
|
|
@ -180,6 +180,10 @@ class VideoProxy:
|
||||||
def __getattr__(self, item: str):
|
def __getattr__(self, item: str):
|
||||||
return getattr(self.video, item)
|
return getattr(self.video, item)
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
"""Number of frames in the video"""
|
||||||
|
return self.shape[0]
|
||||||
|
|
||||||
|
|
||||||
class VideoInterface(Interface):
|
class VideoInterface(Interface):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,6 +8,7 @@ import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
import zarr
|
import zarr
|
||||||
|
import cv2
|
||||||
|
|
||||||
from numpydantic.interface.hdf5 import H5ArrayPath
|
from numpydantic.interface.hdf5 import H5ArrayPath
|
||||||
from numpydantic.interface.zarr import ZarrArrayPath
|
from numpydantic.interface.zarr import ZarrArrayPath
|
||||||
|
@ -150,3 +151,34 @@ def zarr_array(tmp_output_dir_func) -> Path:
|
||||||
array = zarr.open(str(file), mode="w", shape=(100, 100), chunks=(10, 10))
|
array = zarr.open(str(file), mode="w", shape=(100, 100), chunks=(10, 10))
|
||||||
array[:] = 0
|
array[:] = 0
|
||||||
return file
|
return file
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function")
|
||||||
|
def avi_video(tmp_path) -> Callable[[Tuple[int, int], int, bool], Path]:
|
||||||
|
video_path = tmp_path / "test.avi"
|
||||||
|
|
||||||
|
def _make_video(shape=(100, 50), frames=10, is_color=True) -> Path:
|
||||||
|
writer = cv2.VideoWriter(
|
||||||
|
str(video_path),
|
||||||
|
cv2.VideoWriter_fourcc(*"RGBA"), # raw video for testing purposes
|
||||||
|
30,
|
||||||
|
(shape[1], shape[0]),
|
||||||
|
is_color,
|
||||||
|
)
|
||||||
|
if is_color:
|
||||||
|
shape = (*shape, 3)
|
||||||
|
|
||||||
|
for i in range(frames):
|
||||||
|
# make fresh array every time bc opencv eats them
|
||||||
|
array = np.zeros(shape, dtype=np.uint8)
|
||||||
|
if not is_color:
|
||||||
|
array[i, i] = i
|
||||||
|
else:
|
||||||
|
array[i, i, :] = i
|
||||||
|
writer.write(array)
|
||||||
|
writer.release()
|
||||||
|
return video_path
|
||||||
|
|
||||||
|
yield _make_video
|
||||||
|
|
||||||
|
video_path.unlink(missing_ok=True)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from typing import Tuple, Callable
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import dask.array as da
|
import dask.array as da
|
||||||
import zarr
|
import zarr
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from numpydantic import interface
|
from numpydantic import interface, NDArray
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(
|
@pytest.fixture(
|
||||||
|
@ -17,6 +19,7 @@ from numpydantic import interface
|
||||||
(zarr.ones((10, 10)), interface.ZarrInterface),
|
(zarr.ones((10, 10)), interface.ZarrInterface),
|
||||||
("zarr_nested_array", interface.ZarrInterface),
|
("zarr_nested_array", interface.ZarrInterface),
|
||||||
("zarr_array", interface.ZarrInterface),
|
("zarr_array", interface.ZarrInterface),
|
||||||
|
("avi_video", interface.VideoInterface),
|
||||||
],
|
],
|
||||||
ids=[
|
ids=[
|
||||||
"numpy_list",
|
"numpy_list",
|
||||||
|
@ -26,9 +29,10 @@ from numpydantic import interface
|
||||||
"zarr_memory",
|
"zarr_memory",
|
||||||
"zarr_nested",
|
"zarr_nested",
|
||||||
"zarr_array",
|
"zarr_array",
|
||||||
|
"video",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def interface_type(request):
|
def interface_type(request) -> Tuple[NDArray, interface.Interface]:
|
||||||
"""
|
"""
|
||||||
Test cases for each interface's ``check`` method - each input should match the
|
Test cases for each interface's ``check`` method - each input should match the
|
||||||
provided interface and that interface only
|
provided interface and that interface only
|
||||||
|
@ -37,3 +41,20 @@ def interface_type(request):
|
||||||
return (request.getfixturevalue(request.param[0]), request.param[1])
|
return (request.getfixturevalue(request.param[0]), request.param[1])
|
||||||
else:
|
else:
|
||||||
return request.param
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def all_interfaces(interface_type) -> BaseModel:
|
||||||
|
"""
|
||||||
|
An instantiated version of each interface within a basemodel,
|
||||||
|
with the array in an `array` field
|
||||||
|
"""
|
||||||
|
array, interface = interface_type
|
||||||
|
if isinstance(array, Callable):
|
||||||
|
array = array()
|
||||||
|
|
||||||
|
class MyModel(BaseModel):
|
||||||
|
array: NDArray
|
||||||
|
|
||||||
|
instance = MyModel(array=array)
|
||||||
|
return instance
|
||||||
|
|
10
tests/test_interface/test_dunder.py
Normal file
10
tests/test_interface/test_dunder.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
"""
|
||||||
|
Tests for dunder methods on all interfaces
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_dunder_len(all_interfaces):
|
||||||
|
"""
|
||||||
|
Each interface or proxy type should support __len__
|
||||||
|
"""
|
||||||
|
assert len(all_interfaces.array) == all_interfaces.array.shape[0]
|
|
@ -2,8 +2,6 @@
|
||||||
Needs to be refactored to DRY, but works for now
|
Needs to be refactored to DRY, but works for now
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pdb
|
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -17,37 +15,6 @@ from numpydantic import dtype as dt
|
||||||
from numpydantic.interface.video import VideoProxy
|
from numpydantic.interface.video import VideoProxy
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
|
||||||
def avi_video(tmp_path):
|
|
||||||
video_path = tmp_path / "test.avi"
|
|
||||||
|
|
||||||
def _make_video(shape=(100, 50), frames=10, is_color=True) -> Path:
|
|
||||||
writer = cv2.VideoWriter(
|
|
||||||
str(video_path),
|
|
||||||
cv2.VideoWriter_fourcc(*"RGBA"), # raw video for testing purposes
|
|
||||||
30,
|
|
||||||
(shape[1], shape[0]),
|
|
||||||
is_color,
|
|
||||||
)
|
|
||||||
if is_color:
|
|
||||||
shape = (*shape, 3)
|
|
||||||
|
|
||||||
for i in range(frames):
|
|
||||||
# make fresh array every time bc opencv eats them
|
|
||||||
array = np.zeros(shape, dtype=np.uint8)
|
|
||||||
if not is_color:
|
|
||||||
array[i, i] = i
|
|
||||||
else:
|
|
||||||
array[i, i, :] = i
|
|
||||||
writer.write(array)
|
|
||||||
writer.release()
|
|
||||||
return video_path
|
|
||||||
|
|
||||||
yield _make_video
|
|
||||||
|
|
||||||
video_path.unlink(missing_ok=True)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("input_type", [str, Path])
|
@pytest.mark.parametrize("input_type", [str, Path])
|
||||||
def test_video_validation(avi_video, input_type):
|
def test_video_validation(avi_video, input_type):
|
||||||
"""Color videos should validate for normal uint8 shape specs"""
|
"""Color videos should validate for normal uint8 shape specs"""
|
||||||
|
|
Loading…
Reference in a new issue