Skip to content

Commit

Permalink
replace "definition" with "model" throughout
Browse files Browse the repository at this point in the history
  • Loading branch information
gilesknap committed Jun 18, 2024
1 parent 2bd5cb3 commit c191ef8
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 67 deletions.
53 changes: 26 additions & 27 deletions src/ibek/entity_factory.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
A class for constructing Entity classes from Definitions
A class for constructing Entity classes from EntityModels
"""

from __future__ import annotations
Expand All @@ -23,43 +23,42 @@
class EntityFactory:
def __init__(self) -> None:
"""
A class to create `Entity` models from `EntityDefinition`s.
A class to create `Entity` models from `EntityModel`s.
Created models are stored in `self._entity_models` to lookup when resolving nested `SubEntity`s.
Created models are stored in `self._entity_models` to lookup when
resolving nested `SubEntity`s.
"""
self._entity_models: Dict[str, Type[Entity]] = {}
# starting a new EntityFactory implies we should throw away any existing
# Entity instances - this is required for tests which create multiple
# EntityFactories
clear_entity_model_ids()

def make_entity_models(self, definition_yaml: List[Path]) -> List[Type[Entity]]:
def make_entity_models(self, entity_model_yaml: List[Path]) -> List[Type[Entity]]:
"""
Read a set of *.ibek.support.yaml files and generate Entity classes
from their Definition entries
from their EntityModel entries
"""

for definition in definition_yaml:
support_dict = YAML(typ="safe").load(definition)
for entity_model in entity_model_yaml:
support_dict = YAML(typ="safe").load(entity_model)

try:
Support.model_validate(support_dict)

# deserialize the support module definition file
# deserialize the support module yaml file
support = Support(**support_dict)
# make Entity classes described in the support module definition file
# make Entity classes described in the support module yaml file
self._make_entity_models(support)
except ValidationError:
print(f"PYDANTIC VALIDATION ERROR IN {definition}")
print(f"PYDANTIC VALIDATION ERROR IN {entity_model}")
raise

return list(self._entity_models.values())

def _make_entity_model(
self, definition: EntityModel, support: Support
) -> Type[Entity]:
def _make_entity_model(self, model: EntityModel, support: Support) -> Type[Entity]:
"""
Create an Entity Model from a Definition instance and a Support instance.
Create an Entity Model from a EntityModel instance and a Support instance.
"""

def add_arg(name, typ, description, default):
Expand Down Expand Up @@ -91,10 +90,10 @@ def add_arg(name, typ, description, default):
validators: Dict[str, Any] = {}

# fully qualified name of the Entity class including support module
full_name = f"{support.module}.{definition.name}"
full_name = f"{support.module}.{model.name}"

# add in each of the arguments as a Field in the Entity
for name, arg in definition.parameters.items():
for name, arg in model.parameters.items():
type: Any

if isinstance(arg, ObjectParam):
Expand Down Expand Up @@ -122,7 +121,7 @@ def add_arg(name, typ, description, default):

# add the type literal which discriminates between the different Entity classes
typ = Literal[full_name] # type: ignore
args["type"] = (typ, Field(description=definition.description))
args["type"] = (typ, Field(description=model.description))

class_name = full_name.replace(".", "_")
entity_cls = create_model(
Expand All @@ -132,8 +131,8 @@ def add_arg(name, typ, description, default):
__base__=Entity,
) # type: ignore

# add a link back to the Definition Instance that generated this Entity Class
entity_cls.__definition__ = definition
# add a link back to the EntityModel Instance that generated this Entity Class
entity_cls._model = model

# store this Entity class in the factory
self._entity_models[full_name] = entity_cls
Expand All @@ -142,20 +141,20 @@ def add_arg(name, typ, description, default):

def _make_entity_models(self, support: Support) -> List[Type[Entity]]:
"""
Create Entity subclasses for all Definition instances in the given
Create Entity subclasses for all EntityModel instances in the given
Support instance. Returns a list of the Entity subclasses Models.
"""
entity_names = []
entity_models = []

for definition in support.entity_models:
if definition.name in entity_names:
for model in support.entity_models:
if model.name in entity_names:
# not tested because schema validation will always catch this first
raise ValueError(f"Duplicate entity name {definition.name}")
raise ValueError(f"Duplicate entity name {model.name}")

entity_models.append(self._make_entity_model(definition, support))
entity_models.append(self._make_entity_model(model, support))

entity_names.append(definition.name)
entity_names.append(model.name)
return entity_models

def resolve_sub_entities(self, entities: List[Entity]) -> List[Entity]:
Expand All @@ -164,11 +163,11 @@ def resolve_sub_entities(self, entities: List[Entity]) -> List[Entity]:
"""
resolved_entities: List[Entity] = []
for parent_entity in entities:
definition = parent_entity.__definition__
model = parent_entity._model
# add the parent standard entity
resolved_entities.append(parent_entity)
# add in SubEntities if any
for sub_entity in definition.sub_entities:
for sub_entity in model.sub_entities:
# find the Entity Class that the SubEntity represents
entity_cls = self._entity_models[sub_entity.type]
# get the SubEntity arguments
Expand Down
6 changes: 3 additions & 3 deletions src/ibek/entity_model.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
The Definition class describes what a given support module can instantiate.
The EntityModel class describes what a given support module can instantiate.
"""

from __future__ import annotations
Expand Down Expand Up @@ -127,7 +127,7 @@ class EntityModel(BaseSettings):
"""

