mutaprops package

Submodules

mutaprops.decorators module

mutaprops.decorators.mutaprop_action(display_name, **kwargs)[source]

Make decorated method accessible in the UI.

Parameters:
  • display_name – A name to be displayed at the UI level.
  • read_only – bool, dynamic Sets GUI element to read-only state. Automatically set to true when setter is not defined.
  • priority – int Display priority, higher numbers are displayed first
  • hierarchy – string Hierarchy path in the GUI. MutaProps with the same hierarchy patch are grouped together.
  • deford – int Modifies definition order. This is normally defined automatically based on the decorator calls. If priority is not used, the order at which MutaProps are listed in GUI is defined by deford.
mutaprops.decorators.mutaprop_class(display_name, gui_id=None, gui_major_version=0, gui_minor_version=0)[source]

Class-level decorator. It is required for classes whose instances should be visible for the Mutaprop UI manager.

Parameters:
  • display_name – Class name/description to be accessible by the UI API. In most cases, it’s not really important.
  • gui_id – API-level identifier of a class definition. In most cases, it’s not really important.
  • gui_major_version – Reserved for future use.
  • gui_minor_version – Reserved for future use.
mutaprops.decorators.mutaproperty(display_name, value_type, **kwargs)[source]

Create a UI property out of existing attribute.

Parameters:
  • display_name – A name to be displayed at the UI level.
  • value_type – [MutaTypes]

Optional arguments - general

Parameters:
  • read_only – bool, dynamic Sets GUI element to read-only state. Automatically set to true when setter is not defined.
  • select

    list or dict, dynamic Set of allowed values. GUI will offer just this set.

    If it’s list, the list items must conform to the value_type:

    @mutaproperty("Cheese", MutaTypes.STRING,
                  select=['Stilton', 'Gruyere', 'Liptauer'])
    def cheese(self):
        return self._cheese
    

    If it’s dict, the keys will be displayed as a selector view, and the values will be set:

    @mutaproperty("Cheese", MutaTypes.INT,
                  select={'Stilton': 1, 'Gruyere': 2,
                          'Liptauer': 3})
    def cheese(self):
        return self._cheese
    
  • priority – int Display priority, higher numbers are displayed first
  • hierarchy – string Hierarchy path in the GUI. MutaProps with the same hierarchy patch are grouped together.
  • deford – int Modifies definition order. This is normally defined automatically based on the decorator calls. If priority is not used, the order at which MutaProps are listed in GUI is defined by deford.

Optional arguments - numerical type (MutaTypes.INT, MutaTypes.REAL)

Parameters:
  • min_val – int, dynamic Minimum possible value,
  • max_val – int, dynamic Maximum possible value,
  • step – int, dynamic For numerical type, step interval between values, for other types ignored

Optional arguments - MutaTypes.STRING

Parameters:
  • min_val – int, dynamic Minimal length of string
  • max_val – int, dynamic Maximal length of string

Optional arguments - MutaTypes.BOOL

Parameters:toggle

Dict of format:

{'on': 'Some-on-label',
 'off': 'Some-off-label'}

If set, a toggle-switch like control will be used as GUI instead of a simple checkbox.

Dynamic arguments

Where dynamic argument is supported, the value doesn’t have to be only a class definition constant, but also another MutaProp or MutaSource.

Dynamic arguments can be referred only directly and cannot be in any sort of expression, as this expression is evaluated only once during the class definition time:

@mutaproperty("Some useful flag", MutaTypes.BOOL)
def some_flag(self):
    return self._some_flag

@some_flag.setter
def some_flag(self, value):
    self._some_flag = value

@mutaproperty("Ham", MutaTypes.STRING,
              read_only=some_flag)  # direct referral, will work
def ham(self):
    return self._spam

@mutaproperty("Spam", MutaTypes.STRING,
              read_only=not some_flag)  #expression, will not work
def spam(self):
    return self._spam
mutaprops.decorators.mutasource(func=None, class_scope=False)[source]
Decorated attribute’s changes will be notified to the UI layer, but

will not be displayed.

MutaSource allows to implement some additional controller (as in MVC) logic in addition to the usual mutaproperties. Usually used to enable or disable (read_only) some parts of UI depending on other parameters, or change the select values.

Parameters:class_scope – [True, False] Set to reflect class-level attribute.

mutaprops.managers module

class mutaprops.managers.HttpManagerProxy(address)[source]

Bases: object

Utility class representing a remote (slave) HTTP manager.

address
attach(host_manager)[source]

Attaches itself to the host manager, by making it’s own remote MutaObjects part of the host managers object list. Also manages WebSocket connection to the remote manager and relays the messagest to the host manager.

Parameters:host_manager – A host HttpMutaManager object.
Returns:
detach()[source]
is_attached
is_being_removed

Host manager checks the flag to know if it shall try to reconnect with the remote manager.

session
ws_manager()[source]

Coroutine implementing the Websocket communication task.

