[#341] Added utility procedures.to_yaml
action.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e39e36e5f6
commit
c54269e3d2
1 changed files with 53 additions and 0 deletions
|
@ -1,10 +1,12 @@
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from multiprocessing import RLock
|
from multiprocessing import RLock
|
||||||
from random import randint
|
from random import randint
|
||||||
from typing import Callable, Collection, Generator, Iterable, Optional, Union
|
from typing import Callable, Collection, Generator, Iterable, Optional, Union
|
||||||
|
|
||||||
|
import yaml
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
|
@ -228,6 +230,57 @@ class ProceduresPlugin(RunnablePlugin, ProcedureEntityManager):
|
||||||
|
|
||||||
self.status()
|
self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
|
def to_yaml(self, procedure: Union[str, dict]) -> str:
|
||||||
|
"""
|
||||||
|
Serialize a procedure to YAML.
|
||||||
|
|
||||||
|
This method is useful to export a procedure to a file.
|
||||||
|
Note that it only works with either YAML-based procedures or
|
||||||
|
database-stored procedures: Python procedures can't be converted to
|
||||||
|
YAML.
|
||||||
|
|
||||||
|
:param procedure: Procedure name or definition. If a string is passed,
|
||||||
|
then the procedure will be looked up by name in the configured
|
||||||
|
procedures. If a dictionary is passed, then it should be a valid
|
||||||
|
procedure definition with at least the ``actions`` and ``name``
|
||||||
|
keys.
|
||||||
|
:return: The serialized procedure in YAML format.
|
||||||
|
"""
|
||||||
|
if isinstance(procedure, str):
|
||||||
|
proc = self._all_procedures.get(procedure)
|
||||||
|
assert proc, f'Procedure {proc} not found'
|
||||||
|
elif isinstance(procedure, dict):
|
||||||
|
name = self._normalize_name(procedure.get('name'))
|
||||||
|
assert name, 'Procedure name cannot be empty'
|
||||||
|
|
||||||
|
actions = procedure.get('actions', [])
|
||||||
|
assert actions and isinstance(
|
||||||
|
actions, (list, tuple, set)
|
||||||
|
), 'Procedure definition should have at least the "actions" key as a list of actions'
|
||||||
|
|
||||||
|
args = [self._normalize_name(arg) for arg in procedure.get('args', [])]
|
||||||
|
proc = {
|
||||||
|
f'procedure.{name}'
|
||||||
|
+ (f'({", ".join(args)})' if args else ''): [
|
||||||
|
{
|
||||||
|
'action': action['action'],
|
||||||
|
**({'args': action['args']} if action.get('args') else {}),
|
||||||
|
}
|
||||||
|
for action in actions
|
||||||
|
]
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
raise AssertionError(
|
||||||
|
f'Invalid procedure definition with type {type(procedure)}'
|
||||||
|
)
|
||||||
|
|
||||||
|
return yaml.safe_dump(proc, default_flow_style=False, indent=2)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _normalize_name(name: Optional[str]) -> str:
|
||||||
|
return re.sub(r'[^\w.]+', '_', (name or '').strip(' .'))
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def _db_session(self) -> Generator[Session, None, None]:
|
def _db_session(self) -> Generator[Session, None, None]:
|
||||||
db: Optional[DbPlugin] = get_plugin(DbPlugin)
|
db: Optional[DbPlugin] = get_plugin(DbPlugin)
|
||||||
|
|
Loading…
Reference in a new issue