name: str = Field(
description="Publish Definition as type <module>.<name> for IOC instances"
description="Publish EntityModel as type <module>.<name> for IOC instances"
)
description: str = Field(
description="A description of the Support module defined here"
Expand Down Expand Up @@ -176,7 +176,7 @@ class EntityModel(BaseSettings):
)

def _get_id_arg(self):
"""Returns the value of the ID argument for this definition, if it exists"""
"""Returns the value of the ID argument for this Model, if it exists"""
for name, value in self.parameters.items():
if isinstance(value, IdParam):
return name
4 changes: 2 additions & 2 deletions src/ibek/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ def STATIC_BUILD(self):

@property
def IBEK_DEFS(self):
"""Directory containing ibek support yaml definitions."""
"""Directory containing ibek support yaml files."""
return self._EPICS_ROOT / "ibek-defs"

@property
def PVI_DEFS(self):
"""Directory containing pvi device yaml definitions."""
"""Directory containing pvi device yaml files."""
return self._EPICS_ROOT / "pvi-defs"

@property
Expand Down
20 changes: 10 additions & 10 deletions src/ibek/ioc.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
Classes for generating an IocInstance derived class from a
support module definition YAML file
Classes for generating an IocInstance derived class from a set of
support module YAML files
"""

from __future__ import annotations
Expand Down Expand Up @@ -55,7 +55,7 @@ class Entity(BaseSettings):
entity_enabled: bool = Field(
description="enable or disable this entity instance", default=True
)
__definition__: EntityModel
_model: EntityModel

def _process_field(self: Entity, name: str, value: Any, typ: str):
"""
Expand Down Expand Up @@ -107,23 +107,23 @@ def add_ibek_attributes(self):
ibek.runtime_cmds.generate().
"""

if self.__definition__.pre_defines:
for name, define in self.__definition__.pre_defines.items():
if self._model.pre_defines:
for name, define in self._model.pre_defines.items():
self._process_field(name, define.value, define.type)

if self.__definition__.parameters:
for name, parameter in self.__definition__.parameters.items():
if self._model.parameters:
for name, parameter in self._model.parameters.items():
self._process_field(name, getattr(self, name), parameter.type)

if self.__definition__.post_defines:
for name, define in self.__definition__.post_defines.items():
if self._model.post_defines:
for name, define in self._model.post_defines.items():
self._process_field(name, define.value, define.type)

return self

def __str__(self):
# if this entity has an id then its string representation is the value of id
id_name = self.__definition__._get_id_arg()
id_name = self._model._get_id_arg()
return getattr(self, id_name) if id_name else super().__str__()

def __repr__(self):
Expand Down
2 changes: 1 addition & 1 deletion src/ibek/ioc_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def deserialize_ioc(
self, ioc_instance_yaml: Path, entity_models: List[Type[Entity]]
) -> IOC:
"""
Takes an ioc instance entities file, list of generic ioc definitions files.
Takes an ioc instance entities file, list of generic ioc yaml files.
Returns a model of the resulting ioc instance
"""
Expand Down
2 changes: 1 addition & 1 deletion src/ibek/parameters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Classes to specify arguments to Definitions
Classes to specify arguments to Entity Models
"""

from __future__ import annotations
Expand Down
12 changes: 6 additions & 6 deletions src/ibek/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Render:
"""
A class for generating snippets of startup script / EPICS DB
by using Jinja to combine snippet templates from support module
definition yaml with substitution values supplied in ioc entity yaml
yaml with substitution values supplied in ioc entity yaml
"""

