Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
f52c245
Add CI app e2e
Jul 1, 2022
eee207a
Merge branch 'master' of github.com:Lightning-AI/lightning into add-c…
Jul 11, 2022
b2ac812
clean projects
Jul 11, 2022
6e1ba6c
clean projects
Jul 11, 2022
4c6a0f4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 11, 2022
1a38ae2
update UserID
Jul 12, 2022
2e0c268
Merge branch 'master' of github.com:Lightning-AI/lightning into add-c…
Jul 12, 2022
e851091
Merge branch 'add-ci-examples-e2e' of github.com:Lightning-AI/lightni…
Jul 12, 2022
60cdb3a
Merge branch 'master' into add-ci-examples-e2e
akihironitta Jul 13, 2022
1e4c442
install l
Jul 13, 2022
65c240a
Merge branch 'add-ci-examples-e2e' of github.com:Lightning-AI/lightni…
Jul 13, 2022
cbaacb0
fix apps cleanup
Jul 13, 2022
5969c1e
isort
Jul 13, 2022
4df7cd0
revert gitignore
Jul 13, 2022
d2e107a
strip username
Jul 13, 2022
33dc161
disable cache
Jul 13, 2022
a93ab18
download frontend while installing lightning
Jul 13, 2022
b42fae5
ci
Jul 13, 2022
119e44d
ci
Jul 13, 2022
88fdc54
add torch
Jul 14, 2022
5e2aeba
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2022
62145b4
ci
Jul 14, 2022
c41b483
ci
Jul 14, 2022
0c355b8
ci
Jul 14, 2022
782ea13
CI
Jul 14, 2022
d202302
ci, and tests
Jul 14, 2022
2c754c4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 14, 2022
3bd6731
CI
Jul 14, 2022
fc87201
Merge branch 'add-ci-examples-e2e' of github.com:Lightning-AI/lightni…
Jul 14, 2022
3ccdc10
Merge branch 'master' of github.com:Lightning-AI/lightning into add-c…
Jul 14, 2022
8972e32
revert install changes
Jul 14, 2022
b606a9a
Merge branch 'master' of github.com:Lightning-AI/lightning into add-c…
Jul 14, 2022
49e924e
move pip list, comment venv
Jul 14, 2022
3a4baa4
fix yaml file
Jul 14, 2022
9441487
skip quick start test
Jul 14, 2022
a782a06
remove .lightning file
Jul 14, 2022
ccdfcad
skip files
Jul 15, 2022
f2ead3e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 15, 2022
9f2ea4a
don't print
Jul 15, 2022
93302be
Merge branch 'add-ci-examples-e2e' of github.com:Lightning-AI/lightni…
Jul 15, 2022
aebb086
download frontend inside setup.py
Jul 15, 2022
e630d27
pylint
Jul 15, 2022
ffecf70
make file changes in seperate job
Jul 16, 2022
8aaa632
Merge branch 'master' of github.com:Lightning-AI/lightning into add-c…
Jul 16, 2022
3adbea6
skip installing quick-start
Jul 16, 2022
3ed0e72
Merge branch 'master' into add-ci-examples-e2e
Borda Jul 17, 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
31 changes: 31 additions & 0 deletions .actions/setup_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@
import glob
import logging
import os
import pathlib
import re
import shutil
import tarfile
import tempfile
import urllib.request
from importlib.util import module_from_spec, spec_from_file_location
from itertools import groupby
from types import ModuleType
Expand All @@ -23,6 +28,9 @@
_PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
_PACKAGE_MAPPING = {"pytorch": "pytorch_lightning", "app": "lightning_app"}

# TODO: remove this once lightning-ui package is ready as a dependency
_LIGHTNING_FRONTEND_RELEASE_URL = "https://storage.googleapis.com/grid-packages/lightning-ui/v0.0.0/build.tar.gz"


def _load_py_module(name: str, location: str) -> ModuleType:
spec = spec_from_file_location(name, location)
Expand Down Expand Up @@ -317,3 +325,26 @@ class implementations by cross-imports to the true package.
os.makedirs(os.path.dirname(new_file), exist_ok=True)
with open(new_file, "w", encoding="utf-8") as fp:
fp.writelines(lines)


def _download_frontend(root: str = _PROJECT_ROOT):
"""Downloads an archive file for a specific release of the Lightning frontend and extracts it to the correct
directory."""

try:
build_dir = "build"
frontend_dir = pathlib.Path(root, "src", "lightning_app", "ui")
download_dir = tempfile.mkdtemp()

shutil.rmtree(frontend_dir, ignore_errors=True)
response = urllib.request.urlopen(_LIGHTNING_FRONTEND_RELEASE_URL)

file = tarfile.open(fileobj=response, mode="r|gz")
file.extractall(path=download_dir)

shutil.move(os.path.join(download_dir, build_dir), frontend_dir)
print("The Lightning UI has successfully been downloaded!")

# If installing from source without internet connection, we don't want to break the installation
except Exception:
print("The Lightning UI downloading has failed!")
9 changes: 9 additions & 0 deletions .github/file-filters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This file contains filters to be used in the CI to detect file changes and run the required CI jobs.

