Skip to content

Commit

Permalink
Make metadata a method. (#527)
Browse files Browse the repository at this point in the history
* Make metadata a method.

* Missed one
  • Loading branch information
danielballan committed Jul 19, 2023
1 parent 839ffd5 commit cc4c599
Show file tree
Hide file tree
Showing 17 changed files with 47 additions and 45 deletions.
4 changes: 2 additions & 2 deletions tiled/_tests/test_catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ async def test_sorting(a):
items = await a.sort([("metadata.number", 1), ("metadata.letter", 1)]).items_range(
0, 10
)
numbers = [v.metadata["number"] for k, v in items]
letters = [v.metadata["letter"] for k, v in items]
numbers = [v.metadata()["number"] for k, v in items]
letters = [v.metadata()["letter"] for k, v in items]
keys = [k for k, v in items]
# Numbers are sorted.
numbers = sorted(numbers)
Expand Down
4 changes: 2 additions & 2 deletions tiled/_tests/test_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async def client(request, tmpdir_module):
with Context.from_app(app) as context:
client = from_context(context)
for k, v in mapping.items():
client.write_array(v.read(), key=k, metadata=dict(v.metadata))
client.write_array(v.read(), key=k, metadata=dict(v.metadata()))
yield client
elif request.param == "postgresql":
if not TILED_TEST_POSTGRESQL_URI:
Expand Down Expand Up @@ -104,7 +104,7 @@ async def client(request, tmpdir_module):
client = from_context(context)
# Write data into catalog.
for k, v in mapping.items():
client.write_array(v.read(), key=k, metadata=dict(v.metadata))
client.write_array(v.read(), key=k, metadata=dict(v.metadata()))
yield client
else:
assert False
Expand Down
6 changes: 2 additions & 4 deletions tiled/adapters/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from ..server.object_cache import get_object_cache
from ..structures.array import ArrayMacroStructure, BuiltinDtype, StructDtype
from ..structures.core import StructureFamily
from ..utils import DictView, ListView


class ArrayAdapter:
Expand Down Expand Up @@ -85,11 +84,10 @@ def __repr__(self):

@property
def dims(self):
return ListView(self._dims)
return self._dims

@property
def metadata(self):
return DictView(self._metadata)
return self._metadata

def macrostructure(self):
"Structures of the layout of blocks of this array"
Expand Down
4 changes: 1 addition & 3 deletions tiled/adapters/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from ..server.object_cache import NO_CACHE, get_object_cache
from ..structures.core import StructureFamily
from ..structures.dataframe import DataFrameMacroStructure, DataFrameMicroStructure
from ..utils import DictView
from .array import ArrayAdapter


Expand Down Expand Up @@ -128,9 +127,8 @@ def items(self):
for key in self._meta.columns
)

@property
def metadata(self):
return DictView(self._metadata)
return self._metadata

def macrostructure(self):
return DataFrameMacroStructure(
Expand Down
5 changes: 2 additions & 3 deletions tiled/adapters/hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ..adapters.utils import IndexersMixin
from ..iterviews import ItemsView, KeysView, ValuesView
from ..structures.core import StructureFamily
from ..utils import DictView, node_repr
from ..utils import node_repr
from .array import ArrayAdapter

SWMR_DEFAULT = bool(int(os.getenv("TILED_HDF5_SWMR_DEFAULT", "0")))
Expand Down Expand Up @@ -79,15 +79,14 @@ def __repr__(self):
def access_policy(self):
return self._access_policy

@property
def metadata(self):
d = dict(self._node.attrs)
for k, v in list(d.items()):
# Convert any bytes to str.
if isinstance(v, bytes):
d[k] = v.decode()
d.update(self._provided_metadata)
return DictView(d)
return d

def __iter__(self):
yield from self._node
Expand Down
11 changes: 5 additions & 6 deletions tiled/adapters/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
)
from ..query_registration import QueryTranslationRegistry
from ..structures.core import StructureFamily
from ..utils import UNCHANGED, DictView
from ..utils import UNCHANGED
from .utils import IndexersMixin


Expand Down Expand Up @@ -116,13 +116,12 @@ def access_policy(self):
def access_policy(self, value):
self._access_policy = value

@property
def metadata(self):
"Metadata about this Adapter."
# Ensure this is immutable (at the top level) to help the user avoid
# getting the wrong impression that editing this would update anything
# persistent.
return DictView(self._metadata)
return self._metadata

