forked from platypush/platypush
[#341] Backend implementation of the new procedure
entities architecture.
This commit is contained in:
parent
1ee8055597
commit
99909c73ab
8 changed files with 138 additions and 10 deletions
|
@ -272,6 +272,7 @@ class Config:
|
|||
@property
|
||||
def _core_plugins(self) -> Dict[str, dict]:
|
||||
return {
|
||||
'procedures': {},
|
||||
'variable': {},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
class ProceduresManager:
|
||||
"""
|
||||
This class is responsible for managing the procedures as native entities.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.procedures = {}
|
29
platypush/entities/managers/procedures.py
Normal file
29
platypush/entities/managers/procedures.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from typing import Callable, Dict, Union
|
||||
|
||||
from platypush.config import Config
|
||||
from . import EntityManager
|
||||
|
||||
|
||||
class ProcedureEntityManager(EntityManager, ABC):
|
||||
"""
|
||||
Base class for integrations that can run and manage procedures.
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def exec(self, procedure: str, *args, **kwargs):
|
||||
"""
|
||||
Run a procedure.
|
||||
|
||||
:param procedure: Procedure to run, by name.
|
||||
:param args: Arguments to pass to the procedure.
|
||||
:param kwargs: Keyword arguments to pass to the procedure.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
@property
|
||||
def _all_procedures(self) -> Dict[str, Union[dict, Callable]]:
|
||||
"""
|
||||
:return: All the procedures that can be run by this entity manager.
|
||||
"""
|
||||
return Config.get_procedures()
|
|
@ -28,9 +28,13 @@ if not is_defined('procedure'):
|
|||
id = Column(
|
||||
Integer, ForeignKey('entity.id', ondelete='CASCADE'), primary_key=True
|
||||
)
|
||||
name = Column(String, unique=True, nullable=False)
|
||||
args = Column(JSON, nullable=False, default=[])
|
||||
type = Column(Enum('python', 'config', name='procedure_type'), nullable=False)
|
||||
procedure_type = Column(
|
||||
Enum('python', 'config', name='procedure_type'), nullable=False
|
||||
)
|
||||
module = Column(String)
|
||||
source = Column(String)
|
||||
line = Column(Integer)
|
||||
|
||||
__table_args__ = {'keep_existing': True}
|
||||
__mapper_args__ = {
|
||||
|
|
|
@ -12,6 +12,7 @@ from platypush.common.db import override_definitions
|
|||
from platypush.common.reflection import Integration, Message as MessageMetadata
|
||||
from platypush.config import Config
|
||||
from platypush.plugins import Plugin, action
|
||||
from platypush.plugins.procedure import ProcedureEncoder
|
||||
from platypush.message import Message
|
||||
from platypush.message.event import Event
|
||||
from platypush.message.response import Response
|
||||
|
@ -20,7 +21,6 @@ from platypush.utils.mock import auto_mocks
|
|||
from platypush.utils.manifest import Manifest, Manifests, PackageManagers
|
||||
|
||||
from ._cache import Cache
|
||||
from ._serialize import ProcedureEncoder
|
||||
|
||||
|
||||
class InspectPlugin(Plugin):
|
||||
|
|
94
platypush/plugins/procedures/__init__.py
Normal file
94
platypush/plugins/procedures/__init__.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
import json
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable, Collection, Optional, Union
|
||||
|
||||
from platypush.entities.managers.procedures import ProcedureEntityManager
|
||||
from platypush.entities.procedures import Procedure
|
||||
from platypush.plugins import RunnablePlugin, action
|
||||
from platypush.utils import run
|
||||
|
||||
from ._serialize import ProcedureEncoder
|
||||
|
||||
|
||||
@dataclass
|
||||
class _ProcedureWrapper:
|
||||
name: str
|
||||
obj: Union[dict, Callable]
|
||||
|
||||
|
||||
class ProceduresPlugin(RunnablePlugin, ProcedureEntityManager):
|
||||
"""
|
||||
Utility plugin to run and store procedures as native entities.
|
||||
"""
|
||||
|
||||
@action
|
||||
def exec(self, procedure: str, *args, **kwargs):
|
||||
return run(f'procedure.{procedure}', *args, **kwargs)
|
||||
|
||||
def _convert_procedure(self, name: str, proc: Union[dict, Callable]) -> Procedure:
|
||||
metadata = self._serialize_procedure(proc, name=name)
|
||||
return Procedure(
|
||||
id=name,
|
||||
name=name,
|
||||
plugin=self,
|
||||
procedure_type=metadata['type'],
|
||||
module=metadata.get('module'),
|
||||
source=metadata.get('source'),
|
||||
line=metadata.get('line'),
|
||||
args=metadata.get('args', []),
|
||||
)
|
||||
|
||||
@action
|
||||
def status(self, *_, **__):
|
||||
"""
|
||||
:return: The serialized configured procedures. Format:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"procedure_name": {
|
||||
"type": "python",
|
||||
"module": "module_name",
|
||||
"source": "/path/to/source.py",
|
||||
"line": 42,
|
||||
"args": ["arg1", "arg2"]
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
self.publish_entities(self._get_wrapped_procedures())
|
||||
return self._get_serialized_procedures()
|
||||
|
||||
def transform_entities(
|
||||
self, entities: Collection[_ProcedureWrapper], **_
|
||||
) -> Collection[Procedure]:
|
||||
return [
|
||||
self._convert_procedure(name=proc.name, proc=proc.obj) for proc in entities
|
||||
]
|
||||
|
||||
def _get_wrapped_procedures(self) -> Collection[_ProcedureWrapper]:
|
||||
return [
|
||||
_ProcedureWrapper(name=name, obj=proc)
|
||||
for name, proc in self._all_procedures.items()
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _serialize_procedure(
|
||||
proc: Union[dict, Callable], name: Optional[str] = None
|
||||
) -> dict:
|
||||
ret = json.loads(json.dumps(proc, cls=ProcedureEncoder))
|
||||
if name:
|
||||
ret['name'] = name
|
||||
|
||||
return ret
|
||||
|
||||
def _get_serialized_procedures(self) -> dict:
|
||||
return {
|
||||
name: self._serialize_procedure(proc, name=name)
|
||||
for name, proc in self._all_procedures.items()
|
||||
}
|
||||
|
||||
def main(self, *_, **__):
|
||||
while not self.should_stop():
|
||||
self.publish_entities(self._get_wrapped_procedures())
|
||||
self.wait_stop()
|
7
platypush/plugins/procedures/manifest.json
Normal file
7
platypush/plugins/procedures/manifest.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"manifest": {
|
||||
"package": "platypush.plugins.procedure",
|
||||
"type": "plugin",
|
||||
"events": []
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue