Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
63e80fc
update
tchaton Jul 11, 2022
8c94042
update
tchaton Jul 11, 2022
39e5036
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 11, 2022
0b6c763
update
tchaton Jul 11, 2022
afb3371
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 11, 2022
608c4a6
update
tchaton Jul 11, 2022
772d4a5
update
tchaton Jul 11, 2022
dca63de
update
tchaton Jul 11, 2022
0091f4e
update
tchaton Jul 11, 2022
ee3f7ad
update
tchaton Jul 11, 2022
b06ec89
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 11, 2022
59661c2
update
tchaton Jul 11, 2022
c69ae80
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 11, 2022
239a879
update
tchaton Jul 11, 2022
8551482
update
tchaton Jul 11, 2022
2154520
update
tchaton Jul 11, 2022
6c95cf5
update
tchaton Jul 11, 2022
350d11e
update
tchaton Jul 11, 2022
2846842
update
tchaton Jul 12, 2022
5d80b33
Merge branch 'master' into lightning_commands
tchaton Jul 12, 2022
602de9c
working poc
tchaton Jul 14, 2022
ad51386
update
tchaton Jul 14, 2022
e678cba
wip
tchaton Jul 14, 2022
bc9b2f5
update
tchaton Jul 14, 2022
870b9aa
update
tchaton Jul 14, 2022
c1de86b
update
tchaton Jul 15, 2022
9d7eb18
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 15, 2022
3c3192f
update
tchaton Jul 18, 2022
a000bc3
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 18, 2022
42fe030
update
tchaton Jul 18, 2022
b796082
update
tchaton Jul 18, 2022
63a57f0
update
tchaton Jul 18, 2022
4ed8759
update
tchaton Jul 18, 2022
19ffd9c
update
tchaton Jul 18, 2022
e78e43b
update
tchaton Jul 18, 2022
0f8b11f
update
tchaton Jul 18, 2022
119b312
update
tchaton Jul 18, 2022
88e6c13
update
tchaton Jul 18, 2022
aa0b60b
Apply suggestions from code review
Borda Jul 18, 2022
3e4fa95
update
tchaton Jul 20, 2022
a462a32
update
tchaton Jul 20, 2022
ddad86c
update
tchaton Jul 20, 2022
7882a9e
update
tchaton Jul 21, 2022
aa7e797
update
tchaton Jul 21, 2022
66f62d2
Merge branch 'master' into lightning_commands
tchaton Jul 21, 2022
27d0ca8
update
tchaton Jul 21, 2022
bd6e449
update
tchaton Jul 22, 2022
73a6a3f
update
tchaton Jul 22, 2022
2e785bb
update
tchaton Jul 22, 2022
8c6849d
Merge branch 'master' into lightning_commands
tchaton Jul 22, 2022
deb1c40
update
tchaton Jul 22, 2022
fa04ab6
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 22, 2022
78dbd10
update
tchaton Jul 22, 2022
da353a7
update
tchaton Jul 22, 2022
05fc114
update
tchaton Jul 22, 2022
4f00118
update
tchaton Jul 22, 2022
4fee4ca
update
tchaton Jul 22, 2022
8867005
update
tchaton Jul 22, 2022
6e11661
update
tchaton Jul 22, 2022
f628641
Update src/lightning_app/CHANGELOG.md
tchaton Jul 22, 2022
bf237a4
update
tchaton Jul 22, 2022
a04bac0
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 22, 2022
275e3f0
Merge branch 'master' into lightning_commands
tchaton Jul 22, 2022
6d011e7
update
tchaton Jul 22, 2022
fc47f84
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 22, 2022
4485cf9
update
tchaton Jul 22, 2022
5f5c8bf
update
tchaton Jul 22, 2022
7e6d09b
update
tchaton Jul 22, 2022
30e84e8
update
tchaton Jul 22, 2022
d40a228
Merge branch 'master' into lightning_commands
tchaton Jul 22, 2022
1abef07
update
tchaton Jul 22, 2022
f11f0b7
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 22, 2022
5525fbf
Merge branch 'master' into lightning_commands
tchaton Jul 22, 2022
495c9f0
update
tchaton Jul 25, 2022
51f6999
Merge branch 'lightning_commands' of https://github.com/Lightning-AI/…
tchaton Jul 25, 2022
1d61f14
update
tchaton Jul 25, 2022
1fb95bc
Merge branch 'master' into lightning_commands
tchaton Jul 25, 2022
5b6434d
update
tchaton Jul 25, 2022
99767c3
Merge branch 'master' into lightning_commands
tchaton Jul 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci-app_cloud_e2e_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
- custom_work_dependencies
- drive
- payload
- commands
timeout-minutes: 35
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -155,7 +156,7 @@ jobs:
shell: bash
run: |
mkdir -p ${VIDEO_LOCATION}
HEADLESS=1 python -m pytest tests/tests_app_examples/test_${{ matrix.app_name }}.py::test_${{ matrix.app_name }}_example_cloud --timeout=900 --capture=no -v --color=yes
HEADLESS=1 PACKAGE_LIGHTNING=1 python -m pytest tests/tests_app_examples/test_${{ matrix.app_name }}.py::test_${{ matrix.app_name }}_example_cloud --timeout=900 --capture=no -v --color=yes
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, are this env. var described somewhere?

