Coverage for /home/runner/work/viur-core/viur-core/viur/src/viur/core/prototypes/skelmodule.py: 0%
39 statements
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-16 22:16 +0000
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-16 22:16 +0000
1import os
2import yaml
3import logging
4from viur.core import Module, db
5from viur.core.config import conf
6from viur.core.skeleton import skeletonByKind, Skeleton, SkeletonInstance
7import typing as t
10SINGLE_ORDER_TYPE = str | tuple[str, db.SortOrder]
11"""
12Type for exactly one sort order definitions.
13"""
15ORDER_TYPE = SINGLE_ORDER_TYPE | tuple[SINGLE_ORDER_TYPE] | list[SINGLE_ORDER_TYPE] | dict[str, str | int] | None
16"""
17Type for sort order definitions (any amount of single order definitions).
18"""
20DEFAULT_ORDER_TYPE = ORDER_TYPE | t.Callable[[db.Query], ORDER_TYPE]
21"""
22Type for default sort order definitions.
23"""
26def __load_indexes_from_file() -> dict[str, list]:
27 """
28 Loads all indexes from the index.yaml and stores it in a dictionary sorted by the module(kind)
29 :return A dictionary of indexes per module
30 """
31 indexes_dict = {}
32 try:
33 with open(os.path.join(conf.instance.project_base_path, "index.yaml"), "r") as file:
34 indexes = yaml.safe_load(file)
35 indexes = indexes.get("indexes", [])
36 for index in indexes:
37 index["properties"] = [_property["name"] for _property in index["properties"]]
38 indexes_dict.setdefault(index["kind"], []).append(index)
40 except FileNotFoundError:
41 logging.warning("index.yaml not found")
42 return {}
44 return indexes_dict
47DATASTORE_INDEXES = __load_indexes_from_file()
50class SkelModule(Module):
51 """
52 This is the extended module prototype used by any other ViUR module prototype.
53 It a prototype which generally is bound to some database model abstracted by the ViUR skeleton system.
54 """
56 kindName: str = None
57 """
58 Name of the datastore kind that is handled by this module.
60 This information is used to bind a specific :class:`viur.core.skeleton.Skeleton`-class to this
61 prototype. By default, it is automatically determined from the module's class name, so a module named
62 `Animal` refers to a Skeleton named `AnimalSkel` and its kindName is `animal`.
64 For more information, refer to the function :func:`~_resolveSkelCls`.
65 """
67 def __init__(self, *args, **kwargs):
68 super().__init__(*args, **kwargs)
70 # automatically determine kindName when not set
71 if self.kindName is None:
72 self.kindName = str(type(self).__name__).lower()
74 # assign index descriptions from index.yaml
75 self.indexes = DATASTORE_INDEXES.get(self.kindName, [])
77 def _resolveSkelCls(self, *args, **kwargs) -> t.Type[Skeleton]:
78 """
79 Retrieve the generally associated :class:`viur.core.skeleton.Skeleton` that is used by
80 the application.
82 This is either be defined by the member variable *kindName* or by a Skeleton named like the
83 application class in lower-case order.
85 If this behavior is not wanted, it can be definitely overridden by defining module-specific
86 :func:`~viewSkel`, :func:`~addSkel`, or :func:`~editSkel` functions, or by overriding this
87 function in general.
89 :return: Returns a Skeleton class that matches the application.
90 """
91 return skeletonByKind(self.kindName)
93 def baseSkel(self, *args, **kwargs) -> SkeletonInstance:
94 """
95 Returns an instance of an unmodified base skeleton for this module.
97 This function should only be used in cases where a full, unmodified skeleton of the module is required, e.g.
98 for administrative or maintenance purposes.
100 By default, baseSkel is used by :func:`~viewSkel`, :func:`~addSkel`, and :func:`~editSkel`.
101 """
102 return self._resolveSkelCls(*args, **kwargs)()