@property
def sorting(self):
Expand Down Expand Up @@ -240,7 +239,7 @@ def sort(self, sorting):
mapping = dict(
sorted(
mapping.items(),
key=lambda item: item[1].metadata.get(key, _HIGH_SORTER),
key=lambda item: item[1].metadata().get(key, _HIGH_SORTER),
)
)
if direction < 0:
Expand Down Expand Up @@ -316,7 +315,7 @@ def counter_to_dict(counter, counts):

def iter_child_metadata(query_key, tree):
for key, value in tree.items():
term = value.metadata
term = value.metadata()
for subkey in query_key.split("."):
if subkey not in term:
term = None
Expand All @@ -341,7 +340,7 @@ def maybe_lower(s):
for key, value in tree.items():
words = set(
word
for s in walk_string_values(value.metadata)
for s in walk_string_values(value.metadata())
for word in maybe_lower(s).split()
)
# Note that `not set.isdisjoint` is faster than `set.intersection`. At
Expand Down
5 changes: 4 additions & 1 deletion tiled/adapters/parquet.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ def __init__(
self.partition_paths = sorted(partition_paths)
self.meta = meta
self.divisions = divisions
self.metadata = metadata or {}
self._metadata = metadata or {}
self.specs = list(specs or [])
self.access_policy = access_policy

def metadata(self):
return self._metadata

@property
def dataframe_adapter(self):
partitions = []
Expand Down
5 changes: 4 additions & 1 deletion tiled/adapters/sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,13 @@ def __init__(
self.chunks = chunks
self.shape = shape
self.dims = dims
self.metadata = metadata or {}
self._metadata = metadata or {}
self.specs = specs or []
self.access_policy = access_policy

def metadata(self):
return self._metadata

def structure(self):
return COOStructure(
dims=self.dims,
Expand Down
5 changes: 4 additions & 1 deletion tiled/adapters/sparse_blocks_parquet.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(
self.dims = dims
self.shape = shape
self.chunks = chunks
self.metadata = metadata or {}
self._metadata = metadata or {}
self.specs = list(specs or [])
self.access_policy = access_policy

Expand Down Expand Up @@ -68,6 +68,9 @@ def init_storage(
]
return assets

def metadata(self):
return self._metadata

def write_block(self, data, block):
uri = self.blocks[block]
data.to_parquet(uri)
Expand Down
2 changes: 0 additions & 2 deletions tiled/adapters/tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def __init__(
self._provided_metadata = metadata or {}
self.access_policy = access_policy

@property
def metadata(self):
# This contains some enums, but Python's built-in JSON serializer
# handles them fine (converting to str or int as appropriate).
Expand Down Expand Up @@ -128,7 +127,6 @@ def __init__(
self.dims = dims
self.access_policy = access_policy

@property
def metadata(self):
# TODO How to deal with the many headers?
return self._provided_metadata
Expand Down
5 changes: 2 additions & 3 deletions tiled/adapters/zarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ..adapters.utils import IndexersMixin
from ..iterviews import ItemsView, KeysView, ValuesView
from ..structures.core import StructureFamily
from ..utils import DictView, node_repr
from ..utils import node_repr
from .array import ArrayAdapter, slice_and_shape_from_block_and_chunks

INLINED_DEPTH = int(os.getenv("TILED_HDF5_INLINED_CONTENTS_MAX_DEPTH", "7"))
Expand Down Expand Up @@ -136,9 +136,8 @@ def __repr__(self):
def access_policy(self):
return self._access_policy

@property
def metadata(self):
return DictView(self._node.attrs)
return self._node.attrs

def __iter__(self):
yield from self._node
Expand Down
4 changes: 3 additions & 1 deletion tiled/catalog/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,16 @@ def __init__(
self.conditions = conditions or []
self.queries = queries or []
self.structure_family = node.structure_family
self.metadata = node.metadata_
self.specs = [Spec.parse_obj(spec) for spec in node.specs]
self.ancestors = node.ancestors
self.key = node.key
self.access_policy = access_policy
self.startup_tasks = [self.startup]
self.shutdown_tasks = [self.shutdown]

def metadata(self):
return self.node.metadata_

async def startup(self):
if (self.context.engine.dialect.name == "sqlite") and (
self.context.engine.url.database == ":memory:"
Expand Down
4 changes: 2 additions & 2 deletions tiled/catalog/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ async def register_single_item(
catalog,
key=key,
structure_family=adapter.structure_family,
metadata=dict(adapter.metadata),
metadata=dict(adapter.metadata()),
data_sources=[
DataSource(
mimetype=mimetype,
Expand Down Expand Up @@ -361,7 +361,7 @@ async def tiff_sequence(
catalog,
key=key,
structure_family=adapter.structure_family,
metadata=dict(adapter.metadata),
metadata=dict(adapter.metadata()),
data_sources=[
DataSource(
mimetype=mimetype,
Expand Down
8 changes: 4 additions & 4 deletions tiled/serialization/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ async def serialize_hdf5(node, metadata, filter_for_access):
else:
group = group.create_group(key)
try:
group.attrs.update(node.metadata)
group.attrs.update(node.metadata())
except TypeError:
raise SerializationError(MSG)
data = array_adapter.read()
dataset = group.create_dataset(key_path[-1], data=data)
for k, v in array_adapter.metadata.items():
for k, v in array_adapter.metadata().items():
dataset.attrs.create(k, v)
return buffer.getbuffer()

Expand All @@ -80,7 +80,7 @@ async def serialize_hdf5(node, metadata, filter_for_access):
async def serialize_json(node, metadata, filter_for_access):
"Export node to JSON, with each node having a 'contents' and 'metadata' sub-key."
root_node = node
to_serialize = {"contents": {}, "metadata": dict(root_node.metadata)}
to_serialize = {"contents": {}, "metadata": dict(root_node.metadata())}
async for key_path, array_adapter in walk(node, filter_for_access):
d = to_serialize["contents"]
node = root_node
Expand All @@ -90,7 +90,7 @@ async def serialize_json(node, metadata, filter_for_access):
else:
node = node[key]
if key not in d:
d[key] = {"contents": {}, "metadata": dict(node.metadata)}
d[key] = {"contents": {}, "metadata": dict(node.metadata())}
d = d[key]["contents"]
return safe_json_dump(to_serialize)

Expand Down
6 changes: 3 additions & 3 deletions tiled/serialization/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ async def as_dataset(node):
"'xarray_coord' or 'xarray_data_var'."
)
return xarray.Dataset(
data_vars=data_vars, coords=coords, attrs=node.metadata["attrs"]
data_vars=data_vars, coords=coords, attrs=node.metadata()["attrs"]
)


Expand Down Expand Up @@ -126,9 +126,9 @@ async def serialize_hdf5(node, metadata, filter_for_access):
group = group[key]
else:
group = group.create_group(key)
group.attrs.update(node.metadata["attrs"])
group.attrs.update(node.metadata()["attrs"])
data = array_adapter.read()
dataset = group.create_dataset(key_path[-1], data=data)
for k, v in array_adapter.metadata["attrs"].items():
for k, v in array_adapter.metadata()["attrs"].items():
dataset.attrs.create(k, v)
return buffer.getbuffer()
4 changes: 2 additions & 2 deletions tiled/server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,10 @@ async def construct_resource(
if schemas.EntryFields.metadata in fields:
if select_metadata is not None:
attributes["metadata"] = jmespath.compile(select_metadata).search(
entry.metadata
entry.metadata()
)
else:
attributes["metadata"] = entry.metadata
attributes["metadata"] = entry.metadata()
if schemas.EntryFields.specs in fields:
specs = []
for spec in getattr(entry, "specs", []):
Expand Down
10 changes: 5 additions & 5 deletions tiled/server/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ async def array_block(
entry.structure_family,
serialization_registry,
array,
entry.metadata,
entry.metadata(),
request,
format,
specs=getattr(entry, "specs", []),
Expand Down Expand Up @@ -471,7 +471,7 @@ async def array_full(
structure_family,
serialization_registry,
array,
entry.metadata,
entry.metadata(),
request,
format,
specs=getattr(entry, "specs", []),
Expand Down Expand Up @@ -530,7 +530,7 @@ async def dataframe_partition(
"dataframe",
serialization_registry,
df,
entry.metadata,
entry.metadata(),
request,
format,
specs=getattr(entry, "specs", []),
Expand Down Expand Up @@ -592,7 +592,7 @@ async def node_full(
entry.structure_family,
serialization_registry,
data,
entry.metadata,
entry.metadata(),
request,
format,
specs=getattr(entry, "specs", []),
Expand Down Expand Up @@ -837,7 +837,7 @@ async def put_metadata(
)

metadata, structure_family, structure, specs = (
body.metadata if body.metadata is not None else entry.metadata,
body.metadata if body.metadata is not None else entry.metadata(),
entry.structure_family,
get_structure(entry),
body.specs if body.specs is not None else entry.specs,
Expand Down

0 comments on commit cc4c599

Please sign in to comment.