Skip to content

Commit

Permalink
Refactor link-writing into separate module.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielballan committed Mar 8, 2024
1 parent afb45ca commit 9b0f051
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 58 deletions.
45 changes: 15 additions & 30 deletions tiled/server/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
)
from . import schemas
from .etag import tokenize
from .links import links_for_node
from .utils import record_timing

del queries
Expand Down Expand Up @@ -404,6 +405,7 @@ async def construct_resource(
depth=0,
):
path_str = "/".join(path_parts)
id_ = path_parts[-1] if path_parts else ""
attributes = {"ancestors": path_parts[:-1]}
if include_data_sources and hasattr(entry, "data_sources"):
attributes["data_sources"] = entry.data_sources
Expand Down Expand Up @@ -488,15 +490,16 @@ async def construct_resource(
for key, direction in entry.sorting
]
d = {
"id": path_parts[-1] if path_parts else "",
"id": id_,
"attributes": schemas.NodeAttributes(**attributes),
}
if not omit_links:
d["links"] = {
"self": f"{base_url}/metadata/{path_str}",
"search": f"{base_url}/search/{path_str}",
"full": f"{base_url}/container/full/{path_str}",
}
d["links"] = links_for_node(
entry.structure_family,
entry.structure(),
base_url,
path_str,
)

resource = schemas.Resource[
schemas.NodeAttributes, schemas.ContainerLinks, schemas.ContainerMeta
Expand All @@ -510,34 +513,16 @@ async def construct_resource(
entry.structure_family
]
links.update(
{
link: template.format(base_url=base_url, path=path_str)
for link, template in FULL_LINKS[entry.structure_family].items()
}
links_for_node(
entry.structure_family,
entry.structure(),
base_url,
path_str,
)
)
structure = asdict(entry.structure())
if schemas.EntryFields.structure_family in fields:
attributes["structure_family"] = entry.structure_family
if entry.structure_family == StructureFamily.sparse:
shape = structure.get("shape")
block_template = ",".join(f"{{{index}}}" for index in range(len(shape)))
links[
"block"
] = f"{base_url}/array/block/{path_str}?block={block_template}"
elif entry.structure_family == StructureFamily.array:
shape = structure.get("shape")
block_template = ",".join(
f"{{index_{index}}}" for index in range(len(shape))
)
links[
"block"
] = f"{base_url}/array/block/{path_str}?block={block_template}"
elif entry.structure_family == StructureFamily.table:
links[
"partition"
] = f"{base_url}/table/partition/{path_str}?partition={{index}}"
elif entry.structure_family == StructureFamily.awkward:
links["buffers"] = f"{base_url}/awkward/buffers/{path_str}"
if schemas.EntryFields.structure in fields:
attributes["structure"] = structure
else:
Expand Down
53 changes: 53 additions & 0 deletions tiled/server/links.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Generate the 'links' section of the response JSON.
The links vary by structure family.
"""
from ..structures.core import StructureFamily


def links_for_node(structure_family, structure, base_url, path_str):
links = {}
links = LINKS_BY_STRUCTURE_FAMILY[structure_family](
structure_family, structure, base_url, path_str
)
links["self"] = f"{base_url}/metadata/{path_str}"
return links


def links_for_array(structure_family, structure, base_url, path_str):
links = {}
block_template = ",".join(f"{{{index}}}" for index in range(len(structure.shape)))
links["block"] = f"{base_url}/array/block/{path_str}?block={block_template}"
links["full"] = f"{base_url}/array/full/{path_str}"
return links


def links_for_awkward(structure_family, structure, base_url, path_str):
links = {}
links["buffers"] = f"{base_url}/awkward/buffers/{path_str}"
links["full"] = f"{base_url}/awkward/full/{path_str}"
return links


def links_for_container(structure_family, structure, base_url, path_str):
links = {}
links["full"] = f"{base_url}/container/full/{path_str}"
links["search"] = f"{base_url}/search/{path_str}"
return links


def links_for_table(structure_family, structure, base_url, path_str):
links = {}
links["partition"] = f"{base_url}/table/partition/{path_str}?partition={{index}}"
links["full"] = f"{base_url}/table/full/{path_str}"
return links


LINKS_BY_STRUCTURE_FAMILY = {
StructureFamily.array: links_for_array,
StructureFamily.awkward: links_for_awkward,
StructureFamily.container: links_for_container,
StructureFamily.sparse: links_for_array, # spare and array are the same
StructureFamily.table: links_for_table,
}
28 changes: 4 additions & 24 deletions tiled/server/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
get_validation_registry,
slice_,
)
from .links import links_for_node
from .settings import get_settings
from .utils import filter_for_access, get_base_url, record_timing

Expand Down Expand Up @@ -1172,30 +1173,9 @@ async def _create_node(
specs=body.specs,
data_sources=body.data_sources,
)
links = {}
base_url = get_base_url(request)
path_parts = [segment for segment in path.split("/") if segment] + [key]
path_str = "/".join(path_parts)
links["self"] = f"{base_url}/metadata/{path_str}"
if body.structure_family in {StructureFamily.array, StructureFamily.sparse}:
block_template = ",".join(
f"{{{index}}}" for index in range(len(node.structure().shape))
)
links["block"] = f"{base_url}/array/block/{path_str}?block={block_template}"
links["full"] = f"{base_url}/array/full/{path_str}"
elif body.structure_family == StructureFamily.table:
links[
"partition"
] = f"{base_url}/table/partition/{path_str}?partition={{index}}"
links["full"] = f"{base_url}/table/full/{path_str}"
elif body.structure_family == StructureFamily.container:
links["full"] = f"{base_url}/container/full/{path_str}"
links["search"] = f"{base_url}/search/{path_str}"
elif body.structure_family == StructureFamily.awkward:
links["buffers"] = f"{base_url}/awkward/buffers/{path_str}"
links["full"] = f"{base_url}/awkward/full/{path_str}"
else:
raise NotImplementedError(body.structure_family)
links = links_for_node(
structure_family, structure, get_base_url(request), path + f"/{key}"
)
response_data = {
"id": key,
"links": links,
Expand Down
8 changes: 4 additions & 4 deletions tiled/server/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ class DataSource(pydantic.BaseModel):
Union[
ArrayStructure,
AwkwardStructure,
TableStructure,
NodeStructure,
SparseStructure,
TableStructure,
]
] = None
mimetype: Optional[str] = None
Expand Down Expand Up @@ -169,9 +169,9 @@ class NodeAttributes(pydantic.BaseModel):
Union[
ArrayStructure,
AwkwardStructure,
TableStructure,
NodeStructure,
SparseStructure,
TableStructure,
]
]
sorting: Optional[List[SortingItem]]
Expand Down Expand Up @@ -218,11 +218,11 @@ class SparseLinks(pydantic.BaseModel):


resource_links_type_by_structure_family = {
StructureFamily.container: ContainerLinks,
StructureFamily.array: ArrayLinks,
StructureFamily.awkward: AwkwardLinks,
StructureFamily.table: DataFrameLinks,
StructureFamily.container: ContainerLinks,
StructureFamily.sparse: SparseLinks,
StructureFamily.table: DataFrameLinks,
}


Expand Down

0 comments on commit 9b0f051

Please sign in to comment.