# Delete the artifacts if successful
rm -r ${VIDEO_LOCATION}/${{ matrix.app_name }}

Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ celerybeat-schedule

# dotenv
.env
.env_stagging

# virtualenv
.venv
Expand Down Expand Up @@ -160,3 +161,5 @@ tags
.tags
src/lightning_app/ui/*
*examples/template_react_ui*
hars*
artifacts/*
1 change: 1 addition & 0 deletions examples/app_commands/.lightning
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name: app-commands
39 changes: 39 additions & 0 deletions examples/app_commands/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from command import CustomCommand, CustomConfig

from lightning import LightningFlow
from lightning_app.core.app import LightningApp


class ChildFlow(LightningFlow):
def trigger_method(self, name: str):
print(f"Hello {name}")

def configure_commands(self):
return [{"nested_trigger_command": self.trigger_method}]


class FlowCommands(LightningFlow):
def __init__(self):
super().__init__()
self.names = []
self.child_flow = ChildFlow()

def run(self):
if len(self.names):
print(self.names)

def trigger_without_client_command(self, name: str):
self.names.append(name)

def trigger_with_client_command(self, config: CustomConfig):
self.names.append(config.name)

def configure_commands(self):
commands = [
{"trigger_without_client_command": self.trigger_without_client_command},
{"trigger_with_client_command": CustomCommand(self.trigger_with_client_command)},
]
return commands + self.child_flow.configure_commands()


app = LightningApp(FlowCommands())
17 changes: 17 additions & 0 deletions examples/app_commands/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from argparse import ArgumentParser

from pydantic import BaseModel

from lightning.app.utilities.commands import ClientCommand


class CustomConfig(BaseModel):
name: str


class CustomCommand(ClientCommand):
def run(self):
parser = ArgumentParser()
parser.add_argument("--name", type=str)
args = parser.parse_args()
self.invoke_handler(config=CustomConfig(name=args.name))
4 changes: 4 additions & 0 deletions src/lightning_app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

### Added

- Add support for `Lightning App Commands` through the `configure_commands` hook on the Lightning Flow and the `ClientCommand` ([#13602](https://github.com/Lightning-AI/lightning/pull/13602))

### Changed

- Update the Lightning App docs ([#13537](https://github.com/PyTorchLightning/pytorch-lightning/pull/13537))

### Changed
Expand Down
91 changes: 80 additions & 11 deletions src/lightning_app/cli/lightning_cli.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import logging
import os
import sys
from argparse import ArgumentParser
from pathlib import Path
from typing import List, Tuple, Union
from uuid import uuid4

import click
import requests
from requests.exceptions import ConnectionError

from lightning_app import __version__ as ver
from lightning_app.cli import cmd_init, cmd_install, cmd_pl_init, cmd_react_ui_init
from lightning_app.core.constants import get_lightning_cloud_url, LOCAL_LAUNCH_ADMIN_VIEW
from lightning_app.runners.runtime import dispatch
from lightning_app.runners.runtime_type import RuntimeType
from lightning_app.utilities.cli_helpers import _format_input_env_variables
from lightning_app.utilities.cli_helpers import (
_format_input_env_variables,
_retrieve_application_url_and_available_commands,
)
from lightning_app.utilities.install_components import register_all_external_components
from lightning_app.utilities.login import Auth
from lightning_app.utilities.state import headers_for

logger = logging.getLogger(__name__)

Expand All @@ -26,14 +34,23 @@ def get_app_url(runtime_type: RuntimeType, *args) -> str:
return "http://127.0.0.1:7501/admin" if LOCAL_LAUNCH_ADMIN_VIEW else "http://127.0.0.1:7501/view"


def main():
if len(sys.argv) == 1:
_main()
elif sys.argv[1] in _main.commands.keys() or sys.argv[1] == "--help":
_main()
else:
app_command()


@click.group()
@click.version_option(ver)
def main():
def _main():
register_all_external_components()
pass


@main.command()
@_main.command()
def login():
"""Log in to your Lightning.ai account."""
auth = Auth()
Expand All @@ -46,7 +63,7 @@ def login():
exit(1)


@main.command()
@_main.command()
def logout():
"""Log out of your Lightning.ai account."""
Auth().clear()
Expand Down Expand Up @@ -93,7 +110,7 @@ def on_before_run(*args):
click.echo("Application is ready in the cloud")


@main.group()
@_main.group()
def run():
"""Run your application."""

Expand Down Expand Up @@ -125,31 +142,83 @@ def run_app(
_run_app(file, cloud, without_server, no_cache, name, blocking, open_ui, env)


@main.group(hidden=True)
def app_command():
"""Execute a function in a running application from its name."""
from lightning_app.utilities.commands.base import _download_command

logger.warn("Lightning Commands are a beta feature and APIs aren't stable yet.")

debug_mode = bool(int(os.getenv("DEBUG", "0")))

parser = ArgumentParser()
parser.add_argument("--app_id", default=None, type=str, help="Optional argument to identify an application.")
hparams, argv = parser.parse_known_args()

# 1: Collect the url and comments from the running application
url, commands = _retrieve_application_url_and_available_commands(hparams.app_id)
if url is None or commands is None:
raise Exception("We couldn't find any matching running app.")

if not commands:
raise Exception("This application doesn't expose any commands yet.")

command = argv[0]

command_names = [c["command"] for c in commands]
if command not in command_names:
raise Exception(f"The provided command {command} isn't available in {command_names}")

# 2: Send the command from the user
command_metadata = [c for c in commands if c["command"] == command][0]
params = command_metadata["params"]

# 3: Execute the command
if not command_metadata["is_client_command"]:
# TODO: Improve what is supported there.
kwargs = {k.split("=")[0].replace("--", ""): k.split("=")[1] for k in argv[1:]}
for param in params:
if param not in kwargs:
raise Exception(f"The argument --{param}=X hasn't been provided.")
json = {
"command_name": command,
"command_arguments": kwargs,
"affiliation": command_metadata["affiliation"],
"id": str(uuid4()),
}
resp = requests.post(url + "/api/v1/commands", json=json, headers=headers_for({}))
assert resp.status_code == 200, resp.json()
else:
client_command, models = _download_command(command_metadata, hparams.app_id, debug_mode=debug_mode)
client_command._setup(metadata=command_metadata, models=models, app_url=url)
sys.argv = argv
client_command.run()


@_main.group(hidden=True)
def fork():
"""Fork an application."""
pass


@main.group(hidden=True)
@_main.group(hidden=True)
def stop():
"""Stop your application."""
pass


@main.group(hidden=True)
@_main.group(hidden=True)
def delete():
"""Delete an application."""
pass


@main.group(name="list", hidden=True)
@_main.group(name="list", hidden=True)
def get_list():
"""List your applications."""
pass


@main.group()
@_main.group()
def install():
"""Install Lightning apps and components."""

Expand Down Expand Up @@ -207,7 +276,7 @@ def install_component(name, yes, version):
cmd_install.gallery_component(name, yes, version)


@main.group()
@_main.group()
def init():
"""Init a Lightning app and component."""

Expand Down
4 changes: 2 additions & 2 deletions src/lightning_app/components/python/tracer.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ def __init__(
:language: python
"""
super().__init__(**kwargs)
if not os.path.exists(script_path):
raise FileNotFoundError(f"The provided `script_path` {script_path}` wasn't found.")
self.script_path = str(script_path)
if isinstance(script_args, str):
script_args = script_args.split(" ")
Expand All @@ -105,6 +103,8 @@ def __init__(
setattr(self, name, None)

def run(self, **kwargs):
if not os.path.exists(self.script_path):
raise FileNotFoundError(f"The provided `script_path` {self.script_path}` wasn't found.")
kwargs = {k: v.value if isinstance(v, Payload) else v for k, v in kwargs.items()}
init_globals = globals()
init_globals.update(kwargs)
Expand Down
Loading