Merge pull request #2224 from pypeclub/feature/module_can_add_cli_command

Modules: Module can add cli commands
This commit is contained in:
Jakub Trllo 2021-11-12 13:21:13 +01:00 committed by GitHub
commit 6a4caf1f86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 143 additions and 3 deletions

View file

@ -57,6 +57,17 @@ def tray(debug=False):
PypeCommands().launch_tray(debug)
@PypeCommands.add_modules
@main.group(help="Run command line arguments of OpenPype modules")
@click.pass_context
def module(ctx):
"""Module specific commands created dynamically.
These commands are generated dynamically by currently loaded addon/modules.
"""
pass
@main.command()
@click.option("-d", "--debug", is_flag=True, help="Print debug messages")
@click.option("--ftrack-url", envvar="FTRACK_SERVER",

View file

@ -22,6 +22,10 @@ OpenPype modules should contain separated logic of specific kind of implementati
- `__init__` should not be overridden and `initialize` should not do time consuming part but only prepare base data about module
- also keep in mind that they may be initialized in headless mode
- connection with other modules is made with help of interfaces
- `cli` method - add cli commands specific for the module
- command line arguments are handled using `click` python module
- `cli` method should expect single argument which is click group on which can be called any group specific methods (e.g. `add_command` to add another click group as children see `ExampleAddon`)
- it is possible to add trigger cli commands using `./openpype_console module <module_name> <command> *args`
## Addon class `OpenPypeAddOn`
- inherits from `OpenPypeModule` but is enabled by default and doesn't have to implement `initialize` and `connect_with_modules` methods
@ -140,4 +144,4 @@ class ClockifyModule(
### TrayModulesManager
- inherits from `ModulesManager`
- has specific implementation for Pype Tray tool and handle `ITrayModule` methods
- has specific implementation for Pype Tray tool and handle `ITrayModule` methods

View file

@ -392,6 +392,28 @@ class OpenPypeModule:
"""
return {}
def cli(self, module_click_group):
"""Add commands to click group.
The best practise is to create click group for whole module which is
used to separate commands.
class MyPlugin(OpenPypeModule):
...
def cli(self, module_click_group):
module_click_group.add_command(cli_main)
@click.group(<module name>, help="<Any help shown in cmd>")
def cli_main():
pass
@cli_main.command()
def mycommand():
print("my_command")
"""
pass
class OpenPypeAddOn(OpenPypeModule):
# Enable Addon by default

View file

@ -1,8 +1,10 @@
import os
import json
import collections
from openpype.modules import OpenPypeModule
import click
from openpype.modules import OpenPypeModule
from openpype_interfaces import (
ITrayModule,
IPluginPaths,
@ -409,3 +411,54 @@ class FtrackModule(
return 0
hours_logged = (task_entity["time_logged"] / 60) / 60
return hours_logged
def cli(self, click_group):
click_group.add_command(cli_main)
@click.group(FtrackModule.name, help="Ftrack module related commands.")
def cli_main():
pass
@cli_main.command()
@click.option("-d", "--debug", is_flag=True, help="Print debug messages")
@click.option("--ftrack-url", envvar="FTRACK_SERVER",
help="Ftrack server url")
@click.option("--ftrack-user", envvar="FTRACK_API_USER",
help="Ftrack api user")
@click.option("--ftrack-api-key", envvar="FTRACK_API_KEY",
help="Ftrack api key")
@click.option("--legacy", is_flag=True,
help="run event server without mongo storing")
@click.option("--clockify-api-key", envvar="CLOCKIFY_API_KEY",
help="Clockify API key.")
@click.option("--clockify-workspace", envvar="CLOCKIFY_WORKSPACE",
help="Clockify workspace")
def eventserver(
debug,
ftrack_url,
ftrack_user,
ftrack_api_key,
legacy,
clockify_api_key,
clockify_workspace
):
"""Launch ftrack event server.
This should be ideally used by system service (such us systemd or upstart
on linux and window service).
"""
if debug:
os.environ["OPENPYPE_DEBUG"] = "3"
from .ftrack_server.event_server_cli import run_event_server
return run_event_server(
ftrack_url,
ftrack_user,
ftrack_api_key,
legacy,
clockify_api_key,
clockify_workspace
)

View file

@ -8,10 +8,12 @@ in global space here until are required or used.
"""
import os
import click
from openpype.modules import (
JsonFilesSettingsDef,
OpenPypeAddOn
OpenPypeAddOn,
ModulesManager
)
# Import interface defined by this addon to be able find other addons using it
from openpype_interfaces import (
@ -114,3 +116,32 @@ class ExampleAddon(OpenPypeAddOn, IPluginPaths, ITrayAction):
return {
"publish": [os.path.join(current_dir, "plugins", "publish")]
}
def cli(self, click_group):
click_group.add_command(cli_main)
@click.group(ExampleAddon.name, help="Example addon dynamic cli commands.")
def cli_main():
pass
@cli_main.command()
def nothing():
"""Does nothing but print a message."""
print("You've triggered \"nothing\" command.")
@cli_main.command()
def show_dialog():
"""Show ExampleAddon dialog.
We don't have access to addon directly through cli so we have to create
it again.
"""
from openpype.tools.utils.lib import qt_app_context
manager = ModulesManager()
example_addon = manager.modules_by_name[ExampleAddon.name]
with qt_app_context():
example_addon.show_dialog()

View file

@ -41,6 +41,25 @@ class PypeCommands:
user_role = "manager"
settings.main(user_role)
@staticmethod
def add_modules(click_func):
"""Modules/Addons can add their cli commands dynamically."""
from openpype.modules import ModulesManager
manager = ModulesManager()
log = PypeLogger.get_logger("AddModulesCLI")
for module in manager.modules:
try:
module.cli(click_func)
except Exception:
log.warning(
"Failed to add cli command for module \"{}\"".format(
module.name
)
)
return click_func
@staticmethod
def launch_eventservercli(*args):
from openpype_modules.ftrack.ftrack_server.event_server_cli import (