.. _custom_scheme_howto: Create a custom Taurus scheme ============================= Taurus schemes map model URIs such as ``tango:`` or ``eval:`` to Taurus models. A custom scheme can be provided by an external plugin when Taurus needs to access a new type of data source. This guide summarizes the main pieces that a scheme plugin normally needs. For a complete worked example, see the `Taurus training material `_. Design the model URI -------------------- Start by deciding how the data source maps to Taurus authorities, devices and attributes, and define the URI syntax for those models. For example, a Redis-backed scheme could use an attribute URI such as:: redis://localhost:6379/0/bl04:detector:status where the authority identifies the Redis server and database, and the path identifies the key represented by a Taurus attribute. Implement name validators ------------------------- A scheme provides validators for the model types that it supports. Validators are responsible for validating and parsing model names and for computing their canonical names. The most commonly used methods are: ``isValid(name)`` Check whether a model name is valid for the scheme. ``getUriGroups(name)`` Parse a model URI and return its components. ``getNames(name)`` Return the full, normal and simple forms of a model name. Existing schemes can be inspected from Taurus itself. For example:: import taurus validator = taurus.Factory("tango").getAttributeNameValidator() groups = validator.getUriGroups( "tango://localhost:10000/sys/tg_test/1/double_scalar" ) print(groups) When implementing a new scheme, create tests for both accepted and rejected model names. URI parsing errors are much easier to diagnose at the validator level than later while creating models. Provide a factory ----------------- The scheme factory connects the URI scheme with its validators and model classes. It derives from the appropriate Taurus factory base class and returns the Authority, Device and Attribute implementations used by the scheme. A simple scheme may initially support only attributes, while more elaborate plugins may also provide meaningful Authority and Device models. .. _custom_scheme_diagnostics: Expose diagnostic information ----------------------------- A factory can optionally expose backend-specific runtime information in the Taurus diagnostics window by overriding :meth:`~taurus.core.taurusfactory.TaurusFactory.getDiagnosticInfo`. Return a mapping whose keys are human-readable labels and whose values can be converted to strings. For example:: def getDiagnosticInfo(self): return { "Backend version": backend.__version__, "Subscription mode": self.subscription_mode, } The base implementation returns an empty mapping. Keep this method inexpensive and read-only: it should not create models, register listeners or perform network queries. The diagnostics window calls it when it is created and isolates failures so that a problem in one optional backend does not prevent information from other factories being displayed. The schemes listed in the factory's ``schemes`` attribute are shown automatically. Implement the models -------------------- The actual Taurus models adapt the underlying data source to the Taurus model API. For a read/write attribute, the implementation will typically need to provide at least the logic for: - decoding values from the backend into Taurus-compatible values; - reading and returning a ``TaurusAttrValue``; - encoding values before writing them to the backend; - writing values; - polling or event handling, depending on the backend. Numeric Taurus values use Pint quantities, so custom schemes should take units into account when mapping numeric backend values to Taurus values. Register the scheme plugin -------------------------- Installed scheme plugins are discovered through the ``taurus.core.schemes`` entry-point group. For a package named ``taurus_my_scheme``, a ``pyproject.toml`` entry may look like:: [project.entry-points."taurus.core.schemes"] taurus_my_scheme = "taurus_my_scheme" The module exposed by the entry point must make the factory and model classes needed by Taurus importable. Test the installed scheme ------------------------- Once the plugin is installed, Taurus can create models from the new URI in the same way as for built-in schemes:: import taurus attr = taurus.Attribute("myscheme://server/path/to/value") value = attr.read() print(value.rvalue) The same URI can then be passed to Taurus widgets and applications without those clients needing backend-specific code. See also -------- - :doc:`Models and schemes <../explanation/models>` - :doc:`Plugins <../reference/plugins>` - `Taurus training: Custom Schemes `_