def __init__(self: "Render"):
Expand All @@ -30,13 +30,13 @@ def render_text(
but we pass all strings though jinja again to render any other jinja
in the IOC (e.g. database and function entries)
once uses the name of the definition + suffix to track which lines
once uses the name of the model + suffix to track which lines
have been rendered already. The suffix can be used where a given
Entity has more than one element to render once (e.g. functions)
"""

if when == When.first.value:
name = instance.__definition__.name + suffix
name = instance._model.name + suffix
if name not in self.once_done:
self.once_done.append(name)
else:
Expand Down Expand Up @@ -73,23 +73,23 @@ def render_pre_ioc_init(self, instance: Entity) -> Optional[str]:
render the startup script by combining the jinja template from
an entity with the arguments from an Entity
"""
pre_init = instance.__definition__.pre_init
pre_init = instance._model.pre_init
return self.render_script(instance, pre_init)

def render_post_ioc_init(self, instance: Entity) -> Optional[str]:
"""
render the post-iocInit entries by combining the jinja template
from an entity with the arguments from an Entity
"""
post_init = instance.__definition__.post_init
post_init = instance._model.post_init
return self.render_script(instance, post_init)

def render_environment_variables(self, instance: Entity) -> Optional[str]:
"""
render the environment variable elements by combining the jinja template
from an entity with the arguments from an Entity
"""
variables = getattr(instance.__definition__, "env_vars")
variables = getattr(instance._model, "env_vars")
if not variables:
return None

Expand Down
6 changes: 3 additions & 3 deletions src/ibek/render_db.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
A class for rendering a substitution file from multiple instantiations of
support module definitions
support module yaml files.
"""

from dataclasses import dataclass
Expand Down Expand Up @@ -56,7 +56,7 @@ def parse_instances(self) -> None:
while validating the arguments
"""
for entity in self.entities:
databases = entity.__definition__.databases
databases = entity._model.databases

# Not all entities instantiate database templates
if entity.entity_enabled and databases is not None:
Expand Down Expand Up @@ -85,7 +85,7 @@ def add_database(self, database: Database, entity: Entity) -> None:
self.add_row(database.file, database.args, entity)

def add_extra_databases(self, databases: List[Tuple[Database, Entity]]) -> None:
"""Add databases that are not part of Entity definitions
"""Add databases that are not part of EntityModels
Args:
databases: Databases to add, each mapped against an Entity to use as context
Expand Down
4 changes: 2 additions & 2 deletions src/ibek/runtime_cmds/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def generate(
),
definitions: List[Path] = typer.Argument(
...,
help="The filepath to a support module definition file",
help="The filepath to a support module yaml file",
autocompletion=lambda: [], # Forces path autocompletion
),
):
Expand Down Expand Up @@ -85,7 +85,7 @@ def generate_pvi(ioc: IOC) -> Tuple[List[IndexEntry], List[Tuple[Database, Entit

formatted_pvi_devices: List[str] = []
for entity in ioc.entities:
definition = entity.__definition__
definition = entity._model
if not hasattr(definition, "pvi") or definition.pvi is None:
continue
entity_pvi = definition.pvi
Expand Down
6 changes: 2 additions & 4 deletions src/ibek/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@

class Support(BaseSettings):
"""
Lists the definitions for a support module, this defines what Entities it supports
Provides the deserialize entry point.
Lists the EntityModels for a support module, this defines what Entities it supports
"""

shared: Sequence[Any] = Field(
Expand All @@ -27,7 +25,7 @@ class Support(BaseSettings):

module: str = Field(description="Support module name, normally the repo name")
entity_models: Sequence[EntityModel] = Field(
description="The definitions an IOC can create using this module"
description="The Entity Models an IOC can create using this module"
)

@classmethod
Expand Down
6 changes: 3 additions & 3 deletions tests/samples/schemas/ibek.support.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
"description": "A Model for a class of Entity that an IOC instance may instantiate",
"properties": {
"name": {
"description": "Publish Definition as type <module>.<name> for IOC instances",
"description": "Publish EntityModel as type <module>.<name> for IOC instances",
"title": "Name",
"type": "string"
},
Expand Down Expand Up @@ -690,7 +690,7 @@
}
},
"additionalProperties": false,
"description": "Lists the definitions for a support module, this defines what Entities it supports\n\nProvides the deserialize entry point.",
"description": "Lists the EntityModels for a support module, this defines what Entities it supports",
"properties": {
"shared": {
"default": [],
Expand All @@ -705,7 +705,7 @@
"type": "string"
},
"entity_models": {
"description": "The definitions an IOC can create using this module",
"description": "The Entity Models an IOC can create using this module",
"items": {
"$ref": "#/$defs/EntityModel"
},
Expand Down
Loading

0 comments on commit c191ef8

Please sign in to comment.