app_examples:
- "src/lightning_app/**"
- "tests/tests_app_examples/**"
- "requirements/app/**"
- "examples/app_*"
- "setup.py"
- "src/pytorch_lightning/__version__.py"
186 changes: 186 additions & 0 deletions .github/workflows/ci-app_cloud_e2e_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
name: cloud-testing

# Used to run the e2e tests on lightning.ai

on: # Trigger the workflow on push or pull request, but only for the master branch
push:
branches:
- "master"
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

jobs:
# This is job should once only once per PR to detect file changes so run required jobs.
# see .github/file-filters.yml to define file filters and run the jobs based on the output of each filter.
# More info: https://github.com/marketplace/actions/paths-changes-filter

changes:
runs-on: ubuntu-latest
# Set job outputs to the values from filter step
outputs:
app_examples: ${{ steps.filter.outputs.app_examples }}
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: "3.8"

- uses: dorny/paths-filter@v2
id: filter
with:
filters: .github/file-filters.yml

cloud-test:
name: Cloud Test
needs: changes
if: ${{ needs.changes.outputs.app_examples == 'true' }}
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
app_name:
- v0_app
- boring_app
# - quick_start # TODO: fix this
- template_streamlit_ui
- template_react_ui
- template_jupyterlab
- idle_timeout
- collect_failures
- custom_work_dependencies
- drive
- payload
timeout-minutes: 35
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: "3.8"

- name: Get PR ID
id: PR
run: |
if [ -z ${{github.event.number}} ]; then
echo "::set-output name=ID::$(date +%s)"
else
echo "::set-output name=ID::${{github.event.number}}"
fi

# TODO: Enable cache
# - name: Cache virtualenv
# id: cache-venv
# uses: actions/cache@v2
# with:
# path: ./.venv/
# key: ${{ runner.os }}-pip-${{ matrix.app_name }}-${{ hashFiles('requirements/app/base.txt', 'requirements/app/*.txt', 'src/lightning_app/__version__.py') }}
# restore-keys: ${{ runner.os }}-venv-${{ matrix.app_name }}-

- name: Install dependencies
shell: bash
run: |
pip --version
python -m pip install -r requirements/app/devel.txt --no-cache --quiet --find-links https://download.pytorch.org/whl/cpu/torch_stable.html
# if: steps.cache-venv.outputs.cache-hit != 'true' # TODO: Enable cache

- name: Cache Playwright dependencies
id: playwright-cache
uses: actions/cache@v2
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ matrix.app_name }}-${{ hashFiles('requirements/app/base.txt', 'requirements/app/*.txt', 'src/lightning_app/__version__.py') }}
restore-keys: ${{ runner.os }}-playwright-${{ matrix.app_name }}-

- name: Install Playwright system dependencies
shell: bash
run: |
python -m pip install playwright
python -m playwright install --with-deps
# if: steps.playwright-cache.outputs.cache-hit != 'true' # TODO: Enable cache

- name: Install lightning
run: |
pip install -e .
shell: bash

- name: Lightning Install quick-start
if: ${{ (matrix.app_name == 'quick_start') }}
shell: bash
run: |
python -m lightning install app lightning/quick-start -y

- name: Clone Template React UI Repo
uses: actions/checkout@v3
with:
repository: Lightning-AI/lightning-template-react
token: ${{ secrets.PAT_GHOST }}
ref: 'master'
path: examples/app_template_react_ui

- name: Clone Template Jupyter Lab Repo
uses: actions/checkout@v3
with:
repository: Lightning-AI/lightning-template-jupyterlab
token: ${{ secrets.PAT_GHOST }}
ref: 'master'
path: examples/app_template_jupyterlab

- name: Copy Template Jupyter Lab Repo tests
shell: bash
run: cp examples/app_template_jupyterlab/tests/test_template_jupyterlab.py tests/tests_app_examples/test_template_jupyterlab.py

- name: List pip dependency
shell: bash
run: |
pip list

- name: Run the tests
env:
LAI_USER: ${{ secrets.LAI_USER }}
LAI_PASS: ${{ secrets.LAI_PASS }}
LIGHTNING_USER_ID: ${{ secrets.LIGHTNING_USER_ID }}
LIGHTNING_API_KEY: ${{ secrets.LIGHTNING_API_KEY }}
LIGHTNING_USERNAME: ${{ secrets.LIGHTNING_USERNAME }}
LIGHTNING_CLOUD_URL: ${{ secrets.LIGHTNING_CLOUD_URL }}
CLOUD: "1"
VIDEO_LOCATION: ./artifacts/videos
PR_NUMBER: ${{ steps.PR.outputs.ID }}
TEST_APP_NAME: ${{ matrix.app_name }}
HAR_LOCATION: ./artifacts/hars
SLOW_MO: 50
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
# Delete the artifacts if successful
rm -r ${VIDEO_LOCATION}/${{ matrix.app_name }}

- uses: actions/upload-artifact@v2

if: ${{ always() }}
with:
name: test-artifacts
path: ./artifacts/videos

