From 05536af88f2de5d2113b54f4743ce00ca2002af2 Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 26 Mar 2025 14:15:53 +0100 Subject: [PATCH 1/5] Reformat docs --- docs/index.rst | 21 +++++++++------------ docs/paradigms.rst | 28 +++++++++++++--------------- docs/usage.rst | 30 +++++++++++++++--------------- 3 files changed, 37 insertions(+), 42 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index e5fe232..8bc1430 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,18 +7,15 @@ HEROS - Highly Efficient Remote Object Service =============================================== HEROS is a decentralized object sharing service. In simple words it makes your software objects network transparent. -To be fast and efficient, HEROS relies on eclipse-zenoh as a transport layer. It thus supports different network -topologies and hardware transports. Most notably, it can run completely decentralized, avoiding a single point -of failure and at the same time guaranteeing low latency and and high bandwidth communication through p2p connections. - -HEROS provides a logical representation of software objects and is not tied to any specific language. Even non-object -oriented programming languages might provide a collection of functions, variables, and events to be accessible as an -object in HEROS. - -Very much like a Dynamic Invocation Infrastructure (DII) in a Common Object Broker Architecture (CORBA), HEROS handles -objects dynamically during runtime rather than during compile time. While this does not allow to map HEROS objects to -be mapped to the language objects in compiled languages, languages supporting monkey-patching (python, js, ...) are -still able to create proxy objects during runtime. +To be fast and efficient, HEROS relies on eclipse-zenoh as a transport layer. +It thus supports different network topologies and hardware transports. +Most notably, it can run completely decentralized, avoiding a single point of failure and at the same time guaranteeing low latency and and high bandwidth communication through p2p connections. + +HEROS provides a logical representation of software objects and is not tied to any specific language. +Even non-object oriented programming languages might provide a collection of functions, variables, and events to be accessible as an object in HEROS. + +Very much like a Dynamic Invocation Infrastructure (DII) in a Common Object Broker Architecture (CORBA), HEROS handles objects dynamically during runtime rather than during compile time. +While this does not allow to map HEROS objects to be mapped to the language objects in compiled languages, languages supporting monkey-patching (python, js, ...) are still able to create proxy objects during runtime. The working principle is shown in the following. diff --git a/docs/paradigms.rst b/docs/paradigms.rst index ad50852..8427859 100644 --- a/docs/paradigms.rst +++ b/docs/paradigms.rst @@ -4,21 +4,20 @@ Paradigms Realms ------ -To isolate groups of HERO objects from other groups the concept of realms exists in HEROS. You can think of it as a -namespace where objects in the same namespace can talk to each other while communication across realms/namespaces is -not easily possible. Note that this is solely a management feature, not a security feature. All realms share the same -zenoh network and can thus talk to each other on this level. +To isolate groups of HERO objects from other groups the concept of realms exists in HEROS. +You can think of it as a namespace where objects in the same namespace can talk to each other while communication across realms/namespaces is +not easily possible. +Note that this is solely a management feature, not a security feature. +All realms share the same zenoh network and can thus talk to each other on this level. Objects ------- -An object that should be shared via HEROS must inherit from the class `LocalHero`. When python instantiates such -an object, it will parse the methods, class attributes, and events (see event decorator) and automatically generate -a list of capabilities that describes this HEROS object. The capabilities are announced and a liveliness token for the -object is created. HEROSOberserver in the network will thus be notified that our new object joined the realm. +An object that should be shared via HEROS must inherit from the class ``LocalHero``. +When python instantiates such an object, it will parse the methods, class attributes, and :doc:`events ` (see event decorator) and automatically generate a list of capabilities that describes this HEROS object. +The capabilities are announced and a liveliness token for the object is created. ``HEROSOberserver`` in the network will thus be notified that our new object joined the realm. -When the object is destroyed or the link gets lost, the liveliness token disappears and any remote object will notice -this. +When the object is destroyed or the link gets lost, the liveliness token disappears and any remote object will notice this. Capabilities ------------ @@ -33,12 +32,11 @@ A HEROS object is characterized by the capabilities it provides. There are curre Datasource ---------- -A frequent use case for HERO is that of making data (like sensor data or status data) available to interested peers. To cover this use -case, a special class of HERO exists, the DatasourceHERO. It provides a special event `new_data` that is always emitted when new data -is available. RemoteHEROs connect to the emitting HERO will get noticed directly and react accordingly. In addition also a DatasourceObsever class -exist, that efficiently monitors the events of many HEROs in the network without fully instanciating the RemoteHEROs. +A frequent use case for HERO is that of making data (like sensor data or status data) available to interested peers. +To cover this use case, a special class of HERO exists, the ``DatasourceHERO``. It provides a special event ``new_data`` that is always emitted when new data is available. RemoteHEROs connect to the emitting HERO will get noticed directly and react accordingly. +In addition also a ``DatasourceObsever`` class exist, that efficiently monitors the events of many HEROs in the network without fully instantiating the RemoteHEROs. Class Tree ---------- -This is not yet implemented. I will be a method to \ No newline at end of file +This is not yet implemented. diff --git a/docs/usage.rst b/docs/usage.rst index 2e36501..43a7d7e 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -1,19 +1,17 @@ Usage ##### -Building your first HERO is very simple. Just write your custom class and make it inherit from :code:`heros.LocalHero` +Building your first HERO is very simple. Just write your custom class and make it inherit from ``heros.LocalHero``. A simple example can be seen .. literalinclude:: ../examples/share_local_hero_simple.py :language: python -Due to the infinite loop, the script will not terminate and keep the object `obj` alive. Since it inherits from `heros.LocalHERO`, -the object was analyzed upon instantiation and provided as a HERO to the network. This means, we can now simply access the method -attributes of the object from a remote site. +Due to the infinite loop, the script will not terminate and keep the object ``obj`` alive. Since it inherits from ``heros.LocalHERO``, the object was analyzed upon instantiation and provided as a HERO to the network. +This means, we can now simply access the method attributes of the object from a remote site. -To get remote access we can run the following in a different process or on a different machine in the same network (UDP broadcast -needs to reach the other machine for discovery): +To get remote access we can run the following in a different process or on a different machine in the same network (UDP broadcast needs to reach the other machine for discovery): .. literalinclude:: ../examples/access_remote_hero_simple.py :language: python @@ -21,8 +19,10 @@ needs to reach the other machine for discovery): Nested HEROs ------------ -HEROS is able to serialize HEROs as references to a HERO. This allows to pass a HERO from between the local and the remote site. -When either of the sites receives such a reference, it creates a RemoteHERO to access the referenced HERO. This allows things like +HEROS is able to serialize HEROs as references to a HERO. +This allows to pass a HERO from between the local and the remote site. +When either of the sites receives such a reference, it creates a ``RemoteHERO`` to access the referenced HERO. +This allows things like 1. Deep access to HEROs nested inside of HEROs. 2. Passing HEROs as arguments into methods exposed by a HERO. @@ -32,12 +32,12 @@ When either of the sites receives such a reference, it creates a RemoteHERO to a Unserializable Objects ---------------------- -A HERO attribute or method might return an object that is not a HERO and can not be serialized. In that case, the returned object is -cached on the side of the LocalHERO and an identifier is sent to the remote side. The remote side can store the reference locally. -If the reference is sent back to the LocalHERO side, the corresponding object is taken from the cache and inserted into the request -instead of the reference. This allows to instruct the LocalHERO to do something with an object that cannot be transferred. This -allows, for example, to hand over an unserializable object retrieved earlier as argument to a function. +A HERO attribute or method might return an object that is not a HERO and can not be serialized. +In that case, the returned object is cached on the side of the ``LocalHERO`` and an identifier is sent to the remote side. The remote side can store the reference locally. +If the reference is sent back to the ``LocalHERO`` side, the corresponding object is taken from the cache and inserted into the request instead of the reference. +This allows to instruct the LocalHERO to do something with an object that cannot be transferred. +This allows, for example, to hand over an unserializable object retrieved earlier as argument to a function. .. note:: - The cache that keeps the object references uses only weak references to to avoid memory leaks. That means that an object can be garbage - collected if not any other instance keeps a reference on it. \ No newline at end of file + The cache that keeps the object references uses only weak references to to avoid memory leaks. + That means that an object can be garbage collected if not any other instance keeps a reference on it. -- GitLab From 18c5059deeffa595c603b15d66bdd18640b9062c Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 26 Mar 2025 14:41:09 +0100 Subject: [PATCH 2/5] Change apiref to autoapi --- docs/apiref.rst | 25 ------------------------- docs/conf.py | 21 ++++++++++++++++++--- docs/index.rst | 1 - pyproject.toml | 8 ++++++++ 4 files changed, 26 insertions(+), 29 deletions(-) delete mode 100644 docs/apiref.rst diff --git a/docs/apiref.rst b/docs/apiref.rst deleted file mode 100644 index 0d0ae25..0000000 --- a/docs/apiref.rst +++ /dev/null @@ -1,25 +0,0 @@ -API Reference -############# - -This is reference for the API of HEROS. - -.. autoclass:: heros.HEROPeer - -.. autoclass:: heros.HERO - -.. autoclass:: heros.LocalHERO - - -.. autoclass:: heros.RemoteHERO - - -.. autoclass:: heros.HEROObserver - - -.. autoclass:: heros.LocalDatasourceHERO - - -.. autoclass:: heros.PolledLocalDatasourceHERO - - -.. autoclass:: heros.DatasourceObserver \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 82e9f35..0457eb5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,10 +13,15 @@ author = 'Thomas Niederprüm' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +# -- General configuration --------------------------------------------------- extensions = [ - "sphinx.ext.autodoc", - "sphinx.ext.autosummary", - "sphinx.ext.napoleon", + # 'sphinx.ext.autodoc', # Include docstrings in the documentation + 'autoapi.extension', + 'sphinx.ext.autosummary', + 'sphinx.ext.napoleon', # Support for Google and NumPy style docstrings + 'sphinx.ext.viewcode', # Add links to source code + 'sphinx.ext.todo', # Enable todo lists + 'sphinx_autodoc_typehints', # Handle type hints in documentation ] templates_path = ['_templates'] @@ -34,3 +39,13 @@ html_theme_options = { "dark_logo": "heros_logo.svg", "sidebar_hide_name": False, } + +# Autodoc settings +autoclass_content = "both" +# -- AutoAPI configuration --------------------------------------------------- +autoapi_type = 'python' +autoapi_dirs = ['../src'] # Path to your source code +autoapi_add_toctree_entry = True # Avoid duplicate toctree entries +autoapi_keep_files = False # Keep intermediate reStructuredText files +# todo conf +todo_include_todos = True diff --git a/docs/index.rst b/docs/index.rst index 8bc1430..622fae0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -31,5 +31,4 @@ The working principle is shown in the following. paradigms installation usage - apiref diff --git a/pyproject.toml b/pyproject.toml index 8311aa8..e9db6ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,14 @@ classifiers = [ "Programming Language :: Python :: 3 :: Only" ] +[project.optional-dependencies] +dev = [ + "sphinx>=8", + "sphinx-autoapi>=3", + "sphinx-autodoc-typehints>=3", + "furo>=2024", +] + [project.urls] Homepage = "https://gitlab.com/atomiq-project/heros" Repository = "https://gitlab.com/atomiq-project/heros" -- GitLab From a71b509b067c58f2bdb6ad5536f19828cbfcec7f Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 26 Mar 2025 15:05:14 +0100 Subject: [PATCH 3/5] Cleanup docstrings --- src/heros/capabilities.py | 17 ++++++------- src/heros/datasource/datasource.py | 25 ++++++++++--------- src/heros/datasource/observables.py | 10 ++++---- src/heros/datasource/types.py | 11 +++++---- src/heros/helper.py | 3 ++- src/heros/heros.py | 37 +++++++++++++++-------------- src/heros/serdes.py | 10 ++++---- src/heros/zenoh.py | 4 ++-- 8 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/heros/capabilities.py b/src/heros/capabilities.py index 679a386..ca95044 100644 --- a/src/heros/capabilities.py +++ b/src/heros/capabilities.py @@ -88,8 +88,8 @@ class Capability: @dataclass class AttributeCapability(Capability): """ - An attribute capability describes a single variable of the remote object that is exposed - under the name of the capability. + An attribute capability describes a single variable of the remote object. + It is exposed under the name of the capability. Args: name: name of the capability @@ -100,13 +100,13 @@ class AttributeCapability(Capability): type: str access: str = "rw" - def to_dict(self): + def to_dict(self) -> dict: d = Capability.to_dict(self) d.update({"type": self.type, "access": self.access}) return d @staticmethod - def from_dict(d: dict): + def from_dict(d: dict) -> "AttributeCapability": if "name" not in d: raise AttributeError("required field 'type' not in dict") return AttributeCapability(name=d["name"], type=d["type"], access=d["access"]) @@ -116,14 +116,11 @@ class AttributeCapability(Capability): class EventCapability(Capability): """ An event capability describes the ability of a remote object to notify upon a certain event. - - Args: - """ flavor: ClassVar[str] = "event" @staticmethod - def from_dict(d: dict): + def from_dict(d: dict) -> "EventCapability": return EventCapability(name=d["name"]) @@ -134,7 +131,7 @@ class MethodCapability(Capability): return_type: str = "None" @staticmethod - def from_method(m: Callable): + def from_method(m: Callable) -> "MethodCapability": sig = inspect.signature(m) cap = MethodCapability(name=m.__name__) @@ -161,7 +158,7 @@ class MethodCapability(Capability): return d @staticmethod - def from_dict(d: dict): + def from_dict(d: dict) -> "MethodCapability": """ Generate a method capabilities object from a defining dictionary. diff --git a/src/heros/datasource/datasource.py b/src/heros/datasource/datasource.py index e36b96b..bce8641 100644 --- a/src/heros/datasource/datasource.py +++ b/src/heros/datasource/datasource.py @@ -9,12 +9,13 @@ from .observables import ObservableProcessor class LocalDatasourceHERO(LocalHERO): """ - A datasource is a HERO that can provide information on a standardized interface. This interface is the event - `new_data`. Instances in the zenoh network interested in the data provided by data sources can simply subscribe - to the key expression `@objects/realm/*/new_data` or use the :class:RemoteDatasourceObserver(). + A datasource is a HERO that can provide information on a standardized interface. + This interface is the event `new_data`. Instances in the zenoh network interested in the data provided + by data sources can simply subscribe to the key expression `@objects/realm/*/new_data` or use + the :class:`DatasourceObserver`. To make your class a LocalDatasourceHERO make it inherit this class. - This class is ment for datasources that create asynchronous events on their own. When processing such an event + This class is meant for datasources that create asynchronous events on their own. When processing such an event call `new_data` to publish the data from this datasource. Args: @@ -36,11 +37,12 @@ class LocalDatasourceHERO(LocalHERO): class DatasourceObserver(HEROPeer): """ - A class that can observe and handle the data emitted by one or more datasource HEROs. In particular, this - class provides an efficient way to listen to the data emitted by all datasource HEROs in the realm. By - not instantiating the HEROs themselves but just subscribing to the topics for the datasource, this reduces the - pressure on the backing zenoh network. If, however, only the data of a few HEROs should be observed, it might - make more sense to just instantiate the according RemoteHEROs and connect a callback to their `new_data` signal. + A class that can observe and handle the data emitted by one or more datasource HEROs. + In particular, this class provides an efficient way to listen to the data emitted by all datasource HEROs in + the realm. By not instantiating the HEROs themselves but just subscribing to the topics for the datasource, this + reduces the pressure on the backing zenoh network. If, however, only the data of a few HEROs should be observed, + it might make more sense to just instantiate the according RemoteHEROs and connect a callback to their `new_data` + signal. Args: object_selector: selector to specify which objects to observe. This becomes part of a zenoh selector and thus @@ -87,8 +89,9 @@ class PolledLocalDatasourceHERO(LocalDatasourceHERO): To make your class a PolledLocalDatasourceHERO make it inherit this class an implement the method `_new_data`. The method will get called periodically and the return value will be published as an event. - Note: The periodic calling is realized via asyncio and will thus only work if the asyncio mainloop is - started. + Note: + The periodic calling is realized via asyncio and will thus only work if the asyncio mainloop is + started. Args: name: name/identifier under which the object is available. Make sure this name is unique in the realm. diff --git a/src/heros/datasource/observables.py b/src/heros/datasource/observables.py index 2cab505..d480022 100644 --- a/src/heros/datasource/observables.py +++ b/src/heros/datasource/observables.py @@ -4,8 +4,9 @@ from typing import Optional def lambdify(expression: str, globals_dict: dict = {}): """ - Turn a string into a lambda function with the given globals. By default it enables a set of numpy functions - in the expression. Further functions can be added by providing it in :param:`globals_dict`. + Turn a string into a lambda function with the given globals. + By default it enables a set of numpy functions in the expression. Further functions can be added by providing + it in ``globals_dict``. """ import numpy as np np_functions = ["sin", "cos", "tan", "arcsin", "arccos", "arctan", "hypot", "arctan2", "sinh", "cosh", "tanh", @@ -22,8 +23,7 @@ def lambdify(expression: str, globals_dict: dict = {}): class BoundaryChecker: """ Check whether the observed value is in it's boundaries. - Therefore provide an integer feedback with rising importance. - where boundary = 0 says that everything is fine. + Therefore provide an integer feedback with rising importance where boundary = 0 says that everything is fine. 1, 2, 3 correspond to higher warning / error or fault situations. """ @@ -80,7 +80,7 @@ class Observable: class ObservableProcessor: """ - An ObservableProcessor takes a configuration dict for multiple observables when it is instanciated. + An ObservableProcessor takes a configuration dict for multiple observables when it is instantiated. An object of this class can be called with a :class:DataSourceReturnSet as an argument. """ def __init__(self, obs_def: dict): diff --git a/src/heros/datasource/types.py b/src/heros/datasource/types.py index b689c28..fb43287 100644 --- a/src/heros/datasource/types.py +++ b/src/heros/datasource/types.py @@ -7,10 +7,11 @@ def ensure_string(x): class DatasourceReturnValue(dict): """ - A structure to store data returned from a single entity in a datasource. A datasource can return multiple - entities at once. In this case many DatasourceReturnValues are stored in a :class:DatasourceReturnSet. + A structure to store data returned from a single entity in a datasource. + A datasource can return multiple entities at once. In this case many DatasourceReturnValues are stored in + a :class:`DatasourceReturnSet`. - Default return values from datasource. They can be converted using a calibration. + Default return values from datasource. They can be converted using a calibration. :param raw_value: (float) :param raw_unit: (str[10]) :param time: (int) creation time of the rawValue. @@ -92,13 +93,13 @@ class DatasourceReturnValue(dict): class DatasourceReturnSet(tuple): """ - collection of multiple DatasourceReturnValues + Collection of multiple :class:`DatasourceReturnValue`. """ @staticmethod def from_data(data): """ - we try to build a DatasourceReturnSet by guessing the data format from the following options: + We try to build a DatasourceReturnSet by guessing the data format from the following options: * [FLOAT, FLOAT, ..] -> A list of raw_values * [(FLOAT, STR), (FLOAT, STR), ..] -> a list of (raw_value, raw_unit) tuples * {STR: FLOAT, STR: FLOAT, ..} -> a dict with id: raw_value diff --git a/src/heros/helper.py b/src/heros/helper.py index 46c1f7f..2a95bf9 100644 --- a/src/heros/helper.py +++ b/src/heros/helper.py @@ -10,7 +10,8 @@ def object_name_from_keyexpr(key_expr, ns_objects, realm, endpoint=".*"): def full_classname(o): - """ Return the fully qualified class name of an object + """ + Return the fully qualified class name of an object. Args: o: object diff --git a/src/heros/heros.py b/src/heros/heros.py index c4f208c..c85a830 100644 --- a/src/heros/heros.py +++ b/src/heros/heros.py @@ -11,10 +11,10 @@ from .helper import object_name_from_keyexpr, log class HEROPeer: """ - A HEROPeer provides the minimal interface to establish the HERO communication on top of the zenoh backend. To this - end, it provides methods to send cbor-serialized messages via the zenoh network. It establishes the `@object` - namespace and communicates in a defined realm. Methods to discover objects in the realm and to retrieve their - object information are provided. + A HEROPeer provides the minimal interface to establish the HERO communication on top of the zenoh backend. + To this end, it provides methods to send cbor-serialized messages via the zenoh network. It establishes + the `@object` namespace and communicates in a defined realm. Methods to discover objects in the realm and + to retrieve their object information are provided. Args: realm: Name of the realm that this HEROPeer belongs to. (default: heros) @@ -63,8 +63,8 @@ class HEROPeer: def _subscribe_selector(self, selector: str, callback: callable, *args, **kwargs): """ - Subscribe to a zenoh selector and a attach a callback that receives the deserialized payload of the messages - published. + Subscribe to a zenoh selector and a attach a callback. + The callback receives the deserialized payload of the messages published. Args: selector: zenoh selector for the subscription. See the zenoh documentation for valid descriptors. @@ -96,8 +96,8 @@ class HEROPeer: def _discover(self, timeout: float = 10.0) -> dict: """ - Send query to discovery endpoint of all HEROs in the current realm. All alive objects will respond and - send their remote object descriptor + Send query to discovery endpoint of all HEROs in the current realm. + All alive objects will respond and send their remote object descriptor. Args: timeout: timeout for the discover operation in seconds (default: 10) @@ -155,8 +155,8 @@ class HERO(HEROPeer): def _query_endpoint(self, endpoint: str, *args, **kwargs) -> list: """ - Send a query to an endpoint. This is a wrapper for _query_selector that enforces to talk to the endpoint - of the remote object. + Send a query to an endpoint. + This is a wrapper for _query_selector that enforces to talk to the endpoint of the remote object. Args: endpoint: endpoint within this HERO. If the given endpoint does not start with the endpoint base path, @@ -171,8 +171,8 @@ class HERO(HEROPeer): def _subscribe_endpoint(self, endpoint: str, callback: callable, *args, **kwargs): """ - Subscribe to an endpoint of this HERO. This is a wrapper for _subscribe_selector that enforces to talk to the - endpoint of the remote object. + Subscribe to an endpoint of this HERO. + This is a wrapper for _subscribe_selector that enforces to talk to the endpoint of the remote object. Args: endpoint: endpoint within this HERO. If the given endpoint does not start with the endpoint base path, @@ -188,8 +188,8 @@ class HERO(HEROPeer): class RemoteHERO(HERO): """ - Creates a local stub object from a remote HERO such that it seems like the remote object is a local - object. The remote HERO is identified by its name and has to be available at the given realm. + Creates a local stub object from a remote HERO such that it seems like the remote object is a local object. + The remote HERO is identified by its name and has to be available at the given realm. Attribute and method capabilities of the remote object are directly mapped to attributes and methods of the stub object, respectively. The signature of the methods is adapted accordingly. The remote attributes do not @@ -200,7 +200,8 @@ class RemoteHERO(HERO): To be able to attach attributes to this class, every instance of a `RemoteHERO` is created from a dynamically generated child class of `RemoteHERO` with the name `RemoteHERO__`. - Note: To discover which objects are available in a certain realm, see :class:HEROObserver. + Note: + To discover which objects are available in a certain realm, see :class:HEROObserver. Args: name: name/identifier of the remote object @@ -279,8 +280,8 @@ class RemoteHERO(HERO): class LocalHERO(HERO): """ - Base class for objects exposed through HEROS. Any object that should be able to be accessed remotely must be based - off this class. + Base class for objects exposed through HEROS. + Any object that should be able to be accessed remotely must be based off this class. Args: name: name/identifier under which the object is available. Make sure this name is unique in the realm. @@ -379,7 +380,7 @@ class LocalHERO(HERO): class HEROObserver(HEROPeer): """ A HEROObserver keeps track of the HEROs in a given realm by monitoring its zenoh liveliness tokens. - The member attribute `known_objects` always holds a list of all HEROs known to the observer. + The member attribute ``known_objects`` always holds a list of all HEROs known to the observer. Args: realm: Name of the realm that this HEROPeer belongs to. (default: heros) diff --git a/src/heros/serdes.py b/src/heros/serdes.py index 906aad7..cdb2af6 100644 --- a/src/heros/serdes.py +++ b/src/heros/serdes.py @@ -16,8 +16,7 @@ def is_builtin_class_instance(obj): class ObjectStore: """ - An object store that can be used to keep week references to objects identified by a serializable - identifier (int64) + An object store to be used to keep week references to objects identified by a serializable identifier (int64). """ _cache = {} @@ -37,8 +36,8 @@ class ObjectStore: def get(self, identifier: int) -> object: """ - Retrieve an object identified by :param:identifier from the store. If the object does not - exist any more, None is returned. + Retrieve an object identified by :param:identifier from the store. + If the object does not exist any more, None is returned. Args: identifier: the identifier obtained when storing the object @@ -75,7 +74,8 @@ class UnserializableRemoteObject: def cbor_default_encoder(encoder, value): - """Handle custom types in serialization + """ + Handle custom types in serialization. """ from heros import LocalHERO, RemoteHERO global obj_store diff --git a/src/heros/zenoh.py b/src/heros/zenoh.py index 7d0e90b..2e8934a 100644 --- a/src/heros/zenoh.py +++ b/src/heros/zenoh.py @@ -11,7 +11,7 @@ class ZenohSessionManager: def request_session(self, obj: object) -> zenoh.Session: """ - Request the global zenoh session + Request the global zenoh session. Args: obj: The object that requests the session @@ -31,7 +31,7 @@ class ZenohSessionManager: def release_session(self, obj: object): """ - Release from the global zenoh session + Release from the global zenoh session. Args: obj: The object that wants to release from the global zenoh session -- GitLab From 75019c1cdc0a148d44fc2fade36d706609ab00dc Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 26 Mar 2025 15:11:39 +0100 Subject: [PATCH 4/5] Fix optional deps in pyproject.toml --- pyproject.toml | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e9db6ac..49b6e46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,14 +39,6 @@ classifiers = [ "Programming Language :: Python :: 3 :: Only" ] -[project.optional-dependencies] -dev = [ - "sphinx>=8", - "sphinx-autoapi>=3", - "sphinx-autodoc-typehints>=3", - "furo>=2024", -] - [project.urls] Homepage = "https://gitlab.com/atomiq-project/heros" Repository = "https://gitlab.com/atomiq-project/heros" @@ -56,5 +48,9 @@ Documentation = "https://gitlab.com/atomiq-project/heros/wiki" [project.optional-dependencies] dev = [ "pytest>=7.1", - "flake8>=6.0" + "flake8>=6.0", + "sphinx>=8", + "sphinx-autoapi>=3", + "sphinx-autodoc-typehints>=3", + "furo>=2024", ] -- GitLab From 333813f8f3b9bb3b27afde1b45b3525505b8056a Mon Sep 17 00:00:00 2001 From: Suthep Pomjaksilp Date: Wed, 26 Mar 2025 15:13:57 +0100 Subject: [PATCH 5/5] Fix principle drawing for dark mode enjoyers --- docs/_static/principle.svg | 347 +++++++++++++++++++------------------ 1 file changed, 177 insertions(+), 170 deletions(-) diff --git a/docs/_static/principle.svg b/docs/_static/principle.svg index c6df394..06184c6 100644 --- a/docs/_static/principle.svg +++ b/docs/_static/principle.svg @@ -2,9 +2,9 @@ LocalHEROLocalHERORemoteHERORemoteHEROcapabilitiescapabilitiesdiscoverdiscoverobjectobjectproxyobjectproxyobjectsignallingsignallingRPCRPCinspectinspectconstruct + y="-2.8168223" + id="text12-6" + transform="rotate(45)">construct -- GitLab