Objects and configuration

A configurable component consists of a Config class, which describes its configuration, and an object class, which extends Node. Base classes for most components are in gws.base, for example Object.

Config classes

A Config class extends Config or the Config of a base component. Each field has a type annotation and a docstring on the next line:

class Config(gws.Config):
    """Search provider."""

    url: gws.Url
    """Service url."""
    maxResults: int = 100
    """Maximum number of results."""
    timeout: Optional[gws.Duration]
    """Request timeout."""

To make a component's access configurable, extend ConfigWithAccess, which adds the permissions field. The docstrings appear in the configuration reference, see Configuration reference.

Reading the configuration

The configuration is validated and converted before the object is created. Special types are converted to their runtime values, for example a Duration like "2m" becomes the number of seconds, and a CrsName becomes a Crs object. See Specs for the list.

The object reads its configuration with self.cfg(key, default=None). Keys can be dotted to read nested values, like self.cfg('provider.url'). The whole configuration is in self.config, a Data object.

Lifecycle

A node has four lifecycle methods:

MethodWhen
pre_configurewhen the node is created, before configure
configurewhen the node is created, creates children
post_configureafter the whole tree is built
activatein every worker process, after loading the stored tree

The server calls pre_configure, configure and post_configure of all base classes automatically, base classes first. Do not call super().configure(). activate is an ordinary method: call super().activate() if a base class implements it.

configure sets attributes from the configuration and creates children. post_configure is the place for code that needs other parts of the tree, which might not exist yet during configure. activate opens per-process resources, see Architecture.

Creating children

MethodPurpose
create_child(classref, config=None, **kwargs)create a child node
create_child_if_configured(classref, config=None, **kwargs)same, but return None if config is empty
create_children(classref, configs, **kwargs)create a child node for each config in a list

classref is a class, a class name, or an extension category like gws.ext.object.layer. With a category, the type key of the configuration selects the class. Keyword arguments are defaults for the configuration. Declare the attributes with their types at the class level:

class Object(gws.Node):
    layers: list[gws.Layer]
    storage: Optional[gws.base.storage.Object]

    def configure(self):
        self.layers = self.create_children(gws.ext.object.layer, self.cfg('layers'))
        self.storage = self.create_child_if_configured(gws.base.storage.Object, self.cfg('storage'), categoryName='Select')

If a child fails to configure, create_child returns None, the error is reported, and the parent continues.

The root (self.root) also creates nodes:

Finding objects

MethodSearches
self.root.get(uid, classref=None)a node by its uid
self.root.find_all(classref), find_firstthe whole tree
self.find_all(classref), find_firstdirect children
self.find_closest(classref), find_ancestorsancestors
self.find_descendants(classref)descendants

The uid of a node is taken from the uid key of its configuration, or generated.

Props

props(user) returns the properties of a node for the client, as a Props object:

def props(self, user):
    return gws.Props(
        title=self.title,
        layers=self.layers,
    )

Use props_of to get the props of a node. It returns None if the user cannot read the node. Nodes nested in the returned props are converted the same way, and nodes the user cannot read are left out.

Configuration errors

To reject an invalid configuration, raise ConfigurationError. If it is raised in configure, the node is not created. The error is listed in the configuration report with its location in the configuration files.

For problems that do not prevent the node from working, call self.root.config_warning(message).