class mutaprops.managers.HttpMutaManager(name, loop=None, master=None, local_dir=None, help_doc=None, proxy_log=None, log_level=0)[source]

Bases: object

Manages HTML5 gateway for controlling the MutaObjects. Each MutaObject is made accessible as REST API with websocket (SockJS) downstream channel for notifications about model update.

Managers can be chained by specifying a “master manager” upon initialization. Master manager can see and manipulate the slave manager’s MutaObjects. One Manager can have only one master, but can be master of many slaves. Chains can be of any length, but in practice the feasibility of long chains will be limited by the HTTP response times etc.

EVENT_SOURCE_MASTER = 'master'
EVENT_SOURCE_OBJECT = 'object'
EVENT_SOURCE_USER = 'user'
HEADER_SUPERVISOR = 'muta-supervisor'
INDEX_FILE = b'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <title>web_ui</title>\n <!-- CSS -->\n <link rel="stylesheet" href="dist/bootstrap.min.css">\n <link rel="stylesheet" href="dist/bootstrap-toggle.min.css">\n <link rel="stylesheet" href="dist/base.css">\n <link rel="stylesheet" href="local/custom.css">\n </head>\n <body>\n <div id="app"></div>\n <script src="dist/build.js"></script>\n <script src="dist/jquery-3.1.1.min.js"></script>\n <script src="dist/bootstrap.min.js"></script>\n <script src="dist/bootstrap-toggle.min.js"></script>\n </body>\n</html>\n'
NOTIFICATION_EXTERNAL_CHANGE = 'external_change'
NOTIFICATION_LOG_MESSAGE = 'log'
NOTIFICATION_OBJECTS_CHANGE = 'objects_change'
NOTIFICATION_PROPERTY_CHANGE = 'property_change'
NOTIFICATION_TERMINATION = 'terminated'
WEB_ASSETS = '/home/docs/checkouts/readthedocs.org/user_builds/mutaprops/checkouts/latest/mutaprops/web_ui/dist/'
class WsHandler(msg_callback, level=0)[source]

Bases: logging.Handler

Handler to forward logging messages over websocket.

emit(record)[source]

Do whatever it takes to actually log the specified logging record.

This version is intended to be implemented by subclasses and so raises a NotImplementedError.

add_object(muta_object, obj_id=None)[source]

Add decorated object to the UI manager.

Parameters:muta_object – An instance of a class decorated with mutaprop_class().

Optional:

Parameters:obj_id – ‘Id to be used for the added muta_object.
register_on_master(master_addr)[source]
remove_object(muta_object)[source]
Remove object from the UI manager. (Causes object to disappear from
the UI).
Parameters:muta_object – Object to be removed.
run(**aiohttp_kwargs)[source]

Run the manager.

Parameters:aiohttp_kwargs – HTTP server parameters as defined for aiohttp web.run_app
run_in_thread(**aiohttp_kwargs)[source]

Run the UI manager in a separate thread.

Theoretically this allows to run the UI for code which is otherwise incompatible with Asyncio. In practice, this is a minefield and it was never properly tested.

Parameters:aiohttp_kwargs

HTTP server parameters as defined for aiohttp web.run_app

shutdown()[source]
class mutaprops.managers.HttpMutaObjectProxy(manager_proxy, obj_id)[source]

Bases: object

Utility class proxying remote MutaObjects through REST calls.

get_object()[source]
get_prop(prop_id)[source]
get_prop_value(prop_id)[source]
get_props()[source]
is_muta_ready()[source]
muta_id
muta_init(object_id, change_callback=None)[source]
muta_unregister()[source]
set_prop_action(prop_id)[source]
set_prop_value(prop_id, value)[source]
exception mutaprops.managers.MutaManagerError[source]

Bases: mutaprops.utils.MutaPropError

mutaprops.mutaprops module

class mutaprops.mutaprops.MutaAction(pid, display_name, callback, **kwargs)[source]

Bases: mutaprops.mutaprops.MutaProp

MP_CLASS_TYPE = 'action'
MP_READ_ONLY = 'read_only'
muta_call(obj)[source]
class mutaprops.mutaprops.MutaProp(pid, display_name, **kwargs)[source]

Bases: object

Abstract class defining a generic MutaProp object. Such object holds basic information about a “property” of a MutaProp-accessible class (such as ID and human-readable name) as well as position of such property in the hierarchy of all properties.

Each MutaProp implementation is expected to overload following:
  • _allowed_kwargs() class method,
    defining kwargs which are used/allowed in the constructor.
  • _exported_kwargs() class method, i
    defining which parameters are exported during serialization of the MutaProp.
  • MP_CLASS_TYPE constant defining
    the MutaProp class for GUI use (the utilization of this parameter is GUI-implementation-dependent).
MP_CLASS_TYPE = 'abstract'
MP_DEFINITION_ORDER = 'deford'
MP_DOC = 'doc'
MP_HIERARCHY = 'hierarchy'
MP_ID = 'id'
MP_NAME = 'name'
MP_PRIORITY = 'priority'
MP_TYPE = 'type'
MP_VIEW = 'view'
definition_order
display_name
display_priority
hierarchy
prop_id
to_dict(obj=None)[source]
view
class mutaprops.mutaprops.MutaPropClass[source]

