Skip to content

Commit

Permalink
Added read/save_object_file to match the R packages.
Browse files Browse the repository at this point in the history
This is also a bit more convenient for method developers.
  • Loading branch information
LTLA committed Apr 28, 2024
1 parent 26e9c44 commit 01c0f26
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 21 deletions.
2 changes: 2 additions & 0 deletions src/dolomite_base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from .save_object import save_object, validate_saves
from .alt_save_object import alt_save_object, alt_save_object_function
from .save_object_file import save_object_file

from .save_atomic_vector import save_atomic_vector_from_string_list, save_atomic_vector_from_integer_list, save_atomic_vector_from_float_list, save_atomic_vector_from_boolean_list
from .save_string_factor import save_string_factor
Expand All @@ -25,6 +26,7 @@

from .read_object import read_object, read_object_registry
from .alt_read_object import alt_read_object, alt_read_object_function
from .read_object_file import read_object_file

from .read_atomic_vector import read_atomic_vector
from .read_string_factor import read_string_factor
Expand Down
6 changes: 2 additions & 4 deletions src/dolomite_base/read_object.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from typing import Any, Optional
from importlib import import_module
import os
import json
from .read_object_file import read_object_file


read_object_registry = {
Expand Down Expand Up @@ -53,8 +52,7 @@ def read_object(path: str, metadata: Optional[dict] = None, **kwargs) -> Any:
Some kind of object.
"""
if metadata is None:
with open(os.path.join(path, "OBJECT"), "rb") as handle:
metadata = json.load(handle)
metadata = read_object_file(path)

tt = metadata["type"]
if tt not in read_object_registry:
Expand Down
22 changes: 22 additions & 0 deletions src/dolomite_base/read_object_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import Dict, Any
import os
import json


def read_object_file(path: str) -> Dict[str, Any]:
"""
Read the ``OBJECT`` file in each directory, which provides some high-level
metadata of the object represented by that directory. It is guaranteed to
have a ‘type’ property that specifies the object type; individual objects
may add their own information to this file.
Args:
path:
Path to a directory containing the object.
Returns:
Dictionary containing the object metadata.
"""
with open(os.path.join(path, "OBJECT"), "rb") as handle:
metadata = json.load(handle)
return metadata
13 changes: 5 additions & 8 deletions src/dolomite_base/save_atomic_vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import numpy

from .save_object import save_object, validate_saves
from .save_object_file import save_object_file
from . import _utils_string as strings
from . import write_vector_to_hdf5 as write

Expand All @@ -29,8 +30,7 @@ def save_atomic_vector_from_string_list(x: StringList, path: str, **kwargs):
`x` is saved to `path`.
"""
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
handle.write('{ "type": "atomic_vector", "atomic_vector": { "version": "1.0" } }')
save_object_file(path, "atomic_vector", { "atomic_vector": { "version": "1.0" } })

with h5py.File(os.path.join(path, "contents.h5"), "w") as handle:
ghandle = handle.create_group("atomic_vector")
Expand Down Expand Up @@ -64,8 +64,7 @@ def save_atomic_vector_from_integer_list(x: IntegerList, path: str, **kwargs):
`x` is saved to `path`.
"""
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
handle.write('{ "type": "atomic_vector", "atomic_vector": { "version": "1.0" } }')
save_object_file(path, "atomic_vector", { "atomic_vector": { "version": "1.0" } })

with h5py.File(os.path.join(path, "contents.h5"), "w") as handle:
ghandle = handle.create_group("atomic_vector")
Expand Down Expand Up @@ -105,8 +104,7 @@ def save_atomic_vector_from_float_list(x: FloatList, path: str, **kwargs):
`x` is saved to `path`.
"""
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
handle.write('{ "type": "atomic_vector", "atomic_vector": { "version": "1.0" } }')
save_object_file(path, "atomic_vector", { "atomic_vector": { "version": "1.0" } })

with h5py.File(os.path.join(path, "contents.h5"), "w") as handle:
ghandle = handle.create_group("atomic_vector")
Expand Down Expand Up @@ -140,8 +138,7 @@ def save_atomic_vector_from_boolean_list(x: BooleanList, path: str, **kwargs):
`x` is saved to `path`.
"""
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
handle.write('{ "type": "atomic_vector", "atomic_vector": { "version": "1.0" } }')
save_object_file(path, "atomic_vector", { "atomic_vector": { "version": "1.0" } })

with h5py.File(os.path.join(path, "contents.h5"), "w") as handle:
ghandle = handle.create_group("atomic_vector")
Expand Down
4 changes: 2 additions & 2 deletions src/dolomite_base/save_data_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import h5py

from .save_object import save_object
from .save_object_file import save_object_file
from .alt_save_object import alt_save_object
from . import _utils_string as strings
from . import write_vector_to_hdf5 as write
Expand Down Expand Up @@ -97,8 +98,7 @@ def save_data_frame(
cd = cd.set_row_names(None)
alt_save_object(cd, os.path.join(path, "column_annotations"), data_frame_convert_list_to_vector=data_frame_convert_list_to_vector, **kwargs)

with open(os.path.join(path, "OBJECT"), "w") as handle:
handle.write('{ "type": "data_frame", "data_frame": { "version": "1.0" } }')
save_object_file(path, "data_frame", { "data_frame": { "version": "1.0" } })
return


Expand Down
26 changes: 26 additions & 0 deletions src/dolomite_base/save_object_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from typing import Dict, Any
import os
import json


def save_object_file(path: str, object_type: str, extra: Dict[str, Any] = {}):
"""
Saves object-specific metadata into the ``OBJECT`` file inside each
directory, to be used by, e.g., :py:func:`~.read_object_file`.
Args:
path:
Path to the directory representing an object. An ``OBJECT`` file
will be created inside this directory.
object_type:
Type of the object.
extra:
Extra metadata to be written to the ``OBJECT`` file in ``path``.
Any entry named ``type`` will be overwritten by ``object_type``.
"""
to_save = { **extra }
to_save["type"] = object_type
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
json.dump(to_save, handle)
11 changes: 6 additions & 5 deletions src/dolomite_base/save_simple_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import h5py

from .save_object import save_object, validate_saves
from .save_object_file import save_object_file
from .alt_save_object import alt_save_object
from . import _utils_misc as misc
from . import _utils_string as strings
Expand Down Expand Up @@ -100,11 +101,11 @@ def save_simple_list_from_NamedList(x: NamedList, path: str, simple_list_mode: L

def _save_simple_list_internal(x: Union[dict, list, NamedList], path: str, simple_list_mode: Literal["hdf5", "json"] = None, **kwargs):
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
format2 = simple_list_mode
if format2 == "json":
format2 = "json.gz"
handle.write('{ "type": "simple_list", "simple_list": { "version": "1.0", "format": "' + format2 + '" } }')

format2 = simple_list_mode
if format2 == "json":
format2 = "json.gz"
save_object_file(path, "simple_list", { "simple_list": { "version": "1.0", "format": format2 } })

externals = []

Expand Down
5 changes: 3 additions & 2 deletions src/dolomite_base/save_string_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import h5py

from .save_object import save_object, validate_saves
from .save_object_file import save_object_file
from . import _utils_string as strings
from ._utils_factor import save_factor_to_hdf5


@save_object.register
@validate_saves
def save_string_factor(x: Factor, path: str, **kwargs):
Expand All @@ -27,8 +29,7 @@ def save_string_factor(x: Factor, path: str, **kwargs):
`x` is saved to `path`.
"""
os.mkdir(path)
with open(os.path.join(path, "OBJECT"), 'w', encoding="utf-8") as handle:
handle.write('{ "type": "string_factor", "string_factor": { "version": "1.0" } }')
save_object_file(path, "string_factor", { "string_factor": { "version": "1.0" } })

with h5py.File(os.path.join(path, "contents.h5"), "w") as handle:
ghandle = handle.create_group("string_factor")
Expand Down

0 comments on commit 01c0f26

Please sign in to comment.