Skip to content

Commit

Permalink
Merge pull request #3 from flaxandteal/feature/graphql-api
Browse files Browse the repository at this point in the history
GraphQL API: Provides endpoints for GraphQL
  • Loading branch information
philtweir authored May 1, 2024
2 parents c657cbb + 787c5e1 commit 1dd8a30
Show file tree
Hide file tree
Showing 49 changed files with 3,288 additions and 366 deletions.
10 changes: 7 additions & 3 deletions arches_orm/arches_django/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ def get_wrapper(self):

return ArchesDjangoResourceWrapper

def load_from_id(self, resource_id, from_prefetch=None):
from arches_orm.utils import get_resource_models_for_adapter
def load_from_id(self, resource_id, from_prefetch=None, lazy=False):
from arches_orm.wkrm import get_resource_models_for_adapter
from arches.app.models.resource import Resource

resource = (
Expand All @@ -38,10 +38,14 @@ def load_from_id(self, resource_id, from_prefetch=None):
logger.error("Tried to load non-existent WKRM: %s", resource_id)
return None
return resource_models_by_graph_id[str(resource.graph_id)].from_resource(
resource, related_prefetch=from_prefetch
resource, related_prefetch=from_prefetch, lazy=lazy
)

def get_hooks(self):
from .hooks import HOOKS

return HOOKS

def get_wkrm_definitions(self):
from django.conf import settings
return settings.WELL_KNOWN_RESOURCE_MODELS
419 changes: 419 additions & 0 deletions arches_orm/arches_django/bulk_create.py

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions arches_orm/arches_django/datatypes/_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def make(
node: Node,
value: Any = None,
parent: Any = None,
parent_cls: Any = None,
child_nodes: list = None,
datatype: str = None,
):
Expand All @@ -86,19 +87,23 @@ def make(

if datatype_name in self:
registration = self[datatype_name]
record = registration(tile, node, value, parent, child_nodes, datatype)
return record, registration.transform_value_for_tile
record = registration(tile, node, value, parent, parent_cls, child_nodes, datatype)
return record, registration.transform_value_for_tile, datatype_name, datatype.collects_multiple_values()
else:
return datatype.transform_value_for_tile(
value or tile.data, **(node.config or {})
), lambda value: datatype.transform_value_for_tile(
if value or (tile and tile.data.get(node.nodeid)):
transformed = datatype.transform_value_for_tile(
value or tile.data, **(node.config or {})
)
else:
transformed = None
return transformed, lambda value: datatype.transform_value_for_tile(
value, **(node.config or {})
)
), datatype_name, datatype.collects_multiple_values()


def get_view_model_for_datatype(tile, node, parent, child_nodes, value=None):
def get_view_model_for_datatype(tile, node, parent, parent_cls, child_nodes, value=None):
return REGISTER.make(
tile, node, value=value, parent=parent, child_nodes=child_nodes
tile, node, value=value, parent=parent, parent_cls=parent_cls, child_nodes=child_nodes
)


Expand Down
52 changes: 46 additions & 6 deletions arches_orm/arches_django/datatypes/concepts.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
import uuid
from functools import lru_cache

from arches.app.models.concept import Concept

from arches_orm.view_models import (
ConceptListValueViewModel,
ConceptValueViewModel,
EmptyConceptValueViewModel,
)
from arches_orm.collection import make_collection
from ._register import REGISTER

@lru_cache
def retrieve_collection(concept_id):
collection = Concept(id=concept_id)
datatype = REGISTER._datatype_factory.get_instance("concept")
return make_collection(
collection.get_preflabel().value,
[
ConceptValueViewModel(
concept[2],
lambda value_id: datatype.get_value(value_id),
concept_id,
lambda _: retrieve_collection(concept_id)
) for concept in
collection.get_child_collections(concept_id)
]
)


@REGISTER("concept-list")
def concept_list(tile, node, value: list[uuid.UUID | str] | None, _, __, ___):
def concept_list(tile, node, value: list[uuid.UUID | str] | None, _, __, ___, ____):
if value is None:
value = tile.data.get(str(node.nodeid), [])

Expand All @@ -24,15 +46,33 @@ def cl_as_tile_data(concept_list):


@REGISTER("concept")
def concept_value(tile, node, value: uuid.UUID | str | None, __, ___, datatype):
def concept_value(tile, node, value: uuid.UUID | str | None, __, ___, ____, datatype):
if value is None:
value = tile.data.get(str(node.nodeid), None)
concept_value_cb = datatype.get_value
if value is None:
def concept_value_cb(value):
if isinstance(value, ConceptValueViewModel):
value = value._concept_value_id
return datatype.get_value(value)

collection_id = None
if node and node.config:
collection_id = node.config.get("rdmCollection")

if value is None or isinstance(value, EmptyConceptValueViewModel):
if collection_id:
return EmptyConceptValueViewModel(
collection_id,
retrieve_collection
)
return None
return ConceptValueViewModel(value, concept_value_cb)
return ConceptValueViewModel(
value,
concept_value_cb,
collection_id,
retrieve_collection
)


@concept_value.as_tile_data
def cv_as_tile_data(concept_value):
return str(concept_value._concept_value_id)
return None if isinstance(concept_value, EmptyConceptValueViewModel) else str(concept_value._concept_value_id)
9 changes: 7 additions & 2 deletions arches_orm/arches_django/datatypes/resource_instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def resource_instance_list(
node,
value: uuid.UUID | str | WKRI | Resource | ResourceInstance | None,
parent,
parent_cls,
child_nodes,
datatype,
):
Expand All @@ -25,6 +26,7 @@ def make_ri_cb(value):
node,
value=value,
parent=parent,
parent_cls=parent_cls,
child_nodes=child_nodes,
datatype="resource-instance",
)
Expand All @@ -50,10 +52,11 @@ def resource_instance(
node,
value: uuid.UUID | str | WKRI | Resource | ResourceInstance | None,
parent_wkri,
parent_cls,
child_nodes,
resource_instance_datatype,
):
from arches_orm.utils import (
from arches_orm.wkrm import (
get_well_known_resource_model_by_graph_id,
attempt_well_known_resource_model,
)
Expand All @@ -76,7 +79,9 @@ def resource_instance(
else:
return None

if not isinstance(resource_instance, WKRI):
if not resource_instance:
return None
elif not isinstance(resource_instance, WKRI):
wkrm = get_well_known_resource_model_by_graph_id(
resource_instance.graph_id, default=None
)
Expand Down
44 changes: 32 additions & 12 deletions arches_orm/arches_django/datatypes/semantic.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,55 @@
import logging
import uuid
from arches.app.models.models import ResourceInstance
from arches.app.models.resource import Resource

from arches_orm.adapter import get_adapter
from arches_orm.view_models import (
WKRI,
SemanticViewModel,
)
from ._register import REGISTER


logger = logging.getLogger(__name__)


@REGISTER("semantic")
def semantic(
tile,
node,
value: uuid.UUID | str | WKRI | Resource | ResourceInstance | None,
parent,
parent_cls,
child_nodes,
datatype,
):
child_keys = {key: value[1] for key, value in child_nodes.items()}
child_keys = {key: child_value[1] for key, child_value in child_nodes.items()}

def make_pseudo_node(key):
child = parent._make_pseudo_node(
child = parent_cls._make_pseudo_node_cls(
key,
tile=(tile if child_nodes[key][1] else None), # Does it share a tile
wkri=parent
)
child._parent_node = svm
parent._values.setdefault(key, [])
parent._values[key].append(child)
if parent:
parent._values.setdefault(key, [])
parent._values[key].append(child)
return child

def get_child_values(svm):
if not parent:
return {}
for key in child_nodes:
parent._values.get(key)
children = {
key: value
for key, values in parent._values.items()
for value in values
if key in child_keys
and value is not None
and value._parent_node is None
and (value._parent_node is None or value._parent_node == svm)
and (
(tile and value.parenttile_id == tile.tileid)
or (
Expand All @@ -53,33 +65,41 @@ def get_child_values(svm):
}
for key, value in children.items():
value._parent_node = svm
if key in svm._child_values:
raise RuntimeError(
"Semantic view model construction error - "
f"duplicate keys outside node list: {key}"
)
svm._child_values[key] = value

return children

svm = SemanticViewModel(
parent,
child_keys,
value,
make_pseudo_node,
get_child_values,
)
if value:
try:
svm.update(value)
except Exception as exc:
_tile_loading_error("Suppressed a tile loading error: %s (tile: %s; node: %s)", exc, str(tile), str(node))
svm.get_children()

return svm


def _tile_loading_error(reason, exc, *args):
if not get_adapter().config.get("suppress-tile-loading-errors"):
raise exc
elif not get_adapter().config.get("silence-tile-loading-errors"):
logging.warning(reason, exc, *args)

@semantic.as_tile_data
def sm_as_tile_data(semantic):
# Ensure all nodes have populated the tile
relationships = []
for value in semantic.get_children(direct=True):
# We do not use tile, because a child node will ignore its tile reference.
tile, subrelationships = value.get_tile()
_, subrelationships = value.get_tile()
relationships += subrelationships
# This is none because the semantic type has no nodal value,
# only its children have nodal values, and the nodal value of this nodeid should
# not exist.
return None, relationships
2 changes: 1 addition & 1 deletion arches_orm/arches_django/datatypes/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


@REGISTER("string")
def string(tile, node, value: dict | None, _, __, string_datatype):
def string(tile, node, value: dict | None, _, __, ___, string_datatype):
if tile:
tile.data.setdefault(str(node.nodeid), {})
if value is not None:
Expand Down
2 changes: 1 addition & 1 deletion arches_orm/arches_django/datatypes/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def __bool__(self):


@REGISTER("user")
def user(tile, node, value, _, __, user_datatype) -> UserProtocol:
def user(tile, node, value, _, __, ___, user_datatype) -> UserProtocol:
user = None
value = value or tile.data.get(str(node.nodeid))
if value:
Expand Down
Loading

0 comments on commit 1dd8a30

Please sign in to comment.