Bases: object

MP_CLASS_ID = 'class_id'
MP_DOC = 'doc'
MP_GUI_ID = 'gui_id'
MP_GUI_MAJOR_VERSION = 'gui_major_version'
MP_GUI_MINOR_VERSION = 'gui_minor_version'
MP_NAME = 'name'
MP_OBJ_ID = 'obj_id'
MP_PROPS = 'props'
classmethod get_class_name()[source]
classmethod get_gui_id()[source]
classmethod get_gui_version()[source]
is_muta_ready()[source]
classmethod muta_attr(attr)[source]
muta_id
muta_init(object_id, change_callback=None)[source]
muta_unregister()[source]
props
to_dict()[source]
update_props(change_callback=None)[source]

Because this is potentially heavy operation and property definitions are not likely to be changed during objects lifetime, it’s easier to cache it.

class mutaprops.mutaprops.MutaProperty(pid, display_name, value_type, **kwargs)[source]

Bases: mutaprops.mutaprops.MutaProp

Emulate PyProperty_Type() in Objects/descrobject.c

MP_CHANGE_CALLBACK = 'change_callback'
MP_CLASS_TYPE = 'property'
MP_FDEL = 'fdel'
MP_FGET = 'fget'
MP_FSET = 'fset'
MP_MAXVAL = 'max_val'
MP_MINVAL = 'min_val'
MP_READ_ONLY = 'read_only'
MP_SELECT = 'select'
MP_STEP = 'step'
MP_TOGGLE = 'toggle'
MP_VALUE = 'value'
MP_VALUE_TYPE = 'value_type'
deleter(fdel)[source]
getter(fget)[source]

Decorator function for constructing MutaProperty on getter function. Takes all kwargs from __init__()

is_writeable()[source]

Returns true if only getter is defined.

Warning: doesn’t reflect the read_only kwarg!

muta_set(obj, value)[source]
register_change_callback(callback)[source]
setter(func=None, min_val=None, max_val=None, step=None, select={})[source]
Decorator function usable in two ways:
  • decorator without arguments:

    @some_metaprop.setter
    def some_metaprop(self, value):
        pass
    
  • decorator with arguments:

    @some_metaprop.setter(min_value=1.0, max_value=2.0)
    def some_metaprop(self, value):
        pass
    
Parameters:
  • func – Is only for internal decorator use, don’t use it
  • min_val – Min. value for numeric types, min. lenght for Strings
  • max_val – Max. value for numeric types, max. length for Strings
  • step – Step increment for numeric types
  • select – Selector object to provide user select. A selector can be either a dict, or list of (label, value) tuples, or another MutaProperty or MutaSource which provides dict or list of tuples. In such case, the selector list will be updated during runtime.
Returns:

MutaProp object

to_dict(obj=None)[source]
value_type
class mutaprops.mutaprops.MutaSource(pid, display_name, value_type, **kwargs)[source]

Bases: mutaprops.mutaprops.MutaProperty

MutaSource is generalized MutaProperty, which is not visible in the GUI, however it’s changes are reflected in the GUI. MutaSource does not need to define display name and value type - any serializable type goes. MutaSource can also be a class-property. MutaSources cannot be directly changed from the GUI layer, however they can be changed indirectly from the model/MutaObject itself.

Implementation Note

In theory MutaProperty should be child of MutaSource, in practice the differences are of such character it doesn’t make it more convenient to implement MutaSource as child of MutaProperty.

MP_CLASS_SCOPE = 'class_scope'
MP_CLASS_TYPE = 'source'
MP_OWNER_CLASS = 'owner_class'
class_scoped
Returns:True if the MutaSource is classproperty.
muta_set(obj, value)[source]
owner_class

In case of classproperty source, returns the owner class.

classmethod serialize(value)[source]
set_owner_class(defining_class)[source]
setter(func)[source]

Get setter method. :param func: :return: MutaSource object.

setter_classproperty(func)[source]
to_dict(obj=None)[source]
class mutaprops.mutaprops.MutaTypes[source]

Bases: enum.Enum

Representation of allowed MutaProperty types.

BOOL = 3
HTML = 4
INT = 1
REAL = 2
STRING = 0

mutaprops.utils module

class mutaprops.utils.BiDict(*args, **kwargs)[source]

Bases: collections.OrderedDict

Bidirectional dictionary for handling both getters and setters of MutaProperties with selects. Copied from http://stackoverflow.com/a/21894086 and adopted for Python3.

get_map_list()[source]
exception mutaprops.utils.MutaPropError[source]

Bases: Exception

mutaprops.utils.rest_to_html(docstring)[source]

Converts reSTructured text from docstrings to HTML.

As it uses quite strange docutils implementations, it adds some unnecessary clutter to the HTML <div class=”document”> etc.

Module contents