- name: Clean Previous Apps
if: ${{ always() }}
env:
LAI_USER: ${{ secrets.LAI_USER }}
LAI_PASS: ${{ secrets.LAI_PASS }}
LIGHTNING_USER_ID: ${{ secrets.LIGHTNING_USER_ID }}
LIGHTNING_API_KEY: ${{ secrets.LIGHTNING_API_KEY }}
LIGHTNING_USERNAME: ${{ secrets.LIGHTNING_USERNAME }}
LIGHTNING_CLOUD_URL: ${{ secrets.LIGHTNING_CLOUD_URL }}
PR_NUMBER: ${{ steps.PR.outputs.ID }}
TEST_APP_NAME: ${{ matrix.app_name }}
GRID_USER_ID: ${{ secrets.LIGHTNING_USER_ID }}
GRID_USER_KEY: ${{ secrets.LIGHTNING_API_KEY }}
GRID_URL: ${{ secrets.LIGHTNING_CLOUD_URL }}
_GRID_USERNAME: ${{ secrets.LIGHTNING_USERNAME }}
shell: bash
run: |
time python -c "from lightning.app import testing; testing.delete_cloud_lightning_apps()"
48 changes: 48 additions & 0 deletions examples/app_template_streamlit_ui/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import logging

from lightning_app import LightningApp, LightningFlow
from lightning_app.frontend import StreamlitFrontend
from lightning_app.utilities.state import AppState

logger = logging.getLogger(__name__)


class StreamlitUI(LightningFlow):
def __init__(self):
super().__init__()
self.message_to_print = "Hello World!"
self.should_print = False

def configure_layout(self):
return StreamlitFrontend(render_fn=render_fn)


def render_fn(state: AppState):
import streamlit as st

should_print = st.button("Should print to the terminal ?")

if should_print:
state.should_print = not state.should_print

st.write("Currently printing." if state.should_print else "Currently waiting to print.")


class HelloWorld(LightningFlow):
def __init__(self):
super().__init__()
self.counter = 0
self.streamlit_ui = StreamlitUI()

def run(self):
self.streamlit_ui.run()
if self.streamlit_ui.should_print:
logger.info(f"{self.counter}: {self.streamlit_ui.message_to_print}")
self.counter += 1
self.streamlit_ui.should_print = False

def configure_layout(self):
return [{"name": "StreamLitUI", "content": self.streamlit_ui}]


app = LightningApp(HelloWorld())
1 change: 1 addition & 0 deletions examples/app_template_streamlit_ui/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
streamlit
9 changes: 8 additions & 1 deletion src/lightning/__setup__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def _adjust_manifest(**kwargs: Any) -> None:
"recursive-include src *.md" + os.linesep,
"recursive-include requirements *.txt" + os.linesep,
]

# TODO: remove this once lightning-ui package is ready as a dependency
lines += ["recursive-include src/lightning_app/ui *" + os.linesep]
with open(manifest_path, "w") as fp:
fp.writelines(lines)

Expand All @@ -64,7 +67,11 @@ def _setup_args(**kwargs: Any) -> Dict[str, Any]:
if os.path.isdir(d)
]
_requires = list(chain(*_requires))
# todo: consider invaliding some additional arguments from packages, for example if include data or safe to zip
# TODO: consider invaliding some additional arguments from packages, for example if include data or safe to zip

# TODO: remove this once lightning-ui package is ready as a dependency
_setup_tools._download_frontend(_PROJECT_ROOT)

return dict(
name="lightning",
version=_version.version, # todo: consider adding branch for installation from source
Expand Down
9 changes: 8 additions & 1 deletion src/lightning_app/__setup__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def _adjust_manifest(**__: Any) -> None:
"recursive-include src/lightning_app *.md" + os.linesep,
"recursive-include requirements/app *.txt" + os.linesep,
]

# TODO: remove this once lightning-ui package is ready as a dependency
lines += ["recursive-include src/lightning_app/ui *" + os.linesep]

with open(manifest_path, "w") as fp:
fp.writelines(lines)

Expand All @@ -63,7 +67,10 @@ def _setup_args(**__: Any) -> Dict[str, Any]:
_long_description = _setup_tools.load_readme_description(
_PACKAGE_ROOT, homepage=_about.__homepage__, version=_version.version
)
# TODO: at this point we need to download the UI to the package

# TODO: remove this once lightning-ui package is ready as a dependency
_setup_tools._download_frontend(_PROJECT_ROOT)

return dict(
name="lightning-app",
version=_version.version, # todo: consider using date version + branch for installation from source
Expand Down
9 changes: 7 additions & 2 deletions src/lightning_app/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from lightning_app.testing.testing import application_testing, LightningTestApp, run_work_isolated
from lightning_app.testing.testing import (
application_testing,
delete_cloud_lightning_apps,
LightningTestApp,
run_work_isolated,
)

__all__ = ["application_testing", "run_work_isolated", "LightningTestApp"]
__all__ = ["application_testing", "run_work_isolated", "LightningTestApp", "delete_cloud_lightning_apps"]
Loading