diff --git a/.azure/app-cloud-e2e.yml b/.azure/app-cloud-e2e.yml
index 306e8b9fcf8ec..02e9d3daed92c 100644
--- a/.azure/app-cloud-e2e.yml
+++ b/.azure/app-cloud-e2e.yml
@@ -75,7 +75,7 @@ jobs:
name: "commands_and_api"
# 'App: quick_start': # TODO: Failed during installation
# name: "quick_start"
- timeoutInMinutes: "30"
+ timeoutInMinutes: "20"
cancelTimeoutInMinutes: "2"
# values: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#workspace
workspace:
diff --git a/.github/checkgroup.yml b/.github/checkgroup.yml
index d1b74dcabf177..86d4dc9a0d07d 100644
--- a/.github/checkgroup.yml
+++ b/.github/checkgroup.yml
@@ -50,7 +50,6 @@ subprojects:
#- "pl-cpu (windows-2022, lightning, 3.7, 1.9, oldest)"
- "make-doctest (pytorch)"
- "make-html (pytorch)"
- - "mypy"
- "pytorch-lightning (GPUs)"
- "pytorch-lightning (HPUs)"
- "pytorch-lightning (IPUs)"
@@ -60,7 +59,7 @@ subprojects:
# TODO: since this job has intermittent availability, it cannot be required or it will block all PL PRs from forks
#- "test-on-tpus"
- - id: "pytorch_lightning: CPU"
+ - id: "pytorch_lightning: CPU workflow"
paths:
- ".github/workflows/ci-pytorch-tests.yml"
checks:
@@ -87,7 +86,7 @@ subprojects:
- "pl-cpu (windows-2022, lightning, 3.10, 1.12)"
#- "pl-cpu (windows-2022, lightning, 3.7, 1.9, oldest)"
- - id: "pytorch_lightning: Slow"
+ - id: "pytorch_lightning: Slow workflow"
paths:
- ".github/workflows/ci-pytorch-tests-slow.yml"
checks:
@@ -114,7 +113,7 @@ subprojects:
checks:
- "pytorch-lightning (IPUs)"
- - id: "pytorch-lightning: TPU"
+ - id: "pytorch-lightning: TPU workflow"
paths:
- ".github/workflows/tpu-tests.yml"
checks:
@@ -181,7 +180,6 @@ subprojects:
- "lite-cpu (ubuntu-20.04, lightning, 3.8, 1.12)"
- "lite-cpu (windows-2022, lightning, 3.8, 1.12)"
- "lightning-lite (GPUs)"
- - "mypy"
# Lite also requires PL checks as it depends on Lite
- "pl-cpu (macOS-11, pytorch, 3.8, 1.10)"
- "pl-cpu (macOS-11, pytorch, 3.9, 1.11)"
@@ -254,8 +252,7 @@ subprojects:
- "requirements/app/**"
- "src/lightning_app/**"
- "tests/tests_app/**"
- - "examples/app_*" # some tests_app tests call examples files
- - ".github/workflows/ci-app-tests.yml"
+ - "examples/app_*/**" # some tests_app tests call examples files
- "setup.py"
- ".actions/**"
checks:
@@ -272,13 +269,26 @@ subprojects:
- "app-pytest (windows-2022, app, 3.8, oldest)"
- "app-pytest (windows-2022, lightning, 3.8, latest)"
+ - id: "lightning_app: Tests workflow"
+ paths:
+ - ".github/workflows/ci-app-tests.yml"
+ checks:
+ - "app-pytest (macOS-11, app, 3.8, latest)"
+ - "app-pytest (macOS-11, app, 3.8, oldest)"
+ - "app-pytest (macOS-11, lightning, 3.9, latest)"
+ - "app-pytest (ubuntu-20.04, app, 3.8, latest)"
+ - "app-pytest (ubuntu-20.04, app, 3.8, oldest)"
+ - "app-pytest (ubuntu-20.04, lightning, 3.9, latest)"
+ - "app-pytest (windows-2022, app, 3.8, latest)"
+ - "app-pytest (windows-2022, app, 3.8, oldest)"
+ - "app-pytest (windows-2022, lightning, 3.8, latest)"
+
- id: "lightning_app: Examples"
paths:
- "requirements/app/**"
- "src/lightning_app/**"
- "tests/tests_app_examples/**"
- - "examples/app_*"
- - ".github/workflows/ci-app-examples.yml"
+ - "examples/app_*/**"
- "setup.py"
- ".actions/**"
checks:
@@ -292,6 +302,20 @@ subprojects:
- "app-examples (windows-2022, app, 3.9, oldest)"
- "app-examples (windows-2022, lightning, 3.9, latest)"
+ - id: "lightning_app: Examples workflow"
+ paths:
+ - ".github/workflows/ci-app-examples.yml"
+ checks:
+ - "app-examples (macOS-11, app, 3.9, latest)"
+ - "app-examples (macOS-11, app, 3.9, oldest)"
+ - "app-examples (macOS-11, lightning, 3.9, latest)"
+ - "app-examples (ubuntu-20.04, app, 3.9, latest)"
+ - "app-examples (ubuntu-20.04, app, 3.9, oldest)"
+ - "app-examples (ubuntu-20.04, lightning, 3.9, latest)"
+ - "app-examples (windows-2022, app, 3.9, latest)"
+ - "app-examples (windows-2022, app, 3.9, oldest)"
+ - "app-examples (windows-2022, lightning, 3.9, latest)"
+
- id: "lightning_app: Azure"
paths:
- ".azure/app-cloud-e2e.yml"
@@ -313,7 +337,10 @@ subprojects:
- id: "mypy"
paths:
- ".github/workflows/code-checks.yml"
+ - "requirements/**"
+ - "src/**"
- "pyproject.toml" # includes mypy config
+ - ".actions/**"
checks:
- "mypy"
diff --git a/.github/workflows/ci-app-examples.yml b/.github/workflows/ci-app-examples.yml
index d05d272401643..5b504c7b6b470 100644
--- a/.github/workflows/ci-app-examples.yml
+++ b/.github/workflows/ci-app-examples.yml
@@ -12,7 +12,8 @@ on:
- "src/lightning_app/**"
- "tests/tests_app_examples/**"
- "examples/app_*"
- - "requirements/app/**"
+ - "requirements/app/*"
+ - "!requirements/app/docs.txt"
- "setup.py"
- ".actions/**"
diff --git a/.github/workflows/ci-app-tests.yml b/.github/workflows/ci-app-tests.yml
index f6f479dd1cbd7..0d000846ef885 100644
--- a/.github/workflows/ci-app-tests.yml
+++ b/.github/workflows/ci-app-tests.yml
@@ -11,7 +11,8 @@ on:
- "src/lightning_app/**"
- "tests/tests_app/**"
- "examples/app_*" # some tests_app tests call examples files
- - "requirements/app/**"
+ - "requirements/app/*"
+ - "!requirements/app/docs.txt"
- "setup.py"
- ".actions/**"
diff --git a/.github/workflows/ci-lite-tests.yml b/.github/workflows/ci-lite-tests.yml
index 2a49ce883669d..a6c6ba421b2a5 100644
--- a/.github/workflows/ci-lite-tests.yml
+++ b/.github/workflows/ci-lite-tests.yml
@@ -8,7 +8,8 @@ on:
branches: [master, "release/*"]
types: [opened, reopened, ready_for_review, synchronize] # add `ready_for_review` since draft is skipped
paths:
- - "requirements/lite/**"
+ - "requirements/lite/*"
+ - "!requirements/lite/docs.txt"
- "src/lightning_lite/**"
- "tests/tests_lite/**"
- "setup.cfg" # includes pytest config
diff --git a/.github/workflows/ci-pkg-install.yml b/.github/workflows/ci-pkg-install.yml
index 4128f721b8576..2f1ab634425b7 100644
--- a/.github/workflows/ci-pkg-install.yml
+++ b/.github/workflows/ci-pkg-install.yml
@@ -12,6 +12,7 @@ on:
- "setup.py"
- "src/**"
- "requirements/**"
+ - "!requirements/*/docs.txt"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
diff --git a/.github/workflows/ci-pytorch-dockers.yml b/.github/workflows/ci-pytorch-dockers.yml
index 7be3e2a15e4fa..a207655e186c5 100644
--- a/.github/workflows/ci-pytorch-dockers.yml
+++ b/.github/workflows/ci-pytorch-dockers.yml
@@ -9,8 +9,8 @@ on:
- "dockers/**"
- "!dockers/README.md"
- "requirements.txt"
- - "requirements/*.txt"
- - "requirements/pytorch/*"
+ - "requirements/**"
+ - "!requirements/*/docs.txt"
- "environment.yml"
- ".github/workflows/*docker*.yml"
- "setup.py"
diff --git a/.github/workflows/ci-pytorch-tests-slow.yml b/.github/workflows/ci-pytorch-tests-slow.yml
index 35de255a6b2b5..fda5fa13f19ff 100644
--- a/.github/workflows/ci-pytorch-tests-slow.yml
+++ b/.github/workflows/ci-pytorch-tests-slow.yml
@@ -9,13 +9,14 @@ on:
types: [opened, reopened, ready_for_review, synchronize] # add `ready_for_review` since draft is skipped
paths:
- ".github/workflows/ci-pytorch-tests-slow.yml"
- - "requirements/pytorch/**"
+ - "requirements/pytorch/*"
- "src/pytorch_lightning/**"
- "tests/tests_pytorch/**"
- "setup.cfg" # includes pytest config
- - "requirements/lite/**"
+ - "requirements/lite/*"
- "src/lightning_lite/**"
- ".actions/**"
+ - "!requirements/*/docs.txt"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
diff --git a/.github/workflows/ci-pytorch-tests.yml b/.github/workflows/ci-pytorch-tests.yml
index fcd19181f6188..1668a5bd7a395 100644
--- a/.github/workflows/ci-pytorch-tests.yml
+++ b/.github/workflows/ci-pytorch-tests.yml
@@ -8,15 +8,16 @@ on:
branches: [master, "release/*"]
types: [opened, reopened, ready_for_review, synchronize] # add `ready_for_review` since draft is skipped
paths:
- - "requirements/pytorch/**"
+ - "requirements/pytorch/*"
- "src/pytorch_lightning/**"
- "tests/tests_pytorch/**"
- "tests/legacy/back-compatible-versions.txt"
- "setup.cfg" # includes pytest config
- ".github/workflows/ci-pytorch-tests.yml"
- - "requirements/lite/**"
+ - "requirements/lite/*"
- "src/lightning_lite/**"
- ".actions/**"
+ - "!requirements/*/docs.txt"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
diff --git a/.github/workflows/code-checks.yml b/.github/workflows/code-checks.yml
index 8af3bc0f5809e..0c4dc6f290719 100644
--- a/.github/workflows/code-checks.yml
+++ b/.github/workflows/code-checks.yml
@@ -5,6 +5,12 @@ on:
branches: [master, "release/*"]
pull_request:
branches: [master, "release/*"]
+ paths:
+ - ".github/workflows/code-checks.yml"
+ - "requirements/**"
+ - "src/**"
+ - "pyproject.toml" # includes mypy config
+ - "actions/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref }}
diff --git a/.github/workflows/docs-checks.yml b/.github/workflows/docs-checks.yml
index 8ff7330a6780e..95746e5a8fb7c 100644
--- a/.github/workflows/docs-checks.yml
+++ b/.github/workflows/docs-checks.yml
@@ -4,7 +4,9 @@ name: Check Docs
on:
push:
branches: ["master", "release/*"]
- pull_request:
+ # use this event type to share secrets with forks.
+ # it's important that the PR head SHA is checked out to run the changes
+ pull_request_target:
branches: ["master", "release/*"]
paths:
- ".actions/**"
@@ -30,6 +32,8 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-python@v4
with:
python-version: "3.8"
@@ -56,6 +60,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
+ ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/download-artifact@v3
with:
name: ci-packages-${{ github.sha }}
@@ -64,6 +69,15 @@ jobs:
with:
python-version: "3.9"
+ - uses: aws-actions/configure-aws-credentials@v1
+ if: ${{ matrix.pkg-name == 'app' }}
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY_ID }}
+ aws-region: us-east-1
+ - run: aws s3 sync s3://sphinx-packages/ pypi/
+ if: ${{ matrix.pkg-name == 'app' }}
+
# Note: This uses an internal pip API and may not always work
# https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow
- name: Cache pip
@@ -82,9 +96,9 @@ jobs:
- name: Install LAI package
# This is needed as App docs is heavily using/referring to lightning package
- if: ${{ matrix.pkg-name== 'app' }}
+ if: ${{ matrix.pkg-name == 'app' }}
run: |
- pip install -e . -U --find-links https://download.pytorch.org/whl/cpu/torch_stable.html --find-links pypi
+ pip install -e . -U -f https://download.pytorch.org/whl/cpu/torch_stable.html -f pypi
git checkout -- setup.py MANIFEST.in
- name: Adjust docs refs
@@ -97,7 +111,8 @@ jobs:
env:
PACKAGE_NAME: ${{ matrix.pkg-name }}
run: |
- pip install -e .[extra,cloud,ui] -U -r requirements/${{ matrix.pkg-name }}/docs.txt --find-links pypi
+ pip install -e .[extra,cloud,ui] -U -r requirements/${{ matrix.pkg-name }}/docs.txt -f pypi
+ pip list
- name: Test Documentation
env:
@@ -120,6 +135,7 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: true
+ ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/download-artifact@v3
with:
name: ci-packages-${{ github.sha }}
@@ -128,6 +144,15 @@ jobs:
with:
python-version: "3.9"
+ - uses: aws-actions/configure-aws-credentials@v1
+ if: ${{ matrix.pkg-name != 'pytorch' }}
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY_ID }}
+ aws-region: us-east-1
+ - run: aws s3 sync s3://sphinx-packages/ pypi/
+ if: ${{ matrix.pkg-name != 'pytorch' }}
+
# Note: This uses an internal pip API and may not always work
# https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow
- name: Cache pip
@@ -145,9 +170,8 @@ jobs:
sudo apt-get update
sudo apt-get install -y cmake pandoc texlive-latex-extra dvipng texlive-pictures
pip --version
- pip install -e . -r requirements/${{ matrix.pkg-name }}/docs.txt \
- --find-links https://download.pytorch.org/whl/cpu/torch_stable.html \
- --find-links pypi
+ pip install -e . -U -r requirements/${{ matrix.pkg-name }}/docs.txt \
+ -f https://download.pytorch.org/whl/cpu/torch_stable.html -f pypi
pip list
shell: bash
diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml
index a2fe59f0b3705..38c5db8a8946c 100644
--- a/.github/workflows/docs-deploy.yml
+++ b/.github/workflows/docs-deploy.yml
@@ -28,6 +28,13 @@ jobs:
with:
python-version: 3.8
+ - uses: aws-actions/configure-aws-credentials@v1
+ with:
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY_ID }}
+ aws-region: us-east-1
+ - run: aws s3 sync s3://sphinx-packages/ pypi/
+
# Note: This uses an internal pip API and may not always work
# https://github.com/actions/cache/blob/master/examples.md#multiple-oss-in-a-workflow
- name: Cache pip
@@ -44,7 +51,8 @@ jobs:
sudo apt-get install -y cmake pandoc
sudo apt-get install -y texlive-latex-extra dvipng texlive-pictures
pip --version
- pip install -e . --quiet -r requirements/app/docs.txt --find-links https://download.pytorch.org/whl/cpu/torch_stable.html
+ pip install -e . --quiet -r requirements/app/docs.txt \
+ -f https://download.pytorch.org/whl/cpu/torch_stable.html -f pypi
pip list
- name: Make Documentation
@@ -87,8 +95,3 @@ jobs:
if: ${{ success() && github.ref == 'refs/heads/master' }}
run: |-
gsutil -m rsync -d -R docs/build/html/ gs://lightning-docs-latest
-
- # fixme
- - name: Upload docs/latest to GCS 🪣
- run: |-
- gsutil -m rsync -d -R docs/build/html/ gs://lightning-docs-latest
diff --git a/.github/workflows/events-nightly.yml b/.github/workflows/events-nightly.yml
deleted file mode 100644
index 70194e498ac27..0000000000000
--- a/.github/workflows/events-nightly.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-name: Nightly
-
-# https://jasonet.co/posts/scheduled-actions/
-# https://github.community/t/distinct-job-for-each-schedule/17811/2
-on:
- schedule:
- # At the end of every day
- - cron: "0 0 * * *"
-
-# based on https://github.com/pypa/gh-action-pypi-publish
-jobs:
- pypi-release:
- if: ${{ github.repository == 'Lightning-AI/lightning' }} # skip for forks
- runs-on: ubuntu-20.04
-
- steps:
- # does nightly releases from feature branch
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
- with:
- python-version: 3.9
-
- - name: Install dependencies
- run: >-
- python -m pip install --user --upgrade setuptools wheel
-
- - name: Build packages
- run: |
- pip install -q -r .actions/requirements.txt
- python .actions/assistant.py prepare_nightly_version
- python setup.py sdist bdist_wheel
- ls -lh dist/
-
- - name: Delay releasing
- uses: juliangruber/sleep-action@v1
- with:
- time: 5m
-
- # We do this, since failures on test.pypi aren't that bad
- - name: Publish to Test PyPI
- uses: pypa/gh-action-pypi-publish@v1.5.1
- with:
- user: __token__
- password: ${{ secrets.test_pypi_password }}
- repository_url: https://test.pypi.org/legacy/
- verbose: true
-
- # report failure to Slack
- - name: Slack notification
- if: failure() && github.event_name == 'schedule'
- uses: ravsamhq/notify-slack-action@v2
- with:
- status: ${{ job.status }}
- token: ${{ secrets.GITHUB_TOKEN }}
- notification_title: 'Publish nightly package to test.pypi.org'
- message_format: '{emoji} *{workflow}* {status_message}, see <{run_url}|detail>, cc: <@UR9FXE6QG>' #Borda
- env:
- SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
diff --git a/.github/workflows/probot-auto-cc.yml b/.github/workflows/probot-auto-cc.yml
index 6de393f41cfd8..7ef962be111da 100644
--- a/.github/workflows/probot-auto-cc.yml
+++ b/.github/workflows/probot-auto-cc.yml
@@ -15,7 +15,7 @@ jobs:
if: github.event_name == 'issue' || github.event.pull_request.draft == false
timeout-minutes: 5
steps:
- - uses: carmocca/probot@v2
+ - uses: Lightning-AI/probot@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
diff --git a/.github/workflows/probot-check-group.yml b/.github/workflows/probot-check-group.yml
index 855c82d38e3fd..19aae47397c9d 100644
--- a/.github/workflows/probot-check-group.yml
+++ b/.github/workflows/probot-check-group.yml
@@ -15,7 +15,7 @@ jobs:
# if this timeout triggers, then the job needs to be manually restarted through the GitHub interface
timeout-minutes: 60
steps:
- - uses: carmocca/probot@v2
+ - uses: Lightning-AI/probot@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml
index 0c7d0f892e685..bba1b5fa15d9e 100644
--- a/.github/workflows/release-pypi.yml
+++ b/.github/workflows/release-pypi.yml
@@ -7,14 +7,7 @@ on:
release:
types: [published]
-# there are several consecutive actions:
-# 1) determine which packages have been change at the time this event is processed
-# 2) build related packages - app/pytorch or download latest from pypi
-# 3) create the meta package - lightning
-# 4) publish all new creations tada
-
jobs:
- # run job which determine changed versions
init:
runs-on: ubuntu-20.04
steps:
@@ -26,7 +19,6 @@ jobs:
name: dist-packages-${{ github.sha }}
path: dist
- # based on https://github.com/pypa/gh-action-pypi-publish
build-packages:
needs: init
runs-on: ubuntu-20.04
diff --git a/.github/workflows/tpu-tests.yml b/.github/workflows/tpu-tests.yml
index 82658935d308b..ac9046b8b1b94 100644
--- a/.github/workflows/tpu-tests.yml
+++ b/.github/workflows/tpu-tests.yml
@@ -8,7 +8,8 @@ on:
types: [opened, reopened, ready_for_review, synchronize] # add `ready_for_review` since draft is skipped
paths:
- ".github/workflows/tpu-tests.yml"
- - "requirements/pytorch/**"
+ - "requirements/pytorch/*"
+ - "!requirements/pytorch/docs.txt"
- "src/pytorch_lightning/**"
- "tests/tests_pytorch/**"
- "setup.cfg" # includes pytest config
diff --git a/.gitignore b/.gitignore
index ab50b997182ce..28606a12d98ca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,3 +177,4 @@ saved_models
data/
.shared
.lightning
+node_modules/
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 3041d634e2fe9..fff64dcf020a1 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -46,6 +46,9 @@ build:
- texlive-latex-extra
- dvipng
- texlive-pictures
+ jobs:
+ pre_install:
+ - export PACKAGE_NAME=pytorch
# Optionally set the version of Python and requirements required to build your docs
python:
diff --git a/_notebooks b/_notebooks
index 0ad097a6fec2b..6d5634b794218 160000
--- a/_notebooks
+++ b/_notebooks
@@ -1 +1 @@
-Subproject commit 0ad097a6fec2b2c3f8ddd5d2263e178c41d614f5
+Subproject commit 6d5634b7942180e6ba4a30bfbd74926d1c22f1eb
diff --git a/docs/source-app/api_reference/api/lightning_app.core.LightningApp.rst b/docs/source-app/api_reference/api/lightning_app.core.LightningApp.rst
index 269a4e8f1143a..8f0a39b44d535 100644
--- a/docs/source-app/api_reference/api/lightning_app.core.LightningApp.rst
+++ b/docs/source-app/api_reference/api/lightning_app.core.LightningApp.rst
@@ -1,6 +1,4 @@
-:orphan:
-
-.. role:: hidden
+.. role:: hidden
:class: hidden-section
.. currentmodule:: lightning_app.core
@@ -10,4 +8,3 @@ LightningApp
.. autoclass:: LightningApp
:members:
- :noindex:
diff --git a/docs/source-app/api_reference/api/lightning_app.core.LightningFlow.rst b/docs/source-app/api_reference/api/lightning_app.core.LightningFlow.rst
index 336efd4d7165b..d305b42d6fc38 100644
--- a/docs/source-app/api_reference/api/lightning_app.core.LightningFlow.rst
+++ b/docs/source-app/api_reference/api/lightning_app.core.LightningFlow.rst
@@ -1,6 +1,4 @@
-:orphan:
-
-.. role:: hidden
+.. role:: hidden
:class: hidden-section
.. currentmodule:: lightning_app.core
@@ -10,4 +8,3 @@ LightningFlow
.. autoclass:: LightningFlow
:members:
- :noindex:
diff --git a/docs/source-app/api_reference/api/lightning_app.core.LightningWork.rst b/docs/source-app/api_reference/api/lightning_app.core.LightningWork.rst
index db80b79e41d8b..77965e2146757 100644
--- a/docs/source-app/api_reference/api/lightning_app.core.LightningWork.rst
+++ b/docs/source-app/api_reference/api/lightning_app.core.LightningWork.rst
@@ -1,6 +1,4 @@
-:orphan:
-
-.. role:: hidden
+.. role:: hidden
:class: hidden-section
.. currentmodule:: lightning_app.core
@@ -10,4 +8,3 @@ LightningWork
.. autoclass:: LightningWork
:members:
- :noindex:
diff --git a/docs/source-app/api_reference/components.rst b/docs/source-app/api_reference/components.rst
index c5f99f0f96629..828a78ea89db1 100644
--- a/docs/source-app/api_reference/components.rst
+++ b/docs/source-app/api_reference/components.rst
@@ -1,5 +1,5 @@
########################
-lightning_app.components
+lightning.app.components
########################
.. contents::
diff --git a/docs/source-app/api_reference/core.rst b/docs/source-app/api_reference/core.rst
index 3f6863ca8a244..10a23f8c71f49 100644
--- a/docs/source-app/api_reference/core.rst
+++ b/docs/source-app/api_reference/core.rst
@@ -1,7 +1,7 @@
:orphan:
##################
-lightning_app.core
+lightning.app.core
##################
.. contents::
diff --git a/docs/source-app/api_reference/frontend.rst b/docs/source-app/api_reference/frontend.rst
index f5e57516bcbe0..7e3ff74c7f097 100644
--- a/docs/source-app/api_reference/frontend.rst
+++ b/docs/source-app/api_reference/frontend.rst
@@ -1,5 +1,5 @@
######################
-lightning_app.frontend
+lightning.app.frontend
######################
.. contents::
diff --git a/docs/source-app/api_reference/runners.rst b/docs/source-app/api_reference/runners.rst
index 3e7eb614af13e..3040d3adde36c 100644
--- a/docs/source-app/api_reference/runners.rst
+++ b/docs/source-app/api_reference/runners.rst
@@ -1,5 +1,5 @@
#####################
-lightning_app.runners
+lightning.app.runners
#####################
.. contents::
diff --git a/docs/source-app/api_reference/storage.rst b/docs/source-app/api_reference/storage.rst
index f59653e96d708..5bcdb0973dad6 100644
--- a/docs/source-app/api_reference/storage.rst
+++ b/docs/source-app/api_reference/storage.rst
@@ -1,5 +1,5 @@
#####################
-lightning_app.storage
+lightning.app.storage
#####################
Lightning Core
diff --git a/docs/source-app/cloud/customize_a_lightning_cluster.rst b/docs/source-app/cloud/customize_a_lightning_cluster.rst
new file mode 100644
index 0000000000000..6a2f12a57bbd6
--- /dev/null
+++ b/docs/source-app/cloud/customize_a_lightning_cluster.rst
@@ -0,0 +1,13 @@
+*********************************
+Take full control of your cluster
+*********************************
+If you are an experienced user, we can enable you to fully own your cluster
+configuration using terraform directly. Please email support@lightning.ai for more information.
+
+----
+
+**************************************
+Get help building an optimized cluster
+**************************************
+For enterprise and academic use-cases, we offer tailored cluster set up in case you don't
+have experts in-house. Email support@lightning.ai.
diff --git a/docs/source-app/conf.py b/docs/source-app/conf.py
index 62bd18a900417..75777f6dd3ab1 100644
--- a/docs/source-app/conf.py
+++ b/docs/source-app/conf.py
@@ -16,7 +16,7 @@
import shutil
import sys
-import pt_lightning_sphinx_theme
+import lai_sphinx_theme
import lightning_app
@@ -79,6 +79,7 @@
# 'sphinxcontrib.fulltoc', # breaks pytorch-theme with unexpected kw argument 'titles_only'
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
+ "sphinx_toolbox.collapse",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.linkcode",
@@ -93,7 +94,7 @@
"sphinx_paramlinks",
"sphinx_togglebutton",
"sphinx.ext.githubpages",
- "pt_lightning_sphinx_theme.extensions.lightning",
+ "lai_sphinx_theme.extensions.lightning",
]
# Add any paths that contain templates here, relative to this directory.
@@ -138,6 +139,7 @@
"PULL_REQUEST_TEMPLATE.md",
"**/README.md/*",
"readme.md",
+ "_templates",
"code_samples/convert_pl_to_app/requirements.txt",
]
@@ -149,8 +151,8 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = "pt_lightning_sphinx_theme"
-html_theme_path = [pt_lightning_sphinx_theme.get_html_theme_path()]
+html_theme = "lai_sphinx_theme"
+html_theme_path = [os.environ.get('LIT_SPHINX_PATH', lai_sphinx_theme.get_html_theme_path())]
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
diff --git a/docs/source-app/core_api/lightning_app/index.rst b/docs/source-app/core_api/lightning_app/index.rst
index eeae294adc741..bf0430f3bee5b 100644
--- a/docs/source-app/core_api/lightning_app/index.rst
+++ b/docs/source-app/core_api/lightning_app/index.rst
@@ -3,6 +3,8 @@ Lightning App
#############
**Audience:** Users who want to know how an app works under the hood 🤯.
+**Lightning App:** We call workflows composed of multiple LightningWorks a **Lightning App**.
+
----
*******************
diff --git a/docs/source-app/examples/dag/dag.rst b/docs/source-app/examples/dag/dag.rst
index f5eae0d4aa1d3..fb7af2c945fd2 100644
--- a/docs/source-app/examples/dag/dag.rst
+++ b/docs/source-app/examples/dag/dag.rst
@@ -1,3 +1,5 @@
+:orphan:
+
######################################
Develop a Directed Acyclic Graph (DAG)
######################################
diff --git a/docs/source-app/examples/file_server/app.py b/docs/source-app/examples/file_server/app.py
index e36040f1b8662..cfc72a70b3f8a 100644
--- a/docs/source-app/examples/file_server/app.py
+++ b/docs/source-app/examples/file_server/app.py
@@ -157,9 +157,9 @@ def alive(self):
return self.url != ""
-import requests # noqa: E402
+import requests
-from lightning import LightningWork # noqa: E402
+from lightning import LightningWork
class TestFileServer(LightningWork):
@@ -184,7 +184,7 @@ def run(self, file_server_url: str, first=True):
assert response.json() == {"asset_names": ["test.txt"]}
-from lightning import LightningApp, LightningFlow # noqa: E402
+from lightning import LightningApp, LightningFlow
class Flow(LightningFlow):
@@ -218,7 +218,7 @@ def configure_layout(self):
return {"name": "File Server", "content": self.file_server}
-from lightning.app.runners import MultiProcessRuntime # noqa: E402
+from lightning.app.runners import MultiProcessRuntime
def test_file_server():
@@ -226,7 +226,7 @@ def test_file_server():
MultiProcessRuntime(app).dispatch()
-from lightning.app.testing import run_app_in_cloud # noqa: E402
+from lightning.app.testing import run_app_in_cloud
def test_file_server_in_cloud():
diff --git a/docs/source-app/examples/file_server/file_server.rst b/docs/source-app/examples/file_server/file_server.rst
index ab854c17e450e..f9f800a085bb8 100644
--- a/docs/source-app/examples/file_server/file_server.rst
+++ b/docs/source-app/examples/file_server/file_server.rst
@@ -1,3 +1,4 @@
+:orphan:
.. _fileserver_example:
diff --git a/docs/source-app/examples/github_repo_runner/github_repo_runner.rst b/docs/source-app/examples/github_repo_runner/github_repo_runner.rst
index cd420f5c5db27..02064ca4b9b5f 100644
--- a/docs/source-app/examples/github_repo_runner/github_repo_runner.rst
+++ b/docs/source-app/examples/github_repo_runner/github_repo_runner.rst
@@ -1,3 +1,5 @@
+:orphan:
+
.. _github_repo_script_runner_example:
###################################
diff --git a/docs/source-app/examples/index.rst b/docs/source-app/examples/index.rst
new file mode 100644
index 0000000000000..bb7e645da446e
--- /dev/null
+++ b/docs/source-app/examples/index.rst
@@ -0,0 +1,36 @@
+########
+Examples
+########
+
+.. raw:: html
+
+
+
+
+.. displayitem::
+ :header: Develop a DAG workflow
+ :description: Develop sequential, non-reactive workflows
+ :col_css: col-md-4
+ :button_link: dag/dag.html
+ :height: 150
+
+.. displayitem::
+ :header: Develop a File Server
+ :description: Develop a file server
+ :col_css: col-md-4
+ :button_link: file_server/file_server.html
+ :height: 150
+
+.. displayitem::
+ :header: Develop a Github Repo Script Runner
+ :description: Build an app to run a Github repo
+ :col_css: col-md-4
+ :button_link: github_repo_runner/github_repo_runner.html
+ :height: 150
+
+.. displayitem::
+ :header: Deploy a model
+ :description: Learn how to deploy a model
+ :col_css: col-md-4
+ :button_link: model_server_app/model_server_app.html
+ :height: 150
diff --git a/docs/source-app/get_started/go_beyond_training_content.rst b/docs/source-app/get_started/go_beyond_training_content.rst
index c8baeb8fab77b..5ee47eb219fe5 100644
--- a/docs/source-app/get_started/go_beyond_training_content.rst
+++ b/docs/source-app/get_started/go_beyond_training_content.rst
@@ -30,7 +30,7 @@ You must do so in every new shell.
.. tip:: We highly recommend using virtual environments.
-.. code:: python
+.. code:: bash
pip install lightning
diff --git a/docs/source-app/get_started/lightning_apps_intro.rst b/docs/source-app/get_started/lightning_apps_intro.rst
deleted file mode 100644
index bcbc9d8dbf44e..0000000000000
--- a/docs/source-app/get_started/lightning_apps_intro.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-############################
-Lightning Apps in 15 minutes
-############################
-
-**Required background:** Basic Python familiarity.
-
-**Goal:** Guide you to develop your first Lightning App or use an existing App from the `Apps Gallery
`_.
-
-.. join_slack::
- :align: left
-
-----
-
-.. include:: go_beyond_training_content.rst
diff --git a/docs/source-app/glossary/app_tree.rst b/docs/source-app/glossary/app_tree.rst
index 9b16acda0a1af..7b5677a501881 100644
--- a/docs/source-app/glossary/app_tree.rst
+++ b/docs/source-app/glossary/app_tree.rst
@@ -1,3 +1,5 @@
+:orphan:
+
.. _app_component_tree:
###################
diff --git a/docs/source-app/glossary/aws_arn.rst b/docs/source-app/glossary/aws_arn.rst
new file mode 100644
index 0000000000000..fc136b557a6f6
--- /dev/null
+++ b/docs/source-app/glossary/aws_arn.rst
@@ -0,0 +1,83 @@
+:orphan:
+
+.. _aws_arn:
+
+#######
+AWS ARN
+#######
+
+**Audience:** Users who want to run on their AWS account
+
+**Level:** Intermediate
+
+----
+
+*******************
+What is an AWS ARN?
+*******************
+An AWS Amazon Resource Name (ARN) are unique identifiers of Amazon resources (datasets, buckets, machines, clusters) with
+customized access controls.
+
+----
+
+*************
+Create an ARN
+*************
+To create an ARN, first install the AWS CLI
+
+.. code:: bash
+
+ # Linux
+ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
+ unzip awscliv2.zip
+ sudo ./aws/install
+
+ # MAC
+ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
+ sudo installer -pkg AWSCLIV2.pkg -target /
+
+ # WINDOWS
+ msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
+
+Or `follow the AWS guide `_.
+
+Then enter the following commands:
+
+.. code:: bash
+
+ # TODO
+
+----
+
+***********************
+Run on your AWS account
+***********************
+To run on your own AWS account, set up a Lightning cluster (here we name it pikachu):
+
+.. code:: bash
+
+ lightning create cluster pikachu --provider aws --role-arn arn:aws:iam::1234567890:role/lai-byoc --external-id dummy --region us-west-2
+
+Run your code on the pikachu cluster by passing it into CloudCompute:
+
+.. code:: python
+
+ # app.py
+ import lightning as L
+
+ class LitWorker(L.LightningWork):
+ def run(self):
+ message = """
+ ANY python code can run here such as:
+ - train a model
+ - launch a deployment server
+ - label data
+ - run a react app, dash app, streamlit app, etc...
+ - start a jupyter notebook
+ - subprocess.Popen('echo run any shell script, python scripts or non python files')
+ """
+ print(message)
+
+ # uses 1 cloud GPU (or your own hardware)
+ compute = L.CloudCompute('gpu', clusters=['pikachu'])
+ app = L.LightningApp(LitWorker(cloud_compute=compute))
diff --git a/docs/source-app/glossary/build_config/build_config.rst b/docs/source-app/glossary/build_config/build_config.rst
index 8ecd2e4df665a..43ba0b02e2bcf 100644
--- a/docs/source-app/glossary/build_config/build_config.rst
+++ b/docs/source-app/glossary/build_config/build_config.rst
@@ -1,3 +1,5 @@
+:orphan:
+
.. _build_config:
###################
diff --git a/docs/source-app/glossary/index.rst b/docs/source-app/glossary/index.rst
index 8d32358be7984..9652106e2aad1 100644
--- a/docs/source-app/glossary/index.rst
+++ b/docs/source-app/glossary/index.rst
@@ -1,4 +1,23 @@
-:orphan:
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ ios_and_android
+ app_tree
+ aws_arn
+ build_config/build_config
+ command_lines/command_lines
+ dag
+ event_loop
+ environment_variables
+ secrets
+ front ends <../workflows/add_web_ui/glossary_front_end>
+ Lightning app <../core_api/lightning_app/index>
+ sharing_components
+ scheduling
+ storage/storage
+ restful_api/restful_api
+ add web ui <../workflows/add_web_ui/glossary_ui>
########
Glossary
@@ -9,72 +28,121 @@ Glossary
+.. displayitem::
+ :header: Android Lightning App
+ :description: Use Lightning with android apps.
+ :col_css: col-md-12
+ :button_link: ios_and_android.html
+ :height: 100
+
.. displayitem::
:header: App Components Tree
:description: Learn how components can be nested to form component trees where the LightningFlows are its branches and LightningWorks are its leaves.
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: app_tree.html
- :height: 180
+ :height: 100
+
+.. displayitem::
+ :header: AWS ARN
+ :description: Create an AWS ARN
+ :col_css: col-md-12
+ :button_link: aws_arn.html
+ :height: 100
.. displayitem::
:header: Build Configuration
:description: Prepare your requirements, add custom build commands or use docker image
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: build_config/build_config.html
- :height: 180
+ :height: 100
+
+.. displayitem::
+ :header: Command Line Interface (CLI)
+ :description: Learn about the Lightning CLI
+ :col_css: col-md-12
+ :button_link: command_lines/command_lines.html
+ :height: 100
.. displayitem::
:header: DAG
:description: Learn about directed acyclic graph, their properties and usage
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: dag.html
- :height: 180
+ :height: 100
.. displayitem::
:header: Event Loop
:description: Learn how the Infinite Event Loop enables high distributed reactivity by triggering after collecting state changes.
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: event_loop.html
- :height: 180
+ :height: 100
.. displayitem::
:header: Environment Variables
:description: Add secrets such as API keys or access tokens
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: environment_variables.html
- :height: 180
+ :height: 100
+
+.. displayitem::
+ :header: Encrypted Secrets
+ :description: Learn how to add passwords to your Lightning apps
+ :col_css: col-md-12
+ :button_link: secrets.html
+ :height: 100
.. displayitem::
:header: Frontend
:description: Customize your App View with any framework you want
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: ../workflows/add_web_ui/glossary_front_end.html
- :height: 180
+ :height: 100
+
+.. displayitem::
+ :header: iOS Lightning App
+ :description: Use Lightning with iOS apps.
+ :col_css: col-md-12
+ :button_link: ios_and_android.html
+ :height: 100
+
+.. displayitem::
+ :header: Lightning App
+ :description: A Lightning app is a collection of connected components that form a workflow
+ :col_css: col-md-12
+ :button_link: ../core_api/lightning_app/index.html
+ :height: 100
.. displayitem::
:header: Sharing Components
:description: Let's create an ecosystem altogether
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: sharing_components.html
- :height: 180
+ :height: 100
.. displayitem::
:header: Scheduling
:description: Orchestrate execution at specific times
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: scheduling.html
- :height: 180
+ :height: 100
.. displayitem::
:header: Storage
:description: Easily share files even across multiple machines
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: storage/storage.html
- :height: 180
+ :height: 100
+
+.. displayitem::
+ :header: REST API
+ :description: Learn how to set up a RESTful API endpoint
+ :col_css: col-md-12
+ :button_link: restful_api/restful_api.html
+ :height: 100
.. displayitem::
:header: UI
:description: Combine multiple frameworks to create your own UI
- :col_css: col-md-6
+ :col_css: col-md-12
:button_link: ../workflows/add_web_ui/glossary_ui.html
- :height: 180
+ :height: 100
diff --git a/docs/source-app/index.rst b/docs/source-app/index.rst
index 3e635ddac4b6d..aa67dff1b4f33 100644
--- a/docs/source-app/index.rst
+++ b/docs/source-app/index.rst
@@ -3,74 +3,51 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-############################
-Welcome to âš¡ Lightning Apps
-############################
-
-.. twocolumns::
- :left:
- .. image:: https://pl-flash-data.s3.amazonaws.com/assets_lightning/Lightning.gif
- :alt: Animation showing how to convert a standard training loop to a Lightning loop
- :right:
- The `open-source Lightning framework
`_ gives ML Researchers and Data Scientists, the fastest & most flexible
- way to iterate on ML research ideas and deliver scalable ML systems with the performance enterprises requires at the same time.
+#######################
+Welcome to âš¡ Lightning
+#######################
+Build models and full stack AI apps âš¡ *Lightning fast*.
.. join_slack::
- :align: center
- :margin: 0
+ :align: left
-----
-
-*****************
-Install Lightning
-*****************
-
-.. code-block:: bash
-
- pip install -U lightning
-
-
-Or read the :ref:`advanced install ` guide.
+**Featured examples of what you can build with Lightning:**
-----
-
-***********
-Get Started
-***********
+|
.. raw:: html
-
-
-
-
-.. displayitem::
- :header: Discover what Lightning Apps can do in 5 min
- :description: Browse through mind-blowing ML Systems
- :col_css: col-md-6
- :button_link: get_started/what_app_can_do.html
- :height: 180
-
-.. displayitem::
- :header: Build and Train a Model
- :description: Discover PyTorch Lightning and train your first Model.
- :col_css: col-md-6
- :button_link: get_started/build_model.html
- :height: 180
-
-.. displayitem::
- :header: Evolve a Model into an ML System
- :description: Develop an App to train a model in the cloud
- :col_css: col-md-6
- :button_link: get_started/training_with_apps.html
- :height: 180
-
-.. displayitem::
- :header: Start from an ML system template
- :description: Learn about Apps, from a template.
- :col_css: col-md-6
- :button_link: get_started/go_beyond_training.html
- :height: 180
+
+
+
+.. app_card::
+ :title: Develop and Train
+ :description: Train an LLM (512 GPUs)
+ :width: 280
+ :image: https://lightning-ai-docs.s3.amazonaws.com/develop_n_train_v1.jpg
+ :preview: https://lightning.ai
+ :deploy: https://lightning.ai
+ :target: https://apple.com
+ :tags: Model
+
+.. app_card::
+ :title: Serve and deploy
+ :description: Production-ready stable diffusion server (<2s latency)
+ :width: 280
+ :image: https://lightning-ai-docs.s3.amazonaws.com/serve_n_deploy_v1.jpg
+ :preview: https://lightning.ai
+ :deploy: https://lightning.ai
+ :target: https://apple.com
+ :tags: App
+
+.. app_card::
+ :title: Scale and build a product
+ :description: Production-ready generative AI app
+ :width: 280
+ :app_id: HvUwbEG90E
+ :image: https://lightning-ai-docs.s3.amazonaws.com/scale_n_build_v1.jpg
+ :target: https://lightning.ai/muse
+ :tags: App
.. raw:: html
@@ -79,97 +56,72 @@ Get Started
----
-***********************
-Current Lightning Users
-***********************
+************************
+Build modular components
+************************
.. raw:: html
-
-
-Build with Template(s) from the App & Component Gallery
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+
.. raw:: html
-
-
+
+
+
+ Build modular, self-contained components that can train and deploy models, host a web UI or run arbitrary code on the cloud.
+ A Lightning Component manages its own infrastructure, cloud costs, networking and more, so you can focus on application logic and not engineering.
-.. displayitem::
- :header: Start from Ready-to-Run Template Apps
- :description: Jump-start your project's development
- :col_css: col-md-6
- :button_link: get_started/jumpstart_from_app_gallery.html
- :height: 180
+
+ Combine your components and prebuilt ones from our gallery
+ to create full-stack AI apps, âš¡ Lightning fast.
+
+
+
-.. displayitem::
- :header: Add Component made by others to your App
- :description: Add more functionalities to your projects
- :col_css: col-md-6
- :button_link: get_started/jumpstart_from_component_gallery.html
- :height: 180
+.. lit_tabs::
+ :code_files: landing_app.py;
+ :highlights: 6
+ :app_id: abc123
+ :height: 250px
+ :code_only: True
+
+.. lit_tabs::
+ :code_files: landing_app_run.bash
+ :highlights: 5
+ :height: 150px
+ :code_only: True
+|
.. raw:: html
-
-
-Keep Learning
-^^^^^^^^^^^^^
+|
.. raw:: html
-
-
+
+
-.. displayitem::
- :header: Level-up with PyTorch Lightning
- :description: PyTorch Lightning Tutorials
- :col_css: col-md-6
- :button_link: https://pytorch-lightning.readthedocs.io/en/latest/expertise_levels.html
- :height: 180
+.. Add callout items below this line
.. displayitem::
- :header: Level-up with Lightning Apps
- :description: From Basics to Advanced Skills
- :col_css: col-md-6
+ :header: Get started
+ :description: Learn to go from Lightning components to full stack AI apps step-by-step.
+ :col_css: col-md-12
:button_link: levels/basic/index.html
- :height: 180
-
-.. displayitem::
- :header: API Reference
- :description: Detailed description of each API package
- :col_css: col-md-6
- :button_link: api_references.html
- :height: 180
-
-.. displayitem::
- :header: Hands-on Examples
- :description: Learn by building Apps and Components.
- :col_css: col-md-6
- :button_link: examples/hands_on_example.html
- :height: 180
-
-.. displayitem::
- :header: Common Workflows
- :description: Learn how to do ...
- :col_css: col-md-6
- :button_link: workflows/index.html
- :height: 180
-
-.. displayitem::
- :header: Glossary
- :description: Discover Lightning App Concepts
- :col_css: col-md-6
- :button_link: glossary/index.html
- :height: 180
+ :height: 160
+ :tag: 10 minutes
.. raw:: html
-
+
+
.. raw:: html
@@ -179,71 +131,17 @@ Keep Learning
:maxdepth: 1
:caption: Home
+ Install
self
.. toctree::
:maxdepth: 1
- :caption: Get Started
-
- installation
- get_started/lightning_apps_intro
-
-.. toctree::
- :maxdepth: 1
- :caption: App Building Skills
+ :caption: Get started in steps
Basic
Intermediate
Advanced
-.. toctree::
- :maxdepth: 1
- :caption: Examples
-
- Develop a DAG
- Develop a File Server
- Develop a Github Repo Script Runner
- Develop a Model Server
-
-..
- [Docs under construction] Build a data exploring app
- [Docs under construction] Build a ETL app
- [Docs under construction] Build a model deployment app
- [Docs under construction] Build a research demo app
-
-.. toctree::
- :maxdepth: 1
- :caption: How to...
-
- Access the App State
- Add a web user interface (UI)
- Add a web link
- Add encrypted secrets
- Arrange app tabs
- Develop a Command Line Interface (CLI)
- Develop a Lightning App
- Develop a Lightning Component
- Develop a REST API
- Cache Work run calls
- Customize your cloud compute
- Extend an existing app
- Publish a Lightning component
- Run a server within a Lightning App
- Run an App on the cloud
- Run Apps on your cloud account (BYOC)
- Run work in parallel
- Save files
- Share an app
- Share files between components
-
-..
- [Docs under construction] Add a Lightning component
- [Docs under construction] Debug a distributed cloud app locally
- [Docs under construction] Enable fault tolerance
- [Docs under construction] Run components on different hardware
- [Docs under construction] Schedule app runs
- [Docs under construction] Test an app
-
.. toctree::
:maxdepth: 1
:caption: Core API Reference
@@ -263,25 +161,10 @@ Keep Learning
.. toctree::
:maxdepth: 1
- :caption: Glossary
-
- App Components Tree
- Build Configuration
- Command Line Interface (CLI)
- DAG
- Event Loop
- Environment Variables
- Encrypted Secrets
- Frontend
- Apple and Android mobile devices with Lighting Apps
- REST API
- Sharing Components
- Scheduling
- Storage
- UI
-
-..
- [Docs under construction] Debug an app
- [Docs under construction] Distributed front-ends
- [Docs under construction] Distributed hardware
- [Docs under construction] Fault tolerance
+ :caption: More
+
+ Start from component templates
+ Start from app templates
+ Examples
+ Glossary
+ How to...
diff --git a/docs/source-app/install_beginner.rst b/docs/source-app/install/install_beginner.rst
similarity index 90%
rename from docs/source-app/install_beginner.rst
rename to docs/source-app/install/install_beginner.rst
index 3ae423a71ccd6..f690ef74e7d2f 100644
--- a/docs/source-app/install_beginner.rst
+++ b/docs/source-app/install/install_beginner.rst
@@ -2,14 +2,9 @@
.. _install_beginner:
-#######################
-Installation (Beginner)
-#######################
-
-To develop and run Lightning apps, we recommend to set up a virtual environment.
-
-**What is a virtual environment?**
-
+#############################
+What is a virtual environment
+#############################
A virtual environment keeps the packages you install isolated from the rest of your system.
This allows you to work on multiple projects that have different and potentially conflicting requirements, and it
keeps your system Python installation clean.
@@ -72,7 +67,7 @@ Before you can install packages into the environment, you need to activate it:
You need to do this step every time you want to work on your project / open the terminal.
With your virtual environment activated, you are now ready to
-:doc:`install Lightning <../installation>` and get started with Apps!
+:doc:`install Lightning ` and get started with Apps!
----
@@ -119,4 +114,4 @@ Before you can install packages into the environment, you need to activate it:
You need to do this step every time you want to work on your project / open the terminal.
With your virtual environment activated, you are now ready to
-:doc:`install Lightning <../installation>` and get started with Apps!
+:doc:`install Lightning ` and get started with Apps!
diff --git a/docs/source-app/install/installation.rst b/docs/source-app/install/installation.rst
new file mode 100644
index 0000000000000..ed7dbc67afa65
--- /dev/null
+++ b/docs/source-app/install/installation.rst
@@ -0,0 +1,29 @@
+
+.. _install:
+
+
+############
+Installation
+############
+
+**Prerequisites**: Use Python 3.8.x or later (3.8.x, 3.9.x, 3.10.x). We also recommend you install in a virtual environment (`learn how `_).
+
+.. lit_tabs::
+ :descriptions: Pip; Macs, Apple Silicon (M1/M2/M3); Windows
+ :code_files: pip.bash; mac.bash; windows.bash
+ :tab_rows: 4
+ :height: 180px
+
+----
+
+************
+Troubleshoot
+************
+If you encounter issues during installation join our community slack and share the output of the following command:
+
+.. code:: bash
+
+ pip list | grep lightning
+
+.. join_slack::
+ :align: left
diff --git a/docs/source-app/install/mac.bash b/docs/source-app/install/mac.bash
new file mode 100644
index 0000000000000..c8877f948bc64
--- /dev/null
+++ b/docs/source-app/install/mac.bash
@@ -0,0 +1,5 @@
+# needed for M1/M2/M3
+export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
+export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
+
+python -m pip install -U lightning
diff --git a/docs/source-app/install/pip.bash b/docs/source-app/install/pip.bash
new file mode 100644
index 0000000000000..1fe569674aa6e
--- /dev/null
+++ b/docs/source-app/install/pip.bash
@@ -0,0 +1 @@
+python -m pip install -U lightning
diff --git a/docs/source-app/install/windows.bash b/docs/source-app/install/windows.bash
new file mode 100644
index 0000000000000..150b04e5b4d5d
--- /dev/null
+++ b/docs/source-app/install/windows.bash
@@ -0,0 +1,4 @@
+# install pip
+# install git
+# setup an alias for Python: python=python3
+# Add the root folder of Lightning to the Environment Variables to PATH
diff --git a/docs/source-app/installation.rst b/docs/source-app/installation.rst
deleted file mode 100644
index 61a8cf9ce73ca..0000000000000
--- a/docs/source-app/installation.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-
-.. _install:
-
-
-############
-Installation
-############
-
-We strongly recommend to create a virtual environment first.
-Don't know what this is? Follow our `beginner guide here `_.
-
-**Requirements**
-
-* Python 3.8.x or later (3.8.x, 3.9.x, 3.10.x)
-
-Or read the `Apple Silicon Macs installation article `_ or the `Windows installation article `_.
-
-----
-
-****************
-Install with pip
-****************
-
-0. Activate your virtual environment.
-
-1. Install the ``lightning`` package
-
- .. code:: bash
-
- pip install -U lightning
-
-.. note::
-
- If you encounter issues during installation use the following to help troubleshoot:
-
- .. code:: bash
-
- pip list | grep lightning
diff --git a/docs/source-app/installation_mac.rst b/docs/source-app/installation_mac.rst
deleted file mode 100644
index f5dd13bd0a444..0000000000000
--- a/docs/source-app/installation_mac.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-:orphan:
-
-##################################
-Installation on Apple Silicon Macs
-##################################
-
-Apple Silicon (M1, M2, M3) Mac environments need a bit of tweaking before you install.
-
-----
-
-****************
-Install with pip
-****************
-
-Install the ``lightning`` package
-
- .. code:: bash
-
- export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
- export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
-
- pip install -U lightning
diff --git a/docs/source-app/installation_win.rst b/docs/source-app/installation_win.rst
deleted file mode 100644
index a3c548840e21a..0000000000000
--- a/docs/source-app/installation_win.rst
+++ /dev/null
@@ -1,34 +0,0 @@
-:orphan:
-
-#######################
-Installation on Windows
-#######################
-
-We strongly recommend to create a virtual environment first.
-Don't know what this is? Follow our `beginner guide here `_.
-
-Windows environments might need a little more tweaking before you install.
-
-**Requirements**
-
-* Python 3.8.x or later (3.8.x, 3.9.x, 3.10.x)
-* Pip (the latest versions of Python will already have this)
-* Git
-* PyTorch - https://pytorch.org/get-started/locally/
-* Setup an alias for Python: python=python3
-* Add the root folder of Lightning to the Environment Variables to PATH
-* Install Z shell (zsh) (This is required for Windows to install the quickstart app)
-
-----
-
-****************
-Install with pip
-****************
-
-0. Activate your virtual environment.
-
-1. Install the ``lightning`` package
-
- .. code:: bash
-
- pip install -U lightning
diff --git a/docs/source-app/landing_app.py b/docs/source-app/landing_app.py
new file mode 100644
index 0000000000000..d4f4ed8e9a714
--- /dev/null
+++ b/docs/source-app/landing_app.py
@@ -0,0 +1,12 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# run on a cloud machine ("cpu", "gpu", ...)
+component = YourComponent(cloud_compute=L.CloudCompute("cpu"))
+app = L.LightningApp(component)
diff --git a/docs/source-app/landing_app_run.bash b/docs/source-app/landing_app_run.bash
new file mode 100644
index 0000000000000..ce52902d1c5fd
--- /dev/null
+++ b/docs/source-app/landing_app_run.bash
@@ -0,0 +1,5 @@
+# install lightning
+pip install lightning
+
+# run the app
+lightning run app app.py --cloud
diff --git a/docs/source-app/levels/advanced/index.rst b/docs/source-app/levels/advanced/index.rst
index 265a8ce961690..33bd7bc62d575 100644
--- a/docs/source-app/levels/advanced/index.rst
+++ b/docs/source-app/levels/advanced/index.rst
@@ -13,8 +13,7 @@
###############
Advanced skills
###############
-
-Learn to build Lightning Apps for enterprise workloads or advanced research.
+Learn to manage LightningWorks efficiently.
.. join_slack::
:align: left
@@ -29,41 +28,49 @@ Learn to build Lightning Apps for enterprise workloads or advanced research.
.. Add callout items below this line
.. displayitem::
- :header: Level 16: Check work status
- :description: Learn to use work status to coordinate complex apps.
- :button_link: level_16.html
+ :header: Level: Nest flows
+ :description: Learn to nest flows into other flows.
+ :button_link: level_14.html
:col_css: col-md-6
:height: 150
- :tag: advanced
+ :tag: intermediate
+
+.. displayitem::
+ :header: Level: Develop reactive apps.
+ :description: Learn to develop reactive Lightning Apps. Lightning shines with reactive workflows.
+ :button_link: level_14.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: intermediate
.. displayitem::
- :header: Level 17: Cache calls into run
- :description: Learn about caching calls in work.run.
+ :header: Level: Enable CLI commands for your app
+ :description: Speak to your app from a CLI over the network
:button_link: level_17.html
:col_css: col-md-6
:height: 150
:tag: advanced
.. displayitem::
- :header: Level 18: Share objects between works
- :description: Learn to build things like DAGs where values return from Work.
- :button_link: level_18.html
+ :header: Level 11: Connect two components over the network
+ :description: Connect two LightningWorks over the network.
+ :button_link: level_14.html
:col_css: col-md-6
:height: 150
- :tag: advanced
+ :tag: intermediate
.. displayitem::
- :header: Level 19: Handle Lightning App exceptions
- :description: Learn to handle Lightning App exceptions.
- :button_link: level_19.html
+ :header: Level 13: Rerun components
+ :description: Learn to reuse components by passing different variables.
+ :button_link: level_17.html
:col_css: col-md-6
:height: 150
:tag: advanced
.. displayitem::
- :header: Level 20: Enable dynamic Works
- :description: Learn to enable dynamic works for complex systems.
- :button_link: level_20.html
+ :header: Level 14: Handle Lightning App exceptions
+ :description: Learn to handle Lightning App exceptions.
+ :button_link: level_19.html
:col_css: col-md-6
:height: 150
:tag: advanced
diff --git a/docs/source-app/levels/advanced/level_17.rst b/docs/source-app/levels/advanced/level_17.rst
index 7bc8dda7036cc..7f0f505410644 100644
--- a/docs/source-app/levels/advanced/level_17.rst
+++ b/docs/source-app/levels/advanced/level_17.rst
@@ -1,6 +1,6 @@
-##############################
-Level 17: Cache calls into run
-##############################
+##########################
+Level 17: Rerun components
+##########################
**Audience:** Users who want Work.run() to activate multiple times in an app.
**Prereqs:** Level 16+ and read the `Event Loop guide <../glossary/event_loop.html>`_.
diff --git a/docs/source-app/levels/basic/basic_examples.rst b/docs/source-app/levels/basic/basic_examples.rst
new file mode 100644
index 0000000000000..7c7e0b3183bb3
--- /dev/null
+++ b/docs/source-app/levels/basic/basic_examples.rst
@@ -0,0 +1,39 @@
+.. raw:: html
+
+
+
+
+.. app_card::
+ :title: TODO: Name 1
+ :description: Train an LLM (512 GPUs)
+ :width: 280
+ :image: https://lightning-ai-docs.s3.amazonaws.com/develop_n_train_v1.jpg
+ :preview: https://lightning.ai
+ :deploy: https://lightning.ai
+ :target: https://apple.com
+ :tags: Model
+
+.. app_card::
+ :title: TODO: Name 2
+ :description: Production-ready stable diffusion server
+ :width: 280
+ :image: https://lightning-ai-docs.s3.amazonaws.com/serve_n_deploy_v1.jpg
+ :preview: https://lightning.ai
+ :deploy: https://lightning.ai
+ :target: https://apple.com
+ :tags: App
+
+.. app_card::
+ :title: TODO: Name 3
+ :description: Production-ready generative AI app
+ :width: 280
+ :image: https://lightning-ai-docs.s3.amazonaws.com/scale_n_build_v1.jpg
+ :preview: https://lightning.ai
+ :deploy: https://lightning.ai
+ :target: https://apple.com
+ :tags: App
+
+.. raw:: html
+
+
+
diff --git a/docs/source-app/levels/basic/build_a_dag.rst b/docs/source-app/levels/basic/build_a_dag.rst
new file mode 100644
index 0000000000000..d4eeae8715ce0
--- /dev/null
+++ b/docs/source-app/levels/basic/build_a_dag.rst
@@ -0,0 +1,19 @@
+###########################
+Example: Deploy a model API
+###########################
+**Audience:** TODO:
+
+**Prereqs:** You have an app already running locally.
+
+----
+
+****************************
+What is the Lightning Cloud?
+****************************
+The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
+the Lightning Cloud supports AWS.
+
+.. note:: Support for GCP and Azure is coming soon!
+
+To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
+on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
diff --git a/docs/source-app/levels/basic/build_a_lightning_component.rst b/docs/source-app/levels/basic/build_a_lightning_component.rst
new file mode 100644
index 0000000000000..82bebdccf54a5
--- /dev/null
+++ b/docs/source-app/levels/basic/build_a_lightning_component.rst
@@ -0,0 +1,196 @@
+##########################################
+Package your code in a lightning component
+##########################################
+
+**Prereqs:** You know *basic* Python.
+
+**Goal:** In this guide you'll learn to develop `a Lightning component `_.
+
+.. join_slack::
+ :align: left
+
+----
+
+*********************************
+Why you need Lightning components
+*********************************
+ML workflows and full stack AI apps require many pieces working such as training, deploying, data annotation. However, this tight coupling
+can lead to monoliths that are hard to scale or many microservices that are hard to monitor, coordinate
+and scale. A Lightning component is a self-contained piece of code (ie: a microservice) that executes your code
+and manages its own infrastructure, auto-scaling and costs for you.
+
+.. raw:: html
+
+
+
+
+
+|
+
+By using Lightning components you can focus on application logic without dealing with cloud operations
+or even how components speak to each other. Together, Lightning components form a Lightning App that
+gives you these benefits:
+
+.. collapse:: Build systems not scripts
+
+ |
+
+ The Lightning structure forces best practices so you don't have to be an expert production engineer.
+ Although it feels like you're writing a script, you are actually building a production-ready system.
+
+
+.. collapse:: Cost control
+
+ |
+
+ The component run-time has been optimized for cost management to support the largest machine-learning workloads.
+ Lower your cloud bill with machines that shut down or spin up faster.
+
+.. collapse:: For beginners: Code like an expert
+
+ |
+
+ Lightning embeds the best practices of building production-ready full stack AI apps into your
+ coding experience. You can write code like you normally do, and the Lightning structure
+ ensures your code is implicitely production ready... even if you're just doing research.
+
+
+.. collapse:: For experts: Scale with full control
+
+ |
+
+ if you know what you are doing, Lightning gives you full control to manage your own
+ scaling logic, fault-tolerance and even pre-provisioning, all from Python. We even give you
+ full flexibility to use tools like `terraform <../../cloud/customize_a_lightning_cluster.html>`_ to optimize cloud clusters for your Lightning apps.
+
+.. collapse:: Packaged code
+
+ |
+
+ Lightning apps bundles components into an app that runs in any environment. The same code will run on your laptop,
+ or any cloud or private clusters. You don't have to think about the cluster or know anything about the cloud.
+
+.. collapse:: Rapid iteration
+
+ |
+
+ Iterate through ideas in hours not months because you don't have to learn a million other concepts that the components
+ handle for you such as kubernetes, cost management, auto-scaling and more.
+
+.. collapse:: Modularity
+
+ |
+
+ Components are modular and inter-operable by design. Leverage our vibrant community of components so you don't
+ have to build each piece of the system yourself.
+
+----
+
+*****************
+Install Lightning
+*****************
+First, install Lightning.
+
+.. code:: bash
+
+ python -m pip install -U lightning
+
+.. collapse:: Mac M1/M2/M3 and Windows users
+
+ |
+
+ **Mac**
+
+ To install on Mac, set these 2 environment variables
+
+ .. code-block:: bash
+
+ # needed for M1/M2/M3
+ export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
+ export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
+
+ python -m pip install -U lightning
+
+ **Windows users**
+
+ To install on Windows:
+
+ - setup an alias for Python: python=python3
+ - Add the root folder of Lightning to the Environment Variables to PATH
+
+----
+
+**************************
+Build your first component
+**************************
+A Lightning component organizes Python code so it can run on the cloud and be connected with other components to form a Lightning App.
+Pick one of these components to run:
+
+.. lit_tabs::
+ :titles: Hello CPU world; Hello GPU (accelerated) world; Train PyTorch on a cloud GPU; Train PyTorch âš¡ on cloud GPUs; Deploy a model on cloud GPUs; Run a model script; Build a model web UI
+ :code_files: ./hello_components/hello_world.py; ./hello_components/hello_world_gpu.py; ./hello_components/train_pytorch.py; ./hello_components/train_ptl.py; ./hello_components/deploy_model.py; ./hello_components/run_script.py; ./hello_components/build_demo.py
+ :highlights: 7; 10, 11; 3, 7-23;3;4;5;6
+ :app_id: abc123
+ :tab_rows: 4
+ :height: 550px
+
+|
+
+Components run the same on the cloud and locally on your choice of hardware.
+
+.. lit_tabs::
+ :titles: Lightning Cloud (fully-managed); Your AWS account; Your own hardware
+ :code_files: ./hello_components/code_run_cloud.bash; ./hello_components/code_run_cloud_yours.bash; ./hello_components/code_run_local.bash
+ :tab_rows: 4
+ :height: 195px
+
+----
+
+************
+Key features
+************
+You now know enough to build a self-contained component that runs any Python code on the cloud that can be connected to form a
+powerful Lightning app. Here are a few key features available to super-charge your work:
+
+.. lit_tabs::
+ :titles: 15+ accelerators; Auto-stop idle machines; Auto-timeout submitted work; Use spot machines (~70% discount); Work with massive datasets; Mount cloud storage; Use a custom container
+ :code_files: ./key_features/accelerators.py; ./key_features/idle_machine.py; ./key_features/auto_timeout.py; ./key_features/spot.py; ./key_features/massive_dataset.py; ./key_features/mount_data.py; ./key_features/custom_container.py;
+ :highlights: 10;10;10;10;10;2,6,9, 10; 7
+ :app_id: abc123
+ :tab_rows: 3
+ :height: 430px
+
+----
+
+***************************
+Use the community ecosystem
+***************************
+Lightning has a vibrant collection of community-built components you can use as templates or to inspire you.
+
+
+----
+
+************************
+Next: Connect components
+************************
+Now you can build components. To build powerful full stack AI apps you'll need to learn to connect them together.
+
+.. raw:: html
+
+
+
+
+.. Add callout items below this line
+
+.. displayitem::
+ :header: Level 2: Connect components
+ :description: Learn to connect components
+ :col_css: col-md-12
+ :button_link: connect_lightning_components.html
+ :height: 150
+ :tag: beginner
+
+.. raw:: html
+
+
+
diff --git a/docs/source-app/levels/basic/connect_lightning_components.rst b/docs/source-app/levels/basic/connect_lightning_components.rst
new file mode 100644
index 0000000000000..d4c1f9d63b5a2
--- /dev/null
+++ b/docs/source-app/levels/basic/connect_lightning_components.rst
@@ -0,0 +1,100 @@
+####################################################
+Level 2: Connect components into a full stack AI app
+####################################################
+
+**Audience:** Users who want to build apps with multiple components.
+
+**Prereqs:** You know how to `build a component `_.
+
+----
+
+****************************
+What is a full stack AI app?
+****************************
+A full stack AI app coordinates 2 or more `Lightning components `_ together.
+We call this system of components interacting with each other a Lightning App.
+
+In this guide, we'll coordinate 2 components together and explain how it works.
+
+.. note:: If you've used workflow tools for Python, this page describes conventional DAGs.
+ In `level 5 <../intermediate/run_lightning_work_in_parallel.html>`_, we introduce reactive workflows that generalize beyond DAGs
+ so you can build complex systems without much effort.
+
+----
+
+***********
+The toy app
+***********
+
+In this app, we define two components that run across 2 separate machines. One to train a model on a GPU machine and one to analyze the model
+on a separate CPU machine. We save money by stopping the GPU machine when the work is done.
+
+.. lit_tabs::
+ :titles: Import Lightning; Define Component 1; Define Component 2; Orchestrator; Connect component 1; Connect component 2; Implement run; Train; Analyze; Define app placeholder
+ :descriptions: First, import Lightning; This component trains a model on a GPU machine; This component analyzes a model on a CPU machine; Define the LightningFlow that orchestrates components; Component 1 will run on a CPU machine; Component 2 will run on an accelerated GPU machine; Describe the workflow in the run method; Training runs first and completes; Analyze runs after training completes; This allows the app to be runnable
+ :code_files: ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py
+ :highlights: 2; 4-6; 8-10; 12; 15; 16; 18; 19; 20; 22
+ :app_id: abc123
+ :tab_rows: 4
+ :height: 450px
+
+|
+
+Now run the app:
+
+.. lit_tabs::
+ :titles: Run on Lightning cloud; Your own hardware
+ :descriptions: Run to see these 2 components execute on separate machines 🤯; Run it locally without code changes 🤯🤯;
+ :code_files: ./hello_components/code_run_cloud.bash; ./hello_components/code_run_local.bash
+ :tab_rows: 7
+ :height: 195px
+
+|
+
+Now you can develop distributed cloud apps on your laptop 🤯🤯🤯🤯!
+
+
+----
+
+**************************
+Now you know ...
+**************************
+
+Without going out of your way, you're now doing the following: (Hint: Click **visualize** to see an animation describing the code).
+
+.. lit_tabs::
+ :titles: Orchestration; Distributed cloud computing; Multi-machine communication; Multi-machine communication; Multi-cloud;
+ :descriptions: Define orchestration in Python with full control-flow; The two pieces of independent Python code ran on separate machines 🤯🤯; The text "GPU machine 1" was sent from the flow machine to the machine running the TrainComponent; The text "CPU machine 2" was sent from the flow machine to the machine running the AnalyzeComponent; The full Lightning app can move across clusters and clouds
+ :code_files: ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./level_2_scripts/hello_app.py; ./hello_components/multi_cloud.bash
+ :tab_rows: 4
+ :highlights: 18-20; 15-16; 19; 20; 2
+ :images: | | | |
+ :height: 450px
+
+----
+
+*********************
+Maintain full control
+*********************
+Although we've abstracted the infrastructure, you still have full control when you need it:
+
+.. lit_tabs::
+ :titles: Scheduler; Crontab syntax; Auto-scaling; Organized Python; Full terraform control;
+ :descriptions: Although you can use Python timers, we have a scheduler short-hand; You can also use full cron syntax; Code your own auto-scaling syntax (Lightning plays well with Kubernetes); *Remember* components organize ANY Python code which can even call external non-python scripts such as optimized C++ model servers ;Experts have the option to use terraform to configure Lightning clusters
+ :code_files: ./level_2_scripts/hello_app_scheduler.py; ./level_2_scripts/hello_app_cron.py; ./level_2_scripts/hello_app_auto_scale.py; ./level_2_scripts/organized_app_python.py; ./hello_components/terraform_example.bash;
+ :tab_rows: 4
+ :highlights: 22, 23; 22, 23; 20, 23, 26, 27; 8-11, 15-17; 2
+ :height: 680px
+
+----
+
+***************************
+Next step: Build a real app
+***************************
+Now that you know how to build components and connect them, pick an app to build in a
+step-by-step walkthrough.
+
+Once you feel comfortable with these examples, move to the `intermediate levels <../intermediate/index.html>`_, where we'll learn about running
+components in parallel so we can build reactive full-stack AI apps.
+
+.. include:: basic_examples.rst
diff --git a/docs/source-app/levels/basic/create_a_model_demo.rst b/docs/source-app/levels/basic/create_a_model_demo.rst
new file mode 100644
index 0000000000000..27460574b646a
--- /dev/null
+++ b/docs/source-app/levels/basic/create_a_model_demo.rst
@@ -0,0 +1,19 @@
+############################
+Example: Create a model demo
+############################
+**Audience:** TODO:
+
+**Prereqs:** You have an app already running locally.
+
+----
+
+****************************
+What is the Lightning Cloud?
+****************************
+The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
+the Lightning Cloud supports AWS.
+
+.. note:: Support for GCP and Azure is coming soon!
+
+To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
+on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
diff --git a/docs/source-app/levels/basic/deploy_ai_model_api.rst b/docs/source-app/levels/basic/deploy_ai_model_api.rst
new file mode 100644
index 0000000000000..d4eeae8715ce0
--- /dev/null
+++ b/docs/source-app/levels/basic/deploy_ai_model_api.rst
@@ -0,0 +1,19 @@
+###########################
+Example: Deploy a model API
+###########################
+**Audience:** TODO:
+
+**Prereqs:** You have an app already running locally.
+
+----
+
+****************************
+What is the Lightning Cloud?
+****************************
+The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
+the Lightning Cloud supports AWS.
+
+.. note:: Support for GCP and Azure is coming soon!
+
+To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
+on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
diff --git a/docs/source-app/levels/basic/hello_components/build_demo.py b/docs/source-app/levels/basic/hello_components/build_demo.py
new file mode 100644
index 0000000000000..75c65bad900b3
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/build_demo.py
@@ -0,0 +1,15 @@
+# A hello world component
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+
+# run on a cloud machine
+compute = L.CloudCompute("cpu")
+worker = YourComponent(cloud_compute=compute)
+app = L.LightningApp(worker)
diff --git a/docs/source-app/levels/basic/hello_components/code_run_cloud.bash b/docs/source-app/levels/basic/hello_components/code_run_cloud.bash
new file mode 100644
index 0000000000000..6594fe0ecac33
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/code_run_cloud.bash
@@ -0,0 +1 @@
+lightning run app app.py --cloud
diff --git a/docs/source-app/levels/basic/hello_components/code_run_cloud_yours.bash b/docs/source-app/levels/basic/hello_components/code_run_cloud_yours.bash
new file mode 100644
index 0000000000000..ff74f6cbaf401
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/code_run_cloud_yours.bash
@@ -0,0 +1,5 @@
+# first create a cluster (creation could take ~30 minutes)
+lightning create cluster pikachu --provider aws --role-arn arn:aws:iam::1234567890:role/lai-byoc
+
+# run on that cluster
+lightning run app app.py --cloud pikachu
diff --git a/docs/source-app/levels/basic/hello_components/code_run_local.bash b/docs/source-app/levels/basic/hello_components/code_run_local.bash
new file mode 100644
index 0000000000000..8a00b45e132ca
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/code_run_local.bash
@@ -0,0 +1 @@
+lightning run app app.py
diff --git a/docs/source-app/levels/basic/hello_components/deploy_model.py b/docs/source-app/levels/basic/hello_components/deploy_model.py
new file mode 100644
index 0000000000000..75c65bad900b3
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/deploy_model.py
@@ -0,0 +1,15 @@
+# A hello world component
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+
+# run on a cloud machine
+compute = L.CloudCompute("cpu")
+worker = YourComponent(cloud_compute=compute)
+app = L.LightningApp(worker)
diff --git a/docs/source-app/levels/basic/hello_components/hello_world.py b/docs/source-app/levels/basic/hello_components/hello_world.py
new file mode 100644
index 0000000000000..92b10638598aa
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/hello_world.py
@@ -0,0 +1,12 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+
+component = YourComponent()
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/hello_components/hello_world_gpu.py b/docs/source-app/levels/basic/hello_components/hello_world_gpu.py
new file mode 100644
index 0000000000000..aa316f93e6990
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/hello_world_gpu.py
@@ -0,0 +1,12 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+# run on a cloud machine ("cpu", "gpu", ...)
+compute = L.CloudCompute("gpu")
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/hello_components/multi_cloud.bash b/docs/source-app/levels/basic/hello_components/multi_cloud.bash
new file mode 100644
index 0000000000000..840208d8a99a5
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/multi_cloud.bash
@@ -0,0 +1,10 @@
+# run on lightning cloud (fully managed)
+lightning run app app.py --cloud
+
+# run on a cluster you created called pikachu
+lightning create cluster pikachu --provider aws --role-arn arn:aws:iam::1234567890:role/lai-byoc
+lightning run app app.py --cloud pikachu
+
+# run on a cluster you created called bolt
+lightning create cluster bolt --provider aws --role-arn arn:aws:iam::1234567890:role/lai-byoc
+lightning run app app.py --cloud bolt
diff --git a/docs/source-app/levels/basic/hello_components/run_script.py b/docs/source-app/levels/basic/hello_components/run_script.py
new file mode 100644
index 0000000000000..ac3ba777b5b19
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/run_script.py
@@ -0,0 +1,15 @@
+# EXAMPLE COMPONENT: RUN A SCRIPT
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+
+# run on a cloud machine
+compute = L.CloudCompute("cpu")
+worker = YourComponent(cloud_compute=compute)
+app = L.LightningApp(worker)
diff --git a/docs/source-app/levels/basic/hello_components/terraform_example.bash b/docs/source-app/levels/basic/hello_components/terraform_example.bash
new file mode 100644
index 0000000000000..af88ef250eb94
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/terraform_example.bash
@@ -0,0 +1,4 @@
+# TODO: show how to use terraform to create a cluster called pikachu
+
+# run the cluster
+lightning run app app.py --cloud pickachu
diff --git a/docs/source-app/levels/basic/hello_components/train_ptl.py b/docs/source-app/levels/basic/hello_components/train_ptl.py
new file mode 100644
index 0000000000000..75c65bad900b3
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/train_ptl.py
@@ -0,0 +1,15 @@
+# A hello world component
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+
+# run on a cloud machine
+compute = L.CloudCompute("cpu")
+worker = YourComponent(cloud_compute=compute)
+app = L.LightningApp(worker)
diff --git a/docs/source-app/levels/basic/hello_components/train_pytorch.py b/docs/source-app/levels/basic/hello_components/train_pytorch.py
new file mode 100644
index 0000000000000..ff322d4dcc0b0
--- /dev/null
+++ b/docs/source-app/levels/basic/hello_components/train_pytorch.py
@@ -0,0 +1,28 @@
+# app.py
+import torch
+
+import lightning as L
+
+
+class PyTorchComponent(L.LightningWork):
+ def run(self):
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
+ model = torch.nn.Sequential(torch.nn.Linear(1, 1),
+ torch.nn.ReLU(),
+ torch.nn.Linear(1, 1))
+ model.to(device)
+ criterion = torch.nn.MSELoss()
+ optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
+
+ for step in range(10000):
+ model.zero_grad()
+ x = torch.tensor([0.8]).to(device)
+ target = torch.tensor([1.0]).to(device)
+ output = model(x)
+ loss = criterion(output, target)
+ print(f'step: {step}. loss {loss}')
+ loss.backward()
+ optimizer.step()
+
+compute = L.CloudCompute('gpu')
+app = L.LightningApp(PyTorchComponent(cloud_compute=compute))
diff --git a/docs/source-app/levels/basic/index.rst b/docs/source-app/levels/basic/index.rst
index 24d34ae6795f4..dee1df7238eec 100644
--- a/docs/source-app/levels/basic/index.rst
+++ b/docs/source-app/levels/basic/index.rst
@@ -4,18 +4,20 @@
:maxdepth: 1
:hidden:
- level_1
- level_2
- level_3
- level_4
- level_5
- level_6
- level_7
+ build_a_lightning_component
+ connect_lightning_components
+ train_pytorch_on_the_cloud
+ deploy_ai_model_api
+ run_jupyter_notebook_on_the_cloud
+ create_a_model_demo
+ build_a_dag
############
Basic skills
############
-Learn the basics of running Lightning Apps and modifying existing Lightning Apps. Researchers and machine learning engineers should start here.
+Learn to package your code into Lightning components and assemble them into full stack AI Lightning apps.
+
+Every new user should start here.
.. join_slack::
:align: left
@@ -30,63 +32,32 @@ Learn the basics of running Lightning Apps and modifying existing Lightning Apps
.. Add callout items below this line
.. displayitem::
- :header: Level 1: Clone and Run
- :description: Learn how to get up and running in minutes
- :button_link: level_1.html
- :col_css: col-md-6
- :height: 150
- :tag: basic
-
-.. displayitem::
- :header: Level 2: Run Lightning Apps locally
- :description: Learn to run an Lightning Apps locally
- :button_link: level_2.html
- :col_css: col-md-6
- :height: 150
- :tag: basic
-
-.. displayitem::
- :header: Level 3: Run Lightning Apps on the cloud
- :description: Learn to run a Lightning Apps on the cloud
- :button_link: level_3.html
+ :header: Level 1: Package code in a Lightning component
+ :description: Learn to build a Lightning component which is the core building block of a full stack AI app (Lightning App).
+ :button_link: build_a_lightning_component.html
:col_css: col-md-6
- :height: 150
- :tag: basic
+ :height: 170
+ :tag: 10 minutes
.. displayitem::
- :header: Level 4: Modify existing Lightning Apps
- :description: Modify a Lightning App from the Lightning App Gallery for your use case.
- :button_link: level_4.html
+ :header: Level 2: Connect components into a full stack AI app
+ :description: Learn to connect components into a full stack AI app.
+ :button_link: connect_lightning_components.html
:col_css: col-md-6
- :height: 150
- :tag: basic
+ :height: 170
+ :tag: 15 minutes
-.. displayitem::
- :header: Level 5: Share your Lightning App
- :description: Learn how to share your Lightning App with colleagues
- :button_link: level_5.html
- :col_css: col-md-6
- :height: 150
- :tag: basic
+.. raw:: html
-.. displayitem::
- :header: Level 6: Publish your Lightning App
- :description: Learn how to submit your Lightning App to the Lightning App Gallery
- :button_link: level_6.html
- :col_css: col-md-6
- :height: 150
- :tag: basic
+
+
-.. displayitem::
- :header: Level 7: Run on your cloud account
- :description: Learn how to run a Lightning App on your own cloud account.
- :button_link: level_7.html
- :col_css: col-md-6
- :height: 150
- :tag: basic
+----
-.. raw:: html
+**************
+Basic Examples
+**************
+Once you've finished the basic levels, work through the following examples:
-
-
+.. include:: basic_examples.rst
diff --git a/docs/source-app/levels/basic/key_features/accelerators.py b/docs/source-app/levels/basic/key_features/accelerators.py
new file mode 100644
index 0000000000000..abfb4be685e9a
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/accelerators.py
@@ -0,0 +1,21 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# custom accelerators
+compute = L.CloudCompute('gpu')
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
+
+# OTHER ACCELERATORS:
+# compute = L.CloudCompute('default') # 1 CPU
+# compute = L.CloudCompute('cpu-medium') # 8 CPUs
+# compute = L.CloudCompute('gpu') # 1 T4 GPU
+# compute = L.CloudCompute('gpu-fast-multi') # 4 V100 GPU
+# compute = L.CloudCompute('p4d.24xlarge') # AWS instance name (8 A100 GPU)
+# compute = ...
diff --git a/docs/source-app/levels/basic/key_features/auto_timeout.py b/docs/source-app/levels/basic/key_features/auto_timeout.py
new file mode 100644
index 0000000000000..8d5e927e967b0
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/auto_timeout.py
@@ -0,0 +1,13 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# if the machine hasn't started after 60 seconds, cancel the work
+compute = L.CloudCompute('gpu', wait_timeout=60)
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/key_features/custom_container.py b/docs/source-app/levels/basic/key_features/custom_container.py
new file mode 100644
index 0000000000000..c1a5e619fd127
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/custom_container.py
@@ -0,0 +1,13 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# custom image (from any provider)
+config= L.BuildConfig(image="gcr.io/google-samples/hello-app:1.0")
+component = YourComponent(cloud_build_config=config)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/key_features/idle_machine.py b/docs/source-app/levels/basic/key_features/idle_machine.py
new file mode 100644
index 0000000000000..dc01572fbcfbc
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/idle_machine.py
@@ -0,0 +1,13 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# stop the machine when idle for 10 seconds
+compute = L.CloudCompute('gpu', idle_timeout=10)
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/key_features/massive_dataset.py b/docs/source-app/levels/basic/key_features/massive_dataset.py
new file mode 100644
index 0000000000000..e8673e3ee1b12
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/massive_dataset.py
@@ -0,0 +1,13 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+
+# use 100 GB of space on that machine (max size: 64 TB)
+compute = L.CloudCompute('gpu', disk_size=100)
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/key_features/mount_data.py b/docs/source-app/levels/basic/key_features/mount_data.py
new file mode 100644
index 0000000000000..c376d104ae612
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/mount_data.py
@@ -0,0 +1,14 @@
+import os
+
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ os.listdir('/foo')
+
+# mount the files on the s3 bucket under this path
+mount = L.Mount(source="s3://lightning-example-public/", mount_path="/foo")
+compute = L.CloudCompute(mounts=mount)
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/key_features/spot.py b/docs/source-app/levels/basic/key_features/spot.py
new file mode 100644
index 0000000000000..d3b0ac0beabbe
--- /dev/null
+++ b/docs/source-app/levels/basic/key_features/spot.py
@@ -0,0 +1,13 @@
+# app.py
+import lightning as L
+
+
+class YourComponent(L.LightningWork):
+ def run(self):
+ print('RUN ANY PYTHON CODE HERE')
+
+# spot machines can be turned off without notice, use for non-critical, resumable work
+# request a spot machine, after 60 seconds of waiting switch to full-price
+compute = L.CloudCompute('gpu', wait_timeout=60, spot=True)
+component = YourComponent(cloud_compute=compute)
+app = L.LightningApp(component)
diff --git a/docs/source-app/levels/basic/level_1.rst b/docs/source-app/levels/basic/level_1.rst
deleted file mode 100644
index cfb0045cfcf4f..0000000000000
--- a/docs/source-app/levels/basic/level_1.rst
+++ /dev/null
@@ -1,99 +0,0 @@
-######################
-Level 1: Clone and Run
-######################
-**Audience:** New users to the framework.
-
-**Prereqs:** None.
-
-----
-
-**********************
-Choose a Lightning App
-**********************
-The simplest way to get started with Lightning Apps, is to find a Lightning App similar to something you are trying
-to build. Simply visit `lightning.ai
`_ and find a Lightning App that is relevant to your work.
-
-If you need inspiration, check out some of these examples:
-
-.. raw:: html
-
-
-
-
-.. Add callout items below this line
-
-.. displayitem::
- :header: Lightning Sweeper
- :description: Use this Lightning App to run hyperparameter sweeps, or build your own version.
- :button_link: https://lightning.ai/app/8FOWcOVsdf-Lightning%20Sweeper
- :col_css: col-md-4
- :height: 200
- :tag: research workflows
-
-.. displayitem::
- :header: InVideo search
- :description: Use this Lightning App to see a more end-to-end production workflow which can be extended with deployment strategies and more.
- :button_link: https://lightning.ai/app/7pmQNIDxAE-InVideo%20Search
- :col_css: col-md-4
- :height: 200
- :tag: production workflows
-
-.. displayitem::
- :header: Unsplash Image Search
- :description: Example Lightning App if you want to build research demos.
- :button_link: https://lightning.ai/app/vIDPvY3YAA-Unsplash%20Image%20Search
- :col_css: col-md-4
- :height: 200
- :tag: demo workflows
-
-.. raw:: html
-
-
-
-
-----
-
-************************
-Launch the Lightning App
-************************
-The first thing you should try is to "launch" the Lightning App to see how a Lightning App works before you decide to dive into the code.
-Some Lightning Apps cannot be launched because of the way they have been constructed, or for cost reasons for the author.
-
-For example, here's the page for the `Unsplash image search app `_.
-
-When you submit a Lightning App to the Lightning App Gallery, you can decide if a Lightning App can be launched. Otherwise, users
-will have to clone & run the Lightning App to run on their accounts.
-
-----
-
-***********
-Clone & Run
-***********
-If you're happy with the Lightning App you found and want to try it out, the next action should be to **clone & run** the Lightning App.
-To **clone & run** go to the details page of that Lightning App and press **Clone & Run**.
-
-For example, try the **Clone & Run** button `for this Lightning App `_.
-
-Clone and run starts the Lightning App on your account. If cloning and running is going to cost you money, you'll get
-a prompt to verify that you want to do that.
-
-----
-
-**********************
-Open the Lightning App
-**********************
-Once the Lightning App has started, press "Launch" to see the Lightning App. You can send that link to any of your colleagues so
-they can also use the Lightning App.
-
-For example, here's the page that appears for the `Unsplash Image Search Lightning App `_.
-
-.. Warning:: Remember, that if the Lightning App performs expensive actions, such as training a model, and you share with people,
- they might accidentally incur costs on your account. Make sure this is what you are expecting.
-
-----
-
-*****************
-Download the code
-*****************
-Now that you verified that the Lightning App does indeed work end-to-end, go to the **Code** tab and click "Download zip", to get the full code
-on your machine.
diff --git a/docs/source-app/levels/basic/level_2.rst b/docs/source-app/levels/basic/level_2.rst
deleted file mode 100644
index 0f75c33588ff3..0000000000000
--- a/docs/source-app/levels/basic/level_2.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-###################################
-Level 2: Run Lightning Apps locally
-###################################
-**Audience:** New users who want to run a Lightning App on their machines
-
-**Prereqs:** You already have the Lightning App code on your local machine.
-
-----
-
-************
-Get the code
-************
-If you followed the instructions for **Level 1: Clone and Run**, you already have the code for the Lightning App locally. Otherwise please go back to `Level 1 `_.
-
-----
-
-***********
-Run locally
-***********
-Run the Lightning App on your local machine by using the following command:
-
-.. code:: bash
-
- lightning run app app.py
-
-Now you'll see the Lightning App start up on your local machine.
-
-.. note:: At this time, you can only run one Lightning App locally at a time. **Submit a PR to unblock that!**
-
-----
-
-*************************
-Run on any remote machine
-*************************
-Remember you can always SSH into any of your cloud machines on your university or enterprise cluster and run
-Lightning App from there. However, you will be responsible for the auto-scaling of those Lightning Apps.
diff --git a/docs/source-app/levels/basic/level_2_scripts/hello_app.py b/docs/source-app/levels/basic/level_2_scripts/hello_app.py
new file mode 100644
index 0000000000000..bb5e2d668fa17
--- /dev/null
+++ b/docs/source-app/levels/basic/level_2_scripts/hello_app.py
@@ -0,0 +1,23 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'))
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('gpu'))
+
+ def run(self):
+ self.train.run("GPU machine 1")
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/basic/level_2_scripts/hello_app_auto_scale.py b/docs/source-app/levels/basic/level_2_scripts/hello_app_auto_scale.py
new file mode 100644
index 0000000000000..b26d49ccf50c3
--- /dev/null
+++ b/docs/source-app/levels/basic/level_2_scripts/hello_app_auto_scale.py
@@ -0,0 +1,30 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'))
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('gpu'))
+
+ def run(self):
+ # run() starts the machine
+ self.train.run("GPU machine 1")
+
+ # stop() stops the machine
+ self.train.stop()
+
+ # run analysis ONLY when machine 1 stopped
+ if self.train.status.STOPPED:
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/basic/level_2_scripts/hello_app_cron.py b/docs/source-app/levels/basic/level_2_scripts/hello_app_cron.py
new file mode 100644
index 0000000000000..a7a3ee6991cfc
--- /dev/null
+++ b/docs/source-app/levels/basic/level_2_scripts/hello_app_cron.py
@@ -0,0 +1,27 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'))
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('gpu'))
+
+ def run(self):
+ # run training once
+ self.train.run("GPU machine 1")
+
+ # run analysis once, then every hour again...
+ if self.schedule("5 4 * * *"):
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/basic/level_2_scripts/hello_app_scheduler.py b/docs/source-app/levels/basic/level_2_scripts/hello_app_scheduler.py
new file mode 100644
index 0000000000000..1e655c28139bf
--- /dev/null
+++ b/docs/source-app/levels/basic/level_2_scripts/hello_app_scheduler.py
@@ -0,0 +1,27 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'))
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('gpu'))
+
+ def run(self):
+ # run training once
+ self.train.run("GPU machine 1")
+
+ # run analysis once, then every hour again...
+ if self.schedule("hourly"):
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/basic/level_2_scripts/organized_app_python.py b/docs/source-app/levels/basic/level_2_scripts/organized_app_python.py
new file mode 100644
index 0000000000000..c34a5deb55686
--- /dev/null
+++ b/docs/source-app/levels/basic/level_2_scripts/organized_app_python.py
@@ -0,0 +1,37 @@
+# app.py
+import subprocess
+
+import lightning as L
+
+
+class ExternalModelServer(L.LightningWork):
+ def run(self, x):
+ # compile
+ process = subprocess.Popen('g++ model_server.cpp -o model_server')
+ process.wait()
+ process = subprocess.Popen('./model_server')
+ process.wait()
+
+class LocustLoadTester(L.LightningWork):
+ def run(self, x):
+ cmd = f'locust --master-host {self.host} --master-port {self.port}'
+ process = subprocess.Popen(cmd)
+ process.wait()
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.serve = ExternalModelServer(
+ cloud_compute=L.CloudCompute('cpu'), parallel=True
+ )
+ self.load_test = LocustLoadTester(cloud_compute=L.CloudCompute('cpu'))
+
+ def run(self):
+ # start the server (on a CPU machine 1)
+ self.serve.run()
+
+ # load testing when the server is up (on a separate cpu machine 2)
+ if self.serve.state.RUNNING:
+ self.load_test.run()
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/basic/level_3.rst b/docs/source-app/levels/basic/level_3.rst
deleted file mode 100644
index cf4c8def7bf3a..0000000000000
--- a/docs/source-app/levels/basic/level_3.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-#############################
-Level 3: Run app on the cloud
-#############################
-**Audience:** Users who want to run an app on the Lightning Cloud.
-
-**Prereqs:** You have an app already running locally.
-
-----
-
-****************************
-What is the Lightning Cloud?
-****************************
-The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
-the Lightning Cloud supports AWS.
-
-.. note:: Support for GCP and Azure is coming soon!
-
-To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
-on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
-
-----
-
-****************
-Run on the cloud
-****************
-To run the app on the cloud, simply add **--cloud** to the command
-
-.. code:: bash
-
- lightning run app app.py --cloud
-
-Lightning packages everything in that folder and uploads it to the cloud. Your code will be visible to everyone (just like Github).
-
-.. note:: To have private Lightning Apps, you'll need to upgrade your account. To upgrade, contact us ``_.
-
-----
-
-************
-Ignore files
-************
-Lightning sends everything in your Lightning App folder to the cloud. If you want to ignore certain files (such as datasets),
-use the **.lightningignore** file which works just like the **.gitignore**
-
-.. code:: bash
-
- touch .lightningignore
-
-----
-
-*******************
-Manage requirements
-*******************
-A Lightning App is simply a Python file. However, when running on the cloud, it is encouraged that you add
-a **requirements.txt** file so that the platform knows what requirements your Lightning App needs.
-
-If you require custom Docker images, each LightningWork has the ability to have a private Docker image.
diff --git a/docs/source-app/levels/basic/level_4.rst b/docs/source-app/levels/basic/level_4.rst
deleted file mode 100644
index 484973dbddac6..0000000000000
--- a/docs/source-app/levels/basic/level_4.rst
+++ /dev/null
@@ -1,122 +0,0 @@
-############################
-Level 4: Modify existing app
-############################
-**Audience:** Users who have already run a Lightning App locally or remote and want to modify it.
-
-**Prereqs:** You've ran a Lightning App locally and the cloud.
-
-----
-
-***************
-Change the code
-***************
-A Lightning App is simply organized Python code. To modify an existing Lightning App, simply change the code!
-There's nothing more you need to do.
-
-----
-
-***************
-Add a component
-***************
-A major superpower you get with Lightning Apps is modular workflows. This allows you to use our gallery
-of opensource components to power your work. Find a component in the `component gallery `_ and add it to your
-Lightning App.
-
-If you need inspiration, here are some components you might want to use to extend your Lightning App:
-
-
-.. raw:: html
-
-
-
-
-.. Add callout items below this line
-
-.. displayitem::
- :header: Slack Messenger
- :description: Send a Slack notification when anything happens in your Lightning App.
- :button_link: https://lightning.ai/component/LJFITYeNBZ-Slack%20Messenger
- :col_css: col-md-4
- :height: 200
- :tag: monitoring
-
-.. displayitem::
- :header: Lightning Serve
- :description: Make your model serving infrastructure resilient with over 7+ strategies such as canary, recreate, ramped and more.
- :button_link: https://lightning.ai/component/BA2slXIke9-Lightning%20Serve
- :col_css: col-md-4
- :height: 200
- :tag: production
-
-.. displayitem::
- :header: Lightning HPO
- :description: Add a hyperparameter sweep to your Lightning App.
- :button_link: https://lightning.ai/component/BA2slXI093-Lightning%20HPO
- :col_css: col-md-4
- :height: 200
- :tag: research
-
-.. displayitem::
- :header: Jupyter Notebook
- :description: Add a Jupyter Notebook to your Lightning App.
- :button_link: https://lightning.ai/component/cRH1UHnvBx-Jupyter%20Notebook
- :col_css: col-md-4
- :height: 200
- :tag: data science
-
-.. displayitem::
- :header: Google BigQuery
- :description: Connect a big BigQuery dataset to your Lightning App.
- :button_link: https://lightning.ai/component/Mtt4fnRlUE-Google%20BigQuery
- :col_css: col-md-4
- :height: 200
- :tag: production
-
-.. raw:: html
-
-
-
-
-----
-
-*********************
-Install the component
-*********************
-To add a component, install the component first.
-
-We'll use the Slack messaging component as example:
-
-.. code:: bash
-
- lightning install component lightning/lit-slack-messenger
-
-
-Now that the component is installed, make sure you add it to your requirements.txt
-
-.. code:: bash
-
- echo 'git+https://github.com/Lightning-AI/LAI-slack-messenger.git@4aa91554f51baf56fc14316365c67fcc67b61e7d' > requirements.txt
-
-----
-
-*****************
-Use the component
-*****************
-To use the component, simply import it and attach it to your Lightning App.
-
-.. code:: python
-
- import lightning as L
- from lit_slack import SlackMessenger
-
-
- class YourComponent(L.LightningFlow):
- def __init__(self):
- super().__init__()
- self.slack_messenger = SlackMessenger(token="a-long-token", channel_id="A03CB4A6AK7")
-
- def run(self):
- self.slack_messenger.send_message("hello from âš¡ lit slack âš¡")
-
-
- app = L.LightningApp(YourComponent())
diff --git a/docs/source-app/levels/basic/level_5.rst b/docs/source-app/levels/basic/level_5.rst
deleted file mode 100644
index c7ec29e78411d..0000000000000
--- a/docs/source-app/levels/basic/level_5.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-##################################
-Level 5: Share your Lightning Apps
-##################################
-**Audience:** Users who work in teams.
-
-**Prereqs:** You've ran a Lightning App locally and the cloud.
-
-----
-
-****************************************
-What sharing Lightning Apps does for you
-****************************************
-When working on teams or to show your Lightning App to your users or collaborators, it's often
-helpful to share a link to your Lightning App.
-
-Sharing a link to your Lightning App, allows your collaborators to see what you've built, instead of them having
-to clone, install the repo, and very likely not get anything running.
-
-----
-
-************************
-Share your Lightning App
-************************
-The easiest way to share your Lightning Apps is to run them on Lightning Cloud:
-
-.. code:: bash
-
- lightning run app app.py --cloud
-
-Once your Lightning App starts running, press "Open", then copy the link from the browser and share the link with your
-colleagues!
diff --git a/docs/source-app/levels/basic/level_6.rst b/docs/source-app/levels/basic/level_6.rst
deleted file mode 100644
index 8a228029ca2b9..0000000000000
--- a/docs/source-app/levels/basic/level_6.rst
+++ /dev/null
@@ -1,78 +0,0 @@
-###################################
-Level 6: Publish your Lightning App
-###################################
-**Audience:** New users to the framework.
-
-**Prereqs:** None.
-
-----
-
-*******************************************
-What publishing Lightning Apps does for you
-*******************************************
-Publishing a Lightning App, allows you to share your work with the Lightning community so that others won't have
-to repeat the work you've built. This is at the core of the opensource ethos, that allows us to build
-on top of each other's work.
-
-If your Lightning App is for a company, or business you are trying to monetize, publishing your Lightning App allows your users
-to visit a single place where they won't have to worry about installing your Lightning App or running it on their own
-accounts.
-
-----
-
-**************************
-Publish your Lightning App
-**************************
-To publish a Lightning App, visit `lightning.ai `_, expand the "Apps & Components" menu, and hit "Submit yours".
-This will take you to `this form `_.
-
-----
-
-********************************************
-Guidelines for publishing your Lightning App
-********************************************
-Only the very best apps get accepted to the Lightning Gallery. Here are some guidelines to help you with yours.
-
-----
-
-Thumbnail
-^^^^^^^^^
-Make sure you have a high-quality Thumbnail. The image should be 300x200 and smaller than 20kb.
-
-----
-
-App name
-^^^^^^^^
-App names can only be 1-3 words at most. Names should be unique/recognizable. Remember Uber, Snapchat, etc...
-
-----
-
-Short Description
-^^^^^^^^^^^^^^^^^
-The short description should be succinct and to the point. Avoid filler words like "this app allows you to". It should
-describe what your users can do with the app NOT the tools that are being used in the app.
-
-----
-
-Long Description
-^^^^^^^^^^^^^^^^
-Use the long description to describe to the user what the app does in more detail, and why they should use it.
-This is your time to shine!
-
-Don't use gimmiky sentences like "have you ever wanted to?", "wouldn't it be great if?". Be professional
-and let the user know what value your app brings to them.
-
-----
-
-Tags
-^^^^
-Tags should allow users to know if the app is relevant for them. This is where it's helpful to let the
-user know the domains (NLP, RL, CV) and even the key libraries used (PyTorch Lightning, Tensorboard, Timm, etc...).
-
-----
-
-Code example
-^^^^^^^^^^^^
-The code example should be minimal. Do not add anything the user doesn't need to know. Don't try to show
-off all the features of your app or component, simply show the most minimal, critical piece of code that
-can get your users started immediately.
diff --git a/docs/source-app/levels/basic/level_7.rst b/docs/source-app/levels/basic/level_7.rst
deleted file mode 100644
index 63b1ae05018b8..0000000000000
--- a/docs/source-app/levels/basic/level_7.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-##################################
-Level 7: Run on your cloud account
-##################################
-**Audience:** Users who want to run on their own cloud accounts
-
-**Prereqs:** Users ran a Lightning App locally and/or the cloud.
-
-----
-
-****************************
-What is the Lightning Cloud?
-****************************
-The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
-the Lightning Cloud supports AWS.
-
-.. note:: Support for GCP and Azure is coming soon!
-
-To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
-on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
-
-----
-
-****************************************
-Run Lightning Apps on your cloud account
-****************************************
-To run Lightning Apps on your own account, you can simply SSH into the machines on your cloud account
-and start the Lightning Apps there! This also works on any machine you have access to, such as your own
-on-prem cluster, DGX machine, etc... However, you will have to manage your own auto-scaling
-and distribition of work for complex Lightning Apps.
-
-If you want to automate all that complexity, we allow you to create as many clusters as you
-want, on the cloud provider of your choice, using Lightning Cloud. Once you've configured your clusters,
-you can run your Lightning Apps on those clusters.
-
-Free clusters on Lightning Cloud have limits of the number of machines you can run. To increase that limit,
-please `contact us `_.
diff --git a/docs/source-app/levels/basic/run_jupyter_notebook_on_the_cloud.rst b/docs/source-app/levels/basic/run_jupyter_notebook_on_the_cloud.rst
new file mode 100644
index 0000000000000..825175516d4a7
--- /dev/null
+++ b/docs/source-app/levels/basic/run_jupyter_notebook_on_the_cloud.rst
@@ -0,0 +1,19 @@
+#############################################
+Example: Develop a Jupyter Notebook component
+#############################################
+**Audience:** TODO:
+
+**Prereqs:** You have an app already running locally.
+
+----
+
+****************************
+What is the Lightning Cloud?
+****************************
+The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
+the Lightning Cloud supports AWS.
+
+.. note:: Support for GCP and Azure is coming soon!
+
+To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
+on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
diff --git a/docs/source-app/levels/basic/run_on_aws_account.rst b/docs/source-app/levels/basic/run_on_aws_account.rst
new file mode 100644
index 0000000000000..ecf1542b4d1b7
--- /dev/null
+++ b/docs/source-app/levels/basic/run_on_aws_account.rst
@@ -0,0 +1,21 @@
+:orphan:
+
+To run on your own AWS account, first `create an AWS ARN <../../glossary/aws_arn.rst>`_.
+
+Next, set up a Lightning cluster (here we name it pikachu):
+
+.. code:: bash
+
+ # TODO: need to remove --external-id dummy --region us-west-2
+ lightning create cluster pikachu --provider aws --role-arn arn:aws:iam::1234567890:role/lai-byoc
+
+Run your code on the pikachu cluster by passing it into CloudCompute:
+
+.. code:: python
+
+ compute = L.CloudCompute('gpu', clusters=['pikachu'])
+ app = L.LightningApp(LitWorker(cloud_compute=compute))
+
+.. warning::
+
+ This feature is available only under early-access. Request access by emailing support@lightning.ai.
diff --git a/docs/source-app/levels/basic/train_pytorch_on_the_cloud.rst b/docs/source-app/levels/basic/train_pytorch_on_the_cloud.rst
new file mode 100644
index 0000000000000..ea257eb9b0a2d
--- /dev/null
+++ b/docs/source-app/levels/basic/train_pytorch_on_the_cloud.rst
@@ -0,0 +1,19 @@
+###################################
+Example: Train PyTorch on the cloud
+###################################
+**Audience:** TODO:
+
+**Prereqs:** You have an app already running locally.
+
+----
+
+****************************
+What is the Lightning Cloud?
+****************************
+The Lightning Cloud is the platform that we've created to interface with the cloud providers. Today
+the Lightning Cloud supports AWS.
+
+.. note:: Support for GCP and Azure is coming soon!
+
+To use the Lightning Cloud, you buy credits that are used to pay the cloud providers. If you want to run
+on your own AWS credentials, please contact us (support@lightning.ai) so we can get your clusters set up for you.
diff --git a/docs/source-app/levels/expert/index.rst b/docs/source-app/levels/expert/index.rst
new file mode 100644
index 0000000000000..a7a52850a6563
--- /dev/null
+++ b/docs/source-app/levels/expert/index.rst
@@ -0,0 +1,94 @@
+:orphan:
+
+.. _expert_level:
+
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+#############
+Expert skills
+#############
+
+.. join_slack::
+ :align: left
+
+----
+
+.. raw:: html
+
+
+
+
+.. displayitem::
+ :header: Level : Use custom containers
+ :description: Learn to use a custom cloud container.
+ :button_link: build_a_machine_learning_workflow.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Level : Customize your cluster creation
+ :description: Learn to use a custom cloud container.
+ :button_link: build_a_machine_learning_workflow.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+
+.. raw:: html
+
+
+
+
+----
+
+*********************
+Intermediate Examples
+*********************
+As you work through the intermediate levels, try these examples:
+
+.. raw:: html
+
+
+
+
+.. Add callout items below this line
+
+.. displayitem::
+ :header: Example: Develop a Github Repo Script Runner
+ :description: Develop a workflow to execute Github Repos
+ :button_link: ../../examples/github_repo_runner/github_repo_runner.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Develop a file server
+ :description: Create a simple Lightning App (App) that allows users to upload files and list the uploaded files.
+ :button_link: ../../examples/file_server/file_server.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Develop a Jupyter Notebook component
+ :description: Develop a LightningWork that runs a notebook on the cloud.
+ :button_link: run_jupyter_notebook_on_the_cloud.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Create a model demo
+ :description: Demo POCs and MVPs which can be shared with a public web user interface.
+ :button_link: create_a_model_demo.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. raw:: html
+
+
+
diff --git a/docs/source-app/levels/intermediate/debug_a_lightning_workflow.rst b/docs/source-app/levels/intermediate/debug_a_lightning_workflow.rst
new file mode 100644
index 0000000000000..fc00b0d07cd0e
--- /dev/null
+++ b/docs/source-app/levels/intermediate/debug_a_lightning_workflow.rst
@@ -0,0 +1,22 @@
+##############################
+Level 4: Debug A Lightning app
+##############################
+**Audience:** Users who want to debug a distributed app locally.
+
+**Prereqs:** You must have finished the `Basic levels <../basic/>`_.
+
+----
+
+**********************
+Enable local debugging
+**********************
+A distributed Lightning app can run locally on a single machine. To debug apps running locally
+you can use the multi-processing runtime:
+
+.. lit_tabs::
+ :titles: Toy app; Enable MultiProcessRuntime
+ :code_files: ./scripts/toy_app.py; ./scripts/debug_app.py
+ :highlights: ; 3, 24
+ :app_id: abc123
+ :tab_rows: 3
+ :height: 480px
diff --git a/docs/source-app/levels/intermediate/embed_web_ui_into_lightningwork.rst b/docs/source-app/levels/intermediate/embed_web_ui_into_lightningwork.rst
new file mode 100644
index 0000000000000..84e4cfcb63e51
--- /dev/null
+++ b/docs/source-app/levels/intermediate/embed_web_ui_into_lightningwork.rst
@@ -0,0 +1,12 @@
+:orphan:
+
+######################################
+Level 6: Embed graphical UIs into work
+######################################
+**Audience:** Users who need to embed a Graphical UI in their Lightning Apps.
+
+**Prereqs:** You must have finished the `Basic levels <../basic/>`_.
+
+----
+
+.. include:: ../../workflows/add_web_ui/index_content.rst
diff --git a/docs/source-app/levels/intermediate/index.rst b/docs/source-app/levels/intermediate/index.rst
index c55792e0a1c45..88d4ddbeed619 100644
--- a/docs/source-app/levels/intermediate/index.rst
+++ b/docs/source-app/levels/intermediate/index.rst
@@ -4,10 +4,10 @@
:maxdepth: 1
:hidden:
- level_8
- level_9
- level_10
- level_11
+ save_money_on_cloud_costs
+ debug_a_lightning_workflow
+ run_lightning_work_in_parallel
+ share_variables_between_lightning_components
level_12
level_13
level_14
@@ -16,7 +16,7 @@
###################
Intermediate skills
###################
-Learn to build your own Lightning Apps from scratch and the basics of the framework.
+Learn to run efficiently on the cloud
.. join_slack::
:align: left
@@ -31,65 +31,73 @@ Learn to build your own Lightning Apps from scratch and the basics of the framew
.. Add callout items below this line
.. displayitem::
- :header: Level 8: Build a Lightning App
- :description: Learn how to build a Lightning App from scratch.
- :button_link: level_8.html
+ :header: Level 3: Save money on cloud costs
+ :description: Explore key Lightning features that save you cloud costs and improve performance.
+ :button_link: save_money_on_cloud_costs.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 9: Event loop
- :description: Learn about the event loop.
- :button_link: level_9.html
+ :header: Level 4: Debug a Lightning App
+ :description: Learn to debug a lightning app.
+ :button_link: debug_a_lightning_workflow.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 10: Add web UIs
- :description: Learn how to add web UIs to your Lightning App.
- :button_link: level_10.html
+ :header: Level 5: Run a Lightning component in parallel
+ :description: Learn when and how to run Components in parallel (asynchronous).
+ :button_link: run_lightning_work_in_parallel.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 11: Customize cloud compute
- :description: Learn to use different cloud machines.
- :button_link: level_11.html
+ :header: Level 6: Share variables between components
+ :description: Share variables between Lightning components.
+ :button_link: share_variables_between_lightning_components.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 12: LightningFlow vs LightningWork
- :description: Learn the difference between LightningFlow and LightningWork.
- :button_link: level_12.html
+ :header: Level : Share files between components
+ :description: Learn how Drives share files between components
+ :button_link: level_14.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 13: Communicate between Lightning components
- :description: Learn about how LightningFlows communicate with LightningWorks.
- :button_link: level_13.html
+ :header: Level : Start dynamic components
+ :description: Learn to start works dynamically
+ :button_link: level_15.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 14: Share files between components
- :description: Learn how Drives share files between components
- :button_link: level_14.html
+ :header: Level 12: Check component status
+ :description: Learn to use work status to coordinate complex apps.
+ :button_link: level_16.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: advanced
+
+.. displayitem::
+ :header: Level : Adapt an app template
+ :description: Learn to start from a template and expand it by adding your own components.
+ :button_link: run_on_aws_efficiently.html
:col_css: col-md-6
:height: 150
:tag: intermediate
.. displayitem::
- :header: Level 15: Run LightningWorks in parallel
- :description: Learn when to run LightningWorks in parallel
- :button_link: level_15.html
+ :header: Level: Render a web UI alongside other components.
+ :description: Learn how to embed graphical UIs like react, vue, streamlit and notebook UIs into a lightning workflow.
+ :button_link: embed_web_ui_into_lightningwork.html
:col_css: col-md-6
:height: 150
:tag: intermediate
@@ -98,3 +106,54 @@ Learn to build your own Lightning Apps from scratch and the basics of the framew
+
+----
+
+*********************
+Intermediate Examples
+*********************
+As you work through the intermediate levels, try these examples:
+
+.. raw:: html
+
+
+
+
+.. Add callout items below this line
+
+.. displayitem::
+ :header: Example: Develop a Github Repo Script Runner
+ :description: Develop a workflow to execute Github Repos
+ :button_link: ../../examples/github_repo_runner/github_repo_runner.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Develop a file server
+ :description: Create a simple Lightning App (App) that allows users to upload files and list the uploaded files.
+ :button_link: ../../examples/file_server/file_server.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Develop a Jupyter Notebook component
+ :description: Develop a LightningWork that runs a notebook on the cloud.
+ :button_link: run_jupyter_notebook_on_the_cloud.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. displayitem::
+ :header: Example: Create a model demo
+ :description: Demo POCs and MVPs which can be shared with a public web user interface.
+ :button_link: create_a_model_demo.html
+ :col_css: col-md-6
+ :height: 150
+ :tag: basic
+
+.. raw:: html
+
+
+
diff --git a/docs/source-app/levels/intermediate/level_10.rst b/docs/source-app/levels/intermediate/level_10.rst
index 3e20771eab4ee..38ff835a5a745 100644
--- a/docs/source-app/levels/intermediate/level_10.rst
+++ b/docs/source-app/levels/intermediate/level_10.rst
@@ -1,3 +1,5 @@
+:orphan:
+
###########
Add web UIs
###########
diff --git a/docs/source-app/levels/intermediate/level_11.rst b/docs/source-app/levels/intermediate/level_11.rst
deleted file mode 100644
index 9dc8804743c9f..0000000000000
--- a/docs/source-app/levels/intermediate/level_11.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-#################################
-Level 11: Customize cloud compute
-#################################
-**Audience:** Users who want to change their cloud compute
-
-**Prereqs:**
-
-**Level:** Intermediate
-
-----
-
-.. include:: ../../core_api/lightning_work/compute_content.rst
diff --git a/docs/source-app/levels/intermediate/level_15.rst b/docs/source-app/levels/intermediate/level_15.rst
index 255e573a71d69..3bd21ec8aaa9d 100644
--- a/docs/source-app/levels/intermediate/level_15.rst
+++ b/docs/source-app/levels/intermediate/level_15.rst
@@ -1,7 +1,7 @@
-########################################
-Level 15: Run LightningWorks in parallel
-########################################
-**Audience:** Users who want to run multiple LightningWorks at once.
+#######################################
+Level 15: Run LightningWork in parallel
+#######################################
+**Audience:** Users who want to run a LightningWork in parallel (asynchroneously).
**Prereqs:** Level 8+
diff --git a/docs/source-app/levels/intermediate/level_8.rst b/docs/source-app/levels/intermediate/level_8.rst
deleted file mode 100644
index a40fe75e82b28..0000000000000
--- a/docs/source-app/levels/intermediate/level_8.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-###########################################
-Level 8: Build a Lightning App from Scratch
-###########################################
-**Audience:** Users who want to build an Lightning App from scratch
-
-**Prereqs:** You must have finished the `Basic levels
`_.
-
-----
-
-.. include:: ../../workflows/build_lightning_app/from_scratch_content.rst
diff --git a/docs/source-app/levels/intermediate/level_9.rst b/docs/source-app/levels/intermediate/level_9.rst
index 33a2e4f50c587..210adbc19a431 100644
--- a/docs/source-app/levels/intermediate/level_9.rst
+++ b/docs/source-app/levels/intermediate/level_9.rst
@@ -1,3 +1,5 @@
+:orphan:
+
###################
Level 9: Event loop
###################
diff --git a/docs/source-app/levels/intermediate/run_lightning_work_in_parallel.rst b/docs/source-app/levels/intermediate/run_lightning_work_in_parallel.rst
new file mode 100644
index 0000000000000..a523ba2ef0d46
--- /dev/null
+++ b/docs/source-app/levels/intermediate/run_lightning_work_in_parallel.rst
@@ -0,0 +1,10 @@
+##############################################
+Level 5: Run a Lightning component in parallel
+##############################################
+**Audience:** Users who want to run a Lightning Component in parallel (asynchroneously).
+
+**Prereqs:** You must have finished the `Basic levels <../basic/>`_.
+
+----
+
+.. include:: ../../workflows/run_work_in_parallel_content.rst
diff --git a/docs/source-app/levels/intermediate/save_money_on_cloud_costs.rst b/docs/source-app/levels/intermediate/save_money_on_cloud_costs.rst
new file mode 100644
index 0000000000000..28e69fb8c2198
--- /dev/null
+++ b/docs/source-app/levels/intermediate/save_money_on_cloud_costs.rst
@@ -0,0 +1,27 @@
+##################################
+Level 3: Save money on cloud costs
+##################################
+**Audience:** Users who want to use the AWS cloud efficiently.
+
+**Prereqs:** You must have finished the `Basic levels <../basic/>`_.
+
+----
+
+***********************************
+Save money with these optimizations
+***********************************
+A Lightning component gives you fine-grain control over the cloud lifecycle of that component.
+
+Here are a few features that will enable you save a lot on your cloud costs:
+
+.. lit_tabs::
+ :titles: 15+ accelerators; Auto-stop idle machines; Auto-timeout submitted work; Use spot machines (~70% discount); Work with massive datasets; Mount cloud storage; Use a custom container
+ :code_files: ../basic/key_features/accelerators.py; ../basic/key_features/idle_machine.py; ../basic/key_features/auto_timeout.py; ../basic/key_features/spot.py; ../basic/key_features/massive_dataset.py; ../basic/key_features/mount_data.py; ../basic/key_features/custom_container.py;
+ :highlights: 11;11;11;11;11;1,7, 10, 11; 11
+ :app_id: abc123
+ :tab_rows: 3
+ :height: 430px
+
+----
+
+.. include:: ../../cloud/customize_a_lightning_cluster.rst
diff --git a/docs/source-app/levels/intermediate/scripts/debug_app.py b/docs/source-app/levels/intermediate/scripts/debug_app.py
new file mode 100644
index 0000000000000..9e3d9c9a7d801
--- /dev/null
+++ b/docs/source-app/levels/intermediate/scripts/debug_app.py
@@ -0,0 +1,25 @@
+# app.py
+import lightning as L
+from lightning.app.runners import MultiProcessRuntime
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent()
+ self.analyze = AnalyzeComponent()
+
+ def run(self):
+ self.train.run("GPU machine 1")
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
+MultiProcessRuntime(app).dispatch()
diff --git a/docs/source-app/levels/intermediate/scripts/toy_app.py b/docs/source-app/levels/intermediate/scripts/toy_app.py
new file mode 100644
index 0000000000000..4604f3ec633f2
--- /dev/null
+++ b/docs/source-app/levels/intermediate/scripts/toy_app.py
@@ -0,0 +1,23 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, x):
+ print(f'train a model on {x}')
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, x):
+ print(f'analyze model on {x}')
+
+class WorkflowOrchestrator(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent()
+ self.analyze = AnalyzeComponent()
+
+ def run(self):
+ self.train.run("CPU machine 1")
+ self.analyze.run("CPU machine 2")
+
+app = L.LightningApp(WorkflowOrchestrator())
diff --git a/docs/source-app/levels/intermediate/share_variables_between_lightning_components.rst b/docs/source-app/levels/intermediate/share_variables_between_lightning_components.rst
new file mode 100644
index 0000000000000..5d586ba416280
--- /dev/null
+++ b/docs/source-app/levels/intermediate/share_variables_between_lightning_components.rst
@@ -0,0 +1,120 @@
+###########################################
+Level 6: Share variables between components
+###########################################
+**Audience:** Users who want to share variables and files across Lightning components.
+
+**Prereqs:** You must have finished `intermediate level 5+
`_.
+
+----
+
+****************************************
+Send a variable from Flow to a Component
+****************************************
+
+Todo
+
+----
+
+**************************************
+Send a variable between two components
+**************************************
+Works cannot communicate directly between each other. Instead, a shared parent Flow must manage the communication.
+
+# A needs to know something about B, maybe the time?
+
+----
+
+********************************************
+Send a large variable between two components
+********************************************
+Payload.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+***********
+The toy app
+***********
+In this page, we'll be using the following toy snippet:
+
+.. code:: python
+
+ # app.py
+ import lightning as L
+
+ class CountingWork(L.LightningWork):
+ def __init__(self):
+ super().__init__(parallel=True)
+ self.count = 0
+
+ def run(self):
+ for i in range(int(1000000)):
+ self.count += 1
+
+ class LitWorkflow(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.counter = CountingWork(cloud_compute=L.CloudCompute('cpu'))
+
+ def run(self):
+ self.counter.run()
+ count = self.counter.count
+ print(count)
+
+ app = L.LightningApp(LitWorkflow())
+
+----
+
+*****************************
+Communicate from Flow to Work
+*****************************
+ABC
+
+----
+
+**********************************
+Communicate between LightningWorks
+**********************************
+Works cannot communicate directly between each other. Instead, a shared parent Flow must manage the communication.
+
+.. code:: python
+
+ # app.py
+ import lightning as L
+
+ class CountingWork(L.LightningWork):
+ def __init__(self):
+ super().__init__(parallel=True)
+ self.count = 0
+
+ def run(self):
+ for i in range(int(1000000)):
+ self.count += 1
+
+ class LitWorkflow(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.counter = CountingWork(cloud_compute=L.CloudCompute('cpu'))
+
+ def run(self):
+ self.counter.run()
+ count = self.counter.count
+ print(count)
diff --git a/docs/source-app/workflows/build_lightning_app/index.rst b/docs/source-app/workflows/build_lightning_app/index.rst
index 0af121d489b1e..e60f0355afb8e 100644
--- a/docs/source-app/workflows/build_lightning_app/index.rst
+++ b/docs/source-app/workflows/build_lightning_app/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
#######################
Develop a Lightning App
#######################
diff --git a/docs/source-app/workflows/build_lightning_component/index.rst b/docs/source-app/workflows/build_lightning_component/index.rst
index 9ff726a9486b1..8620a9b9fd8d5 100644
--- a/docs/source-app/workflows/build_lightning_component/index.rst
+++ b/docs/source-app/workflows/build_lightning_component/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
#############################
Develop a Lightning Component
#############################
diff --git a/docs/source-app/workflows/build_rest_api/index.rst b/docs/source-app/workflows/build_rest_api/index.rst
index 269b810ec6442..8b9192fb350fc 100644
--- a/docs/source-app/workflows/build_rest_api/index.rst
+++ b/docs/source-app/workflows/build_rest_api/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
###########
RESTful API
###########
diff --git a/docs/source-app/workflows/index.rst b/docs/source-app/workflows/index.rst
index 7f0642f661ead..a91220ab2e34d 100644
--- a/docs/source-app/workflows/index.rst
+++ b/docs/source-app/workflows/index.rst
@@ -1,14 +1,44 @@
-:orphan:
-
-################
-Common Workflows
-################
+.. toctree::
+ :maxdepth: 1
+ :hidden:
+
+ access_app_state/access_app_state
+ add_web_ui/index
+ add_web_link
+ secrets <../glossary/secrets>
+ arrange_tabs/index
+ connect components <../levels/basic/connect_lightning_components>
+ build components <../levels/basic/build_a_lightning_component>
+ run_work_once
+ cloud compute <../core_api/lightning_work/compute>
+ build_command_line_interface/index
+ rest API <../glossary/restful_api/restful_api>
+ extend_app
+ build_lightning_component/publish_a_component
+ byoc/index
+ add_server/index
+ run_app_on_cloud/index
+ run_work_in_parallel
+ drive <../glossary/storage/drive>
+ share_app
+ share_files_between_components
+
+#######
+How to:
+#######
.. raw:: html
+.. displayitem::
+ :header: Access the App State
+ :description: Learn to work with the app state
+ :col_css: col-md-4
+ :button_link: access_app_state/access_app_state.html
+ :height: 180
+
.. displayitem::
:header: Add a web user interface
:description: Learn how to add React, StreamLit, Dash to your App.
@@ -23,6 +53,13 @@ Common Workflows
:button_link: add_web_link.html
:height: 180
+.. displayitem::
+ :header: Add encrypted secrets
+ :description: Learn how to organize your UI
+ :col_css: col-md-4
+ :button_link: ../glossary/secrets.html
+ :height: 180
+
.. displayitem::
:header: Arrange App tabs
:description: Learn how to organize your UI
@@ -34,14 +71,14 @@ Common Workflows
:header: Build a Lightning App
:description: Simple App to get started
:col_css: col-md-4
- :button_link: build_lightning_app/index.html
+ :button_link: ../levels/basic/connect_lightning_components.html
:height: 180
.. displayitem::
:header: Build a Lightning Component
:description: Understand how to separated the glue from the actual work
:col_css: col-md-4
- :button_link: build_lightning_component/index.html
+ :button_link: ../levels/basic/build_a_lightning_component.html
:height: 180
.. displayitem::
@@ -58,6 +95,27 @@ Common Workflows
:button_link: ../core_api/lightning_work/compute.html
:height: 180
+.. displayitem::
+ :header: Develop a Command Line Interface (CLI)
+ :description: Learn to develop a CLI
+ :col_css: col-md-4
+ :button_link: build_command_line_interface/index.html
+ :height: 180
+
+.. displayitem::
+ :header: Develop a Lightning App
+ :description: Learn to connect components together into a Lightning App
+ :col_css: col-md-4
+ :button_link: ../levels/basic/connect_lightning_components.html
+ :height: 180
+
+.. displayitem::
+ :header: Develop a REST API
+ :description: Learn to deploy a model behind a REST API
+ :col_css: col-md-4
+ :button_link: ../glossary/restful_api/restful_api.html
+ :height: 180
+
.. displayitem::
:header: Extend an existing App
:description: Learn where to go next with an App
@@ -72,6 +130,13 @@ Common Workflows
:button_link: build_lightning_component/publish_a_component.html
:height: 180
+.. displayitem::
+ :header: Run Apps on your cloud account (BYOC)
+ :description: Share your components with others
+ :col_css: col-md-4
+ :button_link: byoc/index.html
+ :height: 180
+
.. displayitem::
:header: Run a server within a Lightning App
:description: Lightning Work can be infinite jobs
@@ -93,6 +158,13 @@ Common Workflows
:button_link: run_work_in_parallel.html
:height: 180
+.. displayitem::
+ :header: Save files
+ :description: Learn how to save files in a work by using Drive
+ :col_css: col-md-4
+ :button_link: ../glossary/storage/drive.html
+ :height: 180
+
.. displayitem::
:header: Share an App
:description: Learn how to share your work with others
diff --git a/docs/source-app/workflows/run_work_in_parallel.rst b/docs/source-app/workflows/run_work_in_parallel.rst
index 58089b6ed7f46..90c7b7b93cc62 100644
--- a/docs/source-app/workflows/run_work_in_parallel.rst
+++ b/docs/source-app/workflows/run_work_in_parallel.rst
@@ -1,10 +1,9 @@
-##############################
-Run LightningWorks in parallel
-##############################
+#############################
+Run LightningWork in parallel
+#############################
+**Audience:** Users who want to run a LightningWork in parallel (asynchroneously).
-**Audience:** Users who want to run multiple LightningWorks at once.
-
-**Prereqs:** Level 8+
+**Prereqs:** You must have finished the `Basic levels <../basic/>`_.
----
diff --git a/docs/source-app/workflows/run_work_in_parallel_content.rst b/docs/source-app/workflows/run_work_in_parallel_content.rst
index ecb87c5cea7ff..e111df777c79b 100644
--- a/docs/source-app/workflows/run_work_in_parallel_content.rst
+++ b/docs/source-app/workflows/run_work_in_parallel_content.rst
@@ -1,53 +1,23 @@
-****************************************************
-What running LightningWorks in parallel does for you
-****************************************************
-When there is a long-running workload such as a model training, or a deployment server, you might want to run that LightningWork in parallel
-while the rest of the Lightning App continues to execute.
-
-The default behavior of the ``LightningWork`` is to wait for the ``run`` method to complete:
-
-.. code:: python
-
- import lightning as L
-
-
- class Root(L.LightningFlow):
- def __init__(self):
- self.work_component_a = L.demo.InfinteWorkComponent()
-
- def run(self):
- self.work_component_a.run()
- print("this will never print")
-
-Since this LightningWork component we created loops forever, the print statement will never execute. In practice
-``LightningWork`` workloads are finite and don't run forever.
-
-When a ``LightningWork`` performs a heavy operation (longer than 1 second), or requires its own hardware,
-LightningWork that is *not* done in parallel will slow down your app.
+***************************************
+When to run a LightningWork in parallel
+***************************************
+Run LightningWork in parallel when you want to execute work in the background or at the same time as another work.
+An example of when this comes up in machine learning is when data streams-in while a model trains.
----
-******************************
-Enable parallel LightningWorks
-******************************
-To run LightningWorks in parallel, while the rest of the app executes without delays, enable ``parallel=True``:
-
-.. code:: python
- :emphasize-lines: 5
-
- import lightning as L
-
-
- class Root(L.LightningFlow):
- def __init__(self):
- self.work_component_a = L.demo.InfinteWorkComponent(parallel=True)
-
- def run(self):
- self.work_component_a.run()
- print("repeats while the infinite work runs ONCE (and forever) in parallel")
-
-Any LightningWorks that will take more than **1 second** should be run in parallel
-unless the rest of your Lightning App depends on the output of this work (for example, downloading a dataset).
+********************
+Run work in parallel
+********************
+By default, a LightningWork must complete before the next one runs:
+
+.. lit_tabs::
+ :descriptions: Toy app; Run the train component in parallel so we can immediately start analysis without waiting for A to complete; Train and baseline in parallel which launches analysis immediately.
+ :code_files: /workflows/scripts/parallel/toy_app.py; /workflows/scripts/parallel/toy_parallel.py; /workflows/scripts/parallel/toy_two_parallel.py
+ :highlights: ; 17; 17, 18, 22, 23
+ :app_id: abc123
+ :tab_rows: 3
+ :height: 520px
diff --git a/docs/source-app/workflows/scripts/parallel/toy_app.py b/docs/source-app/workflows/scripts/parallel/toy_app.py
new file mode 100644
index 0000000000000..05f25fd84fd7c
--- /dev/null
+++ b/docs/source-app/workflows/scripts/parallel/toy_app.py
@@ -0,0 +1,27 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class LitWorkflow(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'))
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('cpu'))
+
+
+ def run(self):
+ self.train.run("machine A counting")
+ self.analyze.run("machine B counting")
+
+
+app = L.LightningApp(LitWorkflow())
diff --git a/docs/source-app/workflows/scripts/parallel/toy_parallel.py b/docs/source-app/workflows/scripts/parallel/toy_parallel.py
new file mode 100644
index 0000000000000..00d61788aeccf
--- /dev/null
+++ b/docs/source-app/workflows/scripts/parallel/toy_parallel.py
@@ -0,0 +1,27 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class LitWorkflow(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'), parallel=True)
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('cpu'))
+
+
+ def run(self):
+ self.train.run("machine A counting")
+ self.analyze.run("machine B counting")
+
+
+app = L.LightningApp(LitWorkflow())
diff --git a/docs/source-app/workflows/scripts/parallel/toy_two_parallel.py b/docs/source-app/workflows/scripts/parallel/toy_two_parallel.py
new file mode 100644
index 0000000000000..1b04e4ef40840
--- /dev/null
+++ b/docs/source-app/workflows/scripts/parallel/toy_two_parallel.py
@@ -0,0 +1,27 @@
+# app.py
+import lightning as L
+
+
+class TrainComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class AnalyzeComponent(L.LightningWork):
+ def run(self, message):
+ for i in range(100000000000):
+ print(message, i)
+
+class LitWorkflow(L.LightningFlow):
+ def __init__(self) -> None:
+ super().__init__()
+ self.train = TrainComponent(cloud_compute=L.CloudCompute('cpu'), parallel=True)
+ self.baseline_1 = TrainComponent(cloud_compute=L.CloudCompute('cpu'), parallel=True)
+ self.analyze = AnalyzeComponent(cloud_compute=L.CloudCompute('cpu'))
+
+ def run(self):
+ self.train.run("machine A counting")
+ self.baseline_1.run("machine C counting")
+ self.analyze.run("machine B counting")
+
+app = L.LightningApp(LitWorkflow())
diff --git a/docs/source-lit/conf.py b/docs/source-lit/conf.py
index d5dd5e242ec6c..5955bf1a27b47 100644
--- a/docs/source-lit/conf.py
+++ b/docs/source-lit/conf.py
@@ -16,7 +16,7 @@
import shutil
import sys
-import pt_lightning_sphinx_theme
+import lai_sphinx_theme
import lightning
@@ -78,6 +78,7 @@
# 'sphinxcontrib.mockautodoc', # raises error: directive 'automodule' is already registered ...
# 'sphinxcontrib.fulltoc', # breaks pytorch-theme with unexpected kw argument 'titles_only'
"sphinx.ext.doctest",
+ "sphinx_toolbox.collapse",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
@@ -93,11 +94,17 @@
"sphinx_paramlinks",
"sphinx_togglebutton",
"sphinx.ext.githubpages",
- "pt_lightning_sphinx_theme.extensions.lightning",
+ "lai_sphinx_theme.extensions.lightning",
]
# todo: remove this after finishing fusion
suppress_warnings = ["autosectionlabel.*"]
+copybutton_prompt_text = ">>> "
+copybutton_prompt_text1 = "... "
+copybutton_exclude = ".linenos"
+
+copybutton_only_copy_prompt_lines = True
+
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
@@ -155,8 +162,9 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = "pt_lightning_sphinx_theme"
-html_theme_path = [pt_lightning_sphinx_theme.get_html_theme_path()]
+html_theme = "lai_sphinx_theme"
+html_theme_path = [os.environ.get("LIT_SPHINX_PATH", lai_sphinx_theme.get_html_theme_path())]
+
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
diff --git a/docs/source-lit/index.rst b/docs/source-lit/index.rst
index 32fc6c1ce52df..9db8408d9149d 100644
--- a/docs/source-lit/index.rst
+++ b/docs/source-lit/index.rst
@@ -3,9 +3,9 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
-############################
-Welcome to âš¡ Lightning Apps
-############################
+######################
+Welcome to âš¡ Lightning
+######################
.. twocolumns::
:left:
diff --git a/docs/source-pytorch/conf.py b/docs/source-pytorch/conf.py
index 62d6aa55c098a..e8c0b7e83711b 100644
--- a/docs/source-pytorch/conf.py
+++ b/docs/source-pytorch/conf.py
@@ -104,6 +104,7 @@ def _transform_changelog(path_in: str, path_out: str) -> None:
# 'sphinxcontrib.fulltoc', # breaks pytorch-theme with unexpected kw argument 'titles_only'
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
+ "sphinx_toolbox.collapse",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.viewcode",
@@ -125,6 +126,12 @@ def _transform_changelog(path_in: str, path_out: str) -> None:
"autosectionlabel.*",
]
+copybutton_prompt_text = ">>> "
+copybutton_prompt_text1 = "... "
+copybutton_exclude = ".linenos"
+
+copybutton_only_copy_prompt_lines = True
+
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
@@ -179,8 +186,7 @@ def _transform_changelog(path_in: str, path_out: str) -> None:
# html_theme = 'bizstyle'
# https://sphinx-themes.org
html_theme = "pt_lightning_sphinx_theme"
-html_theme_path = [pt_lightning_sphinx_theme.get_html_theme_path()]
-# html_theme_path = ["/Users/williamfalcon/Developer/opensource/lightning_sphinx_theme"]
+html_theme_path = [os.environ.get("LIT_SPHINX_PATH", pt_lightning_sphinx_theme.get_html_theme_path())]
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
diff --git a/docs/source-pytorch/index.rst b/docs/source-pytorch/index.rst
index 215199ec224dc..1c867e1e345e9 100644
--- a/docs/source-pytorch/index.rst
+++ b/docs/source-pytorch/index.rst
@@ -1,8 +1,3 @@
-.. PyTorch-Lightning documentation master file, created by
- sphinx-quickstart on Fri Nov 15 07:48:22 2019.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
Welcome to âš¡ PyTorch Lightning
===============================
@@ -293,3 +288,8 @@ Current Lightning Users
.. raw:: html
+
+.. PyTorch-Lightning documentation master file, created by
+ sphinx-quickstart on Fri Nov 15 07:48:22 2019.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
diff --git a/docs/source-pytorch/starter/installation.rst b/docs/source-pytorch/starter/installation.rst
index f3cfa77dcbf52..136fa427d8e3f 100644
--- a/docs/source-pytorch/starter/installation.rst
+++ b/docs/source-pytorch/starter/installation.rst
@@ -6,20 +6,35 @@
Installation
############
---------------
+.. warning:: pip install pytorch-lightning has been deprecated and will stop being updated June 2023. Use pip install lightning instead.
+
+----
+
+*****************************
+Apple Silicon (M1/M2/M3) Macs
+*****************************
+While ML related python packages are updated to work with Apple Silicon, you'll need to set 2 environment variables on install.
+
+.. code-block:: bash
+
+ # needed for M1/M2/M3
+ export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
+ export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
+
+ python -m pip install -U lightning
+
+
+----
****************
Install with pip
****************
-Install any supported version of PyTorch if you want from `PyTorch Installation Page
`_.
-Now you can install using `pip `_ using the following command:
+Install lightning inside a virtual env or conda environment with pip
.. code-block:: bash
- pip install pytorch-lightning
-
-Or read the `Apple Silicon Macs installation article `_.
+ python -m pip install lightning
--------------
@@ -41,7 +56,7 @@ You can also use `Conda Environments `_.
+
+----
+
+
+*******************************************
+Optimized for ML workflows (lightning Apps)
+*******************************************
+If you are deploying workflows built with Lightning in production and require fewer dependencies, try using the optimized `lightning[apps]` package:
+
+.. code-block:: bash
+
+ pip install lightning-app
diff --git a/docs/source-pytorch/starter/installation_mac.rst b/docs/source-pytorch/starter/installation_mac.rst
deleted file mode 100644
index 180a3a88936ff..0000000000000
--- a/docs/source-pytorch/starter/installation_mac.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-:orphan:
-
-##################################
-Installation on Apple Silicon Macs
-##################################
-
-Apple Silicon (M1, M2, M3) Mac environments need a bit of tweaking before you install.
-
-----
-
-****************
-Install with pip
-****************
-
-Install the ``lightning`` package
-
- .. code:: bash
-
- export GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1
- export GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1
-
- pip install lightning
diff --git a/requirements/app/base.txt b/requirements/app/base.txt
index 8c2f23868411b..3178f6974b7e5 100644
--- a/requirements/app/base.txt
+++ b/requirements/app/base.txt
@@ -10,4 +10,5 @@ traitlets>=5.3.0, <=5.4.0
arrow>=1.2.0, <1.2.4
lightning-utilities==0.3.*
beautifulsoup4<=4.8.2
+inquirer>=2.10.0
psutil<5.9.4
diff --git a/requirements/app/docs.txt b/requirements/app/docs.txt
index 063676f4782e2..a677d283ec9a3 100644
--- a/requirements/app/docs.txt
+++ b/requirements/app/docs.txt
@@ -3,5 +3,4 @@
ipython[notebook]
ipython_genutils
-sphinx-autobuild
-https://storage.googleapis.com/grid-packages/lightning-ai-sphinx-theme/build-32.zip
+lai-sphinx-theme
diff --git a/requirements/base.txt b/requirements/base.txt
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/requirements/docs.txt b/requirements/docs.txt
index d68f16136aac2..d9da02513f816 100644
--- a/requirements/docs.txt
+++ b/requirements/docs.txt
@@ -5,9 +5,12 @@ pandoc>=1.0, <=2.2
docutils>=0.16, <0.20
sphinxcontrib-fulltoc>=1.0, <=1.2.0
sphinxcontrib-mockautodoc
+sphinx-autobuild
sphinx-autodoc-typehints>=1.16
sphinx-paramlinks>=0.5.1, <=0.5.4
sphinx-togglebutton>=0.2, <=0.3.2
sphinx-copybutton>=0.3, <=0.5.0
sphinx-multiproject
+sphinx-toolbox==3.2.0
+sphinx-rtd-dark-mode
jinja2>=3.0.0,<3.1.0
diff --git a/requirements/lit/docs.txt b/requirements/lit/docs.txt
index 54dd258e9620e..8885ea76a2dc3 100644
--- a/requirements/lit/docs.txt
+++ b/requirements/lit/docs.txt
@@ -3,7 +3,6 @@
ipython[notebook]
ipython_genutils
-sphinx-autobuild
-pt-lightning-sphinx-theme @ https://github.com/Lightning-AI/lightning_sphinx_theme/archive/master.zip
+lai-sphinx-theme
-r ../../_notebooks/.actions/requirements.txt
diff --git a/setup.cfg b/setup.cfg
index aa49d0fd4f07c..49691794c2c39 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -63,6 +63,8 @@ exclude =
build
temp
_notebooks
+ # FIXME!
+ docs/source-app/**
select = E,W,F
doctests = True
diff --git a/src/lightning/__version__.py b/src/lightning/__version__.py
index 5481ae875460d..0bf4a385a2903 100644
--- a/src/lightning/__version__.py
+++ b/src/lightning/__version__.py
@@ -1 +1 @@
-version = "1.8.0.post1"
+version = "1.9.0dev"
diff --git a/src/lightning_app/CHANGELOG.md b/src/lightning_app/CHANGELOG.md
index 5e5d116d702a5..5c750bb8f48a4 100644
--- a/src/lightning_app/CHANGELOG.md
+++ b/src/lightning_app/CHANGELOG.md
@@ -19,7 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Changed
--
+- Changed the `flow.flows` to be recursive wont to align the behavior with the `flow.works` ([#15466](https://github.com/Lightning-AI/lightning/pull/15466))
-
@@ -46,7 +46,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Fixed
--
+
+- Fixed writing app name and id in connect.txt file for the command CLI ([#15443](https://github.com/Lightning-AI/lightning/pull/15443))
-
@@ -75,6 +76,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Add a `JustPyFrontend` to ease UI creation with `https://github.com/justpy-org/justpy` ([#15002](https://github.com/Lightning-AI/lightning/pull/15002))
- Added a layout endpoint to the Rest API and enable to disable pulling or pushing to the state ([#15367](https://github.com/Lightning-AI/lightning/pull/15367)
- Added support for functions for `configure_api` and `configure_commands` to be executed in the Rest API process ([#15098](https://github.com/Lightning-AI/lightning/pull/15098)
+- Added support for accessing Lighting Apps via SSH ([#15310](https://github.com/Lightning-AI/lightning/pull/15310))
- Added support to start lightning app on cloud without needing to install dependencies locally ([#15019](https://github.com/Lightning-AI/lightning/pull/15019)
### Changed
diff --git a/src/lightning_app/__version__.py b/src/lightning_app/__version__.py
index 5481ae875460d..0bf4a385a2903 100644
--- a/src/lightning_app/__version__.py
+++ b/src/lightning_app/__version__.py
@@ -1 +1 @@
-version = "1.8.0.post1"
+version = "1.9.0dev"
diff --git a/src/lightning_app/cli/cmd_apps.py b/src/lightning_app/cli/cmd_apps.py
index 67164488e5c06..ec691f07a0142 100644
--- a/src/lightning_app/cli/cmd_apps.py
+++ b/src/lightning_app/cli/cmd_apps.py
@@ -4,6 +4,8 @@
from lightning_cloud.openapi import (
Externalv1LightningappInstance,
+ Externalv1Lightningwork,
+ V1GetClusterResponse,
V1LightningappInstanceState,
V1LightningappInstanceStatus,
)
@@ -22,12 +24,24 @@ class _AppManager:
def __init__(self) -> None:
self.api_client = LightningClient()
- def list(self, cluster_id: str = None, limit: int = 100) -> None:
+ def get_cluster(self, cluster_id: str) -> V1GetClusterResponse:
+ return self.api_client.cluster_service_get_cluster(id=cluster_id)
+
+ def get_app(self, app_id: str) -> Externalv1LightningappInstance:
+ project = _get_project(self.api_client)
+ return self.api_client.lightningapp_instance_service_get_lightningapp_instance(
+ project_id=project.project_id, id=app_id
+ )
+
+ def list_apps(
+ self, cluster_id: str = None, limit: int = 100, phase_in: List[str] = []
+ ) -> List[Externalv1LightningappInstance]:
project = _get_project(self.api_client)
kwargs = {
"project_id": project.project_id,
"limit": limit,
+ "phase_in": phase_in,
}
if cluster_id is not None:
kwargs["cluster_id"] = cluster_id
@@ -38,8 +52,16 @@ def list(self, cluster_id: str = None, limit: int = 100) -> None:
kwargs["page_token"] = resp.next_page_token
resp = self.api_client.lightningapp_instance_service_list_lightningapp_instances(**kwargs)
apps = apps + resp.lightningapps
+ return apps
+
+ def list_components(self, app_id: str) -> List[Externalv1Lightningwork]:
+ project = _get_project(self.api_client)
+ resp = self.api_client.lightningwork_service_list_lightningwork(project_id=project.project_id, app_id=app_id)
+ return resp.lightningworks
+
+ def list(self, cluster_id: str = None, limit: int = 100) -> None:
console = Console()
- console.print(_AppList(resp.lightningapps).as_table())
+ console.print(_AppList(self.list_apps(cluster_id=cluster_id, limit=limit)).as_table())
class _AppList(Formatable):
diff --git a/src/lightning_app/cli/commands/app_commands.py b/src/lightning_app/cli/commands/app_commands.py
index 73b94634ce487..c15a184aaeea2 100644
--- a/src/lightning_app/cli/commands/app_commands.py
+++ b/src/lightning_app/cli/commands/app_commands.py
@@ -94,6 +94,7 @@ def _handle_command_without_client(command: str, metadata: Dict, url: str) -> No
query_parameters = "&".join(provided_params)
resp = requests.post(url + f"/command/{command}?{query_parameters}")
assert resp.status_code == 200, resp.json()
+ print(resp.json())
def _handle_command_with_client(command: str, metadata: Dict, app_name: str, app_id: Optional[str], url: str):
diff --git a/src/lightning_app/cli/commands/connection.py b/src/lightning_app/cli/commands/connection.py
index ec31913c9cc16..5027b33e51f0f 100644
--- a/src/lightning_app/cli/commands/connection.py
+++ b/src/lightning_app/cli/commands/connection.py
@@ -146,7 +146,7 @@ def connect(app_name_or_id: str, yes: bool = False):
click.echo(f" lightning {pretty_command_name}")
with open(connected_file, "w") as f:
- f.write(app_name_or_id + "\n")
+ f.write(retriever.app_name + "\n")
f.write(retriever.app_id + "\n")
click.echo(" ")
click.echo(f"You are connected to the cloud Lightning App: {app_name_or_id}.")
diff --git a/src/lightning_app/cli/lightning_cli.py b/src/lightning_app/cli/lightning_cli.py
index b4509ca58f20f..658b088413180 100644
--- a/src/lightning_app/cli/lightning_cli.py
+++ b/src/lightning_app/cli/lightning_cli.py
@@ -1,16 +1,20 @@
import os
+import shutil
import sys
from pathlib import Path
from typing import Any, Tuple, Union
import arrow
import click
+import inquirer
import rich
-from lightning_cloud.openapi import Externalv1LightningappInstance
+from lightning_cloud.openapi import Externalv1LightningappInstance, V1LightningappInstanceState
+from lightning_cloud.openapi.rest import ApiException
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.cli.cmd_apps import _AppManager
from lightning_app.cli.cmd_clusters import AWSClusterManager
from lightning_app.cli.commands.app_commands import _run_app_command
from lightning_app.cli.commands.connection import (
@@ -54,11 +58,13 @@ def get_app_url(runtime_type: RuntimeType, *args: Any, need_credits: bool = Fals
def main() -> None:
- # Enforce running in PATH Python
- _check_environment_and_redirect()
+ # Check environment and versions if not in the cloud
+ if "LIGHTNING_APP_STATE_URL" not in os.environ:
+ # Enforce running in PATH Python
+ _check_environment_and_redirect()
- # Check for newer versions and upgrade
- _check_version_and_upgrade()
+ # Check for newer versions and upgrade
+ _check_version_and_upgrade()
# 1: Handle connection to a Lightning App.
if len(sys.argv) > 1 and sys.argv[1] in ("connect", "disconnect", "logout"):
@@ -352,6 +358,87 @@ def stop() -> None:
_main.add_command(cli_remove)
+@_main.command("ssh")
+@click.option(
+ "--app-name",
+ "app_name",
+ type=str,
+ default=None,
+ required=False,
+)
+@click.option(
+ "--component-name",
+ "component_name",
+ type=str,
+ default=None,
+ help="Specify which component to SSH into",
+)
+def ssh(app_name: str = None, component_name: str = None) -> None:
+ """SSH into a Lightning App."""
+
+ app_manager = _AppManager()
+ apps = app_manager.list_apps(phase_in=[V1LightningappInstanceState.RUNNING])
+ if len(apps) == 0:
+ raise click.ClickException("No running apps available. Start a Lightning App in the cloud to use this feature.")
+
+ available_app_names = [app.name for app in apps]
+ if app_name is None:
+ available_apps = [
+ inquirer.List(
+ "app_name",
+ message="What app to SSH into?",
+ choices=available_app_names,
+ ),
+ ]
+ app_name = inquirer.prompt(available_apps)["app_name"]
+ app_id = next((app.id for app in apps if app.name == app_name), None)
+ if app_id is None:
+ raise click.ClickException(
+ f"Unable to find a running app with name {app_name} in your account. "
+ + f"Available running apps are: {', '.join(available_app_names)}"
+ )
+ try:
+ instance = app_manager.get_app(app_id=app_id)
+ except ApiException:
+ raise click.ClickException("failed fetching app instance")
+
+ components = app_manager.list_components(app_id=app_id)
+ available_component_names = [work.name for work in components] + ["flow"]
+ if component_name is None:
+ available_components = [
+ inquirer.List(
+ "component_name",
+ message="Which component to SSH into?",
+ choices=available_component_names,
+ )
+ ]
+ component_name = inquirer.prompt(available_components)["component_name"]
+
+ component_id = None
+ if component_name == "flow":
+ component_id = f"lightningapp-{app_id}"
+ elif component_name is not None:
+ work_id = next((work.id for work in components if work.name == component_name), None)
+ if work_id is not None:
+ component_id = f"lightningwork-{work_id}"
+
+ if component_id is None:
+ raise click.ClickException(
+ f"Unable to find an app component with name {component_name}. "
+ f"Available components are: {', '.join(available_component_names)}"
+ )
+
+ app_cluster = app_manager.get_cluster(cluster_id=instance.spec.cluster_id)
+ ssh_endpoint = app_cluster.status.ssh_gateway_endpoint
+
+ ssh_path = shutil.which("ssh")
+ if ssh_path is None:
+ raise click.ClickException(
+ "Unable to find the ssh binary. You must install ssh first to use this functionality."
+ )
+ os.execv(ssh_path, ["-tt", f"{component_id}@{ssh_endpoint}"])
+
+
@_main.group()
def install() -> None:
"""Install a Lightning App and/or component."""
diff --git a/src/lightning_app/components/database/server.py b/src/lightning_app/components/database/server.py
index f2b6c0650ae35..a5499aaae17b8 100644
--- a/src/lightning_app/components/database/server.py
+++ b/src/lightning_app/components/database/server.py
@@ -1,6 +1,9 @@
import asyncio
import os
+import sqlite3
import sys
+import tempfile
+import threading
from typing import List, Optional, Type, Union
import uvicorn
@@ -38,6 +41,7 @@ def __init__(
self,
models: Union[Type["SQLModel"], List[Type["SQLModel"]]],
db_filename: str = "database.db",
+ store_interval: int = 10,
debug: bool = False,
) -> None:
"""The Database Component enables to interact with an SQLite database to store some structured information
@@ -48,6 +52,8 @@ def __init__(
Arguments:
models: A SQLModel or a list of SQLModels table to be added to the database.
db_filename: The name of the SQLite database.
+ store_interval: Time interval (in seconds) at which the database is periodically synchronized to the Drive.
+ Note that the database is also always synchronized on exit.
debug: Whether to run the database in debug mode.
Example::
@@ -132,18 +138,44 @@ class CounterModel(SQLModel, table=True):
"""
super().__init__(parallel=True, cloud_build_config=BuildConfig(["sqlmodel"]))
self.db_filename = db_filename
+ self._root_folder = os.path.dirname(db_filename)
self.debug = debug
+ self.store_interval = store_interval
self._models = models if isinstance(models, list) else [models]
- self.drive = None
+ self._store_thread = None
+ self._exit_event = None
+
+ def store_database(self):
+ with tempfile.TemporaryDirectory() as tmpdir:
+ tmp_db_filename = os.path.join(tmpdir, os.path.basename(self.db_filename))
+
+ source = sqlite3.connect(self.db_filename)
+ dest = sqlite3.connect(tmp_db_filename)
+
+ source.backup(dest)
+
+ source.close()
+ dest.close()
+
+ drive = Drive("lit://database", component_name=self.name, root_folder=tmpdir)
+ drive.put(os.path.basename(tmp_db_filename))
+
+ print("Stored the database to the Drive.")
+
+ def periodic_store_database(self, store_interval):
+ while not self._exit_event.is_set():
+ self.store_database()
+ self._exit_event.wait(store_interval)
def run(self, token: Optional[str] = None) -> None:
"""
Arguments:
token: Token used to protect the database access. Ensure you don't expose it through the App State.
"""
- self.drive = Drive("lit://database")
- if self.drive.list(component_name=self.name):
- self.drive.get(self.db_filename)
+ drive = Drive("lit://database", component_name=self.name, root_folder=self._root_folder)
+ filenames = drive.list(component_name=self.name)
+ if self.db_filename in filenames:
+ drive.get(self.db_filename)
print("Retrieved the database from Drive.")
app = FastAPI()
@@ -157,6 +189,10 @@ def run(self, token: Optional[str] = None) -> None:
sys.modules["uvicorn.main"].Server = _DatabaseUvicornServer
+ self._exit_event = threading.Event()
+ self._store_thread = threading.Thread(target=self.periodic_store_database, args=(self.store_interval,))
+ self._store_thread.start()
+
run(app, host=self.host, port=self.port, log_level="error")
def alive(self) -> bool:
@@ -173,5 +209,5 @@ def db_url(self) -> Optional[str]:
return self.internal_ip
def on_exit(self):
- self.drive.put(self.db_filename)
- print("Stored the database to the Drive.")
+ self._exit_event.set()
+ self.store_database()
diff --git a/src/lightning_app/core/app.py b/src/lightning_app/core/app.py
index 6c7b0062f8aea..caa9126b531b0 100644
--- a/src/lightning_app/core/app.py
+++ b/src/lightning_app/core/app.py
@@ -284,7 +284,7 @@ def check_error_queue(self) -> None:
@property
def flows(self) -> List["LightningFlow"]:
"""Returns all the flows defined within this application."""
- return [self.root] + self.root.get_all_children()
+ return list(self.root.flows.values())
@property
def works(self) -> List[LightningWork]:
diff --git a/src/lightning_app/core/flow.py b/src/lightning_app/core/flow.py
index e65d266c8479d..ac8a7ff325049 100644
--- a/src/lightning_app/core/flow.py
+++ b/src/lightning_app/core/flow.py
@@ -207,22 +207,19 @@ def _attach_backend(flow: "LightningFlow", backend):
"""Attach the backend to all flows and its children."""
flow._backend = backend
- for child_flow in flow.flows.values():
- LightningFlow._attach_backend(child_flow, backend)
-
- for struct_name in flow._structures:
- structure = getattr(flow, struct_name)
- for flow in structure.flows:
- LightningFlow._attach_backend(flow, backend)
- for work in structure.works:
- backend._wrap_run_method(_LightningAppRef().get_current(), work)
- work._backend = backend
-
for name in flow._structures:
getattr(flow, name)._backend = backend
- for work in flow.works(recurse=False):
- backend._wrap_run_method(_LightningAppRef().get_current(), work)
+ for child_flow in flow.flows.values():
+ child_flow._backend = backend
+ for name in child_flow._structures:
+ getattr(child_flow, name)._backend = backend
+
+ app = _LightningAppRef().get_current()
+
+ for child_work in flow.works():
+ child_work._backend = backend
+ backend._wrap_run_method(app, child_work)
def __getattr__(self, item):
if item in self.__dict__.get("_paths", {}):
@@ -274,12 +271,15 @@ def state_with_changes(self):
}
@property
- def flows(self):
+ def flows(self) -> Dict[str, "LightningFlow"]:
"""Return its children LightningFlow."""
- flows = {el: getattr(self, el) for el in sorted(self._flows)}
+ flows = {}
+ for el in sorted(self._flows):
+ flow = getattr(self, el)
+ flows[flow.name] = flow
+ flows.update(flow.flows)
for struct_name in sorted(self._structures):
- for flow in getattr(self, struct_name).flows:
- flows[flow.name] = flow
+ flows.update(getattr(self, struct_name).flows)
return flows
def works(self, recurse: bool = True) -> List[LightningWork]:
@@ -297,28 +297,7 @@ def works(self, recurse: bool = True) -> List[LightningWork]:
def named_works(self, recurse: bool = True) -> List[Tuple[str, LightningWork]]:
"""Return its :class:`~lightning_app.core.work.LightningWork` with their names."""
- named_works = [(el, getattr(self, el)) for el in sorted(self._works)]
- if not recurse:
- return named_works
- for child_name in sorted(self._flows):
- for w in getattr(self, child_name).works(recurse=recurse):
- named_works.append(w)
- for struct_name in sorted(self._structures):
- for w in getattr(self, struct_name).works:
- named_works.append((w.name, w))
- return named_works
-
- def get_all_children_(self, children):
- sorted_children = sorted(self._flows)
- children.extend([getattr(self, el) for el in sorted_children])
- for child in sorted_children:
- getattr(self, child).get_all_children_(children)
- return children
-
- def get_all_children(self):
- children = []
- self.get_all_children_(children)
- return children
+ return [(w.name, w) for w in self.works(recurse=recurse)]
def set_state(self, provided_state: Dict, recurse: bool = True) -> None:
"""Method to set the state to this LightningFlow, its children and
diff --git a/src/lightning_app/core/queues.py b/src/lightning_app/core/queues.py
index f752c6384bb30..9935fd5550fe7 100644
--- a/src/lightning_app/core/queues.py
+++ b/src/lightning_app/core/queues.py
@@ -234,6 +234,18 @@ def __init__(
self.redis = redis.Redis(host=host, port=port, password=password)
def put(self, item: Any) -> None:
+ from lightning_app import LightningWork
+
+ is_work = isinstance(item, LightningWork)
+
+ # TODO: Be careful to handle with a lock if another thread needs
+ # to access the work backend one day.
+ # The backend isn't picklable
+ # Raises a TypeError: cannot pickle '_thread.RLock' object
+ if is_work:
+ backend = item._backend
+ item._backend = None
+
value = pickle.dumps(item)
queue_len = self.length()
if queue_len >= WARNING_QUEUE_SIZE:
@@ -252,6 +264,10 @@ def put(self, item: Any) -> None:
"If the issue persists, please contact support@lightning.ai"
)
+ # The backend isn't pickable.
+ if is_work:
+ item._backend = backend
+
def get(self, timeout: int = None):
"""Returns the left most element of the redis queue.
diff --git a/src/lightning_app/structures/dict.py b/src/lightning_app/structures/dict.py
index b414269b93eec..aaf8a3c8298d0 100644
--- a/src/lightning_app/structures/dict.py
+++ b/src/lightning_app/structures/dict.py
@@ -86,12 +86,17 @@ def works(self):
@property
def flows(self):
from lightning_app import LightningFlow
-
- flows = []
- for flow in [item for item in self.values() if isinstance(item, LightningFlow)]:
- flows.append(flow)
- for child_flow in flow.flows:
- flows.append(child_flow)
+ from lightning_app.structures import Dict, List
+
+ flows = {}
+ for item in self.values():
+ if isinstance(item, LightningFlow):
+ flows[item.name] = item
+ for child_flow in item.flows.values():
+ flows[child_flow.name] = child_flow
+ if isinstance(item, (Dict, List)):
+ for child_flow in item.flows.values():
+ flows[child_flow.name] = child_flow
return flows
@property
diff --git a/src/lightning_app/structures/list.py b/src/lightning_app/structures/list.py
index cf691c98a8c38..f2ff9b4ff2ddf 100644
--- a/src/lightning_app/structures/list.py
+++ b/src/lightning_app/structures/list.py
@@ -89,12 +89,17 @@ def works(self):
@property
def flows(self):
from lightning_app import LightningFlow
-
- flows = []
- for flow in [item for item in self if isinstance(item, LightningFlow)]:
- flows.append(flow)
- for child_flow in flow.flows:
- flows.append(child_flow)
+ from lightning_app.structures import Dict, List
+
+ flows = {}
+ for item in self:
+ if isinstance(item, LightningFlow):
+ flows[item.name] = item
+ for child_flow in item.flows.values():
+ flows[child_flow.name] = child_flow
+ if isinstance(item, (Dict, List)):
+ for child_flow in item.flows.values():
+ flows[child_flow.name] = child_flow
return flows
@property
diff --git a/src/lightning_app/utilities/app_helpers.py b/src/lightning_app/utilities/app_helpers.py
index 5e68d6fcc1821..44f8e2bf6b63c 100644
--- a/src/lightning_app/utilities/app_helpers.py
+++ b/src/lightning_app/utilities/app_helpers.py
@@ -267,10 +267,12 @@ def _set_child_name(component: "Component", child: "Component", new_name: str) -
# the name changed, so recursively update the names of the children of this child
if isinstance(child, lightning_app.core.LightningFlow):
- for n, c in child.flows.items():
+ for n in child._flows:
+ c = getattr(child, n)
+ _set_child_name(child, c, n)
+ for n in child._works:
+ c = getattr(child, n)
_set_child_name(child, c, n)
- for n, w in child.named_works(recurse=False):
- _set_child_name(child, w, n)
for n in child._structures:
s = getattr(child, n)
_set_child_name(child, s, n)
diff --git a/src/lightning_app/utilities/cli_helpers.py b/src/lightning_app/utilities/cli_helpers.py
index 4b404ebf56661..2a2bdda831141 100644
--- a/src/lightning_app/utilities/cli_helpers.py
+++ b/src/lightning_app/utilities/cli_helpers.py
@@ -113,6 +113,7 @@ def __init__(
self.openapi = None
self.api_commands = None
self.app_id = None
+ self.app_name = None
home = os.path.expanduser("~")
if use_cache:
cache_openapi = os.path.join(home, ".lightning", "lightning_connection", "commands", "openapi.json")
@@ -210,6 +211,7 @@ def _collect_open_api_json(self):
self.url = app.status.url
self.openapi = resp.json()
self.app_id = app.id
+ self.app_name = app.name
def _arrow_time_callback(
diff --git a/src/lightning_app/utilities/tree.py b/src/lightning_app/utilities/tree.py
index f1b9f3d4468ec..26eaac0194b15 100644
--- a/src/lightning_app/utilities/tree.py
+++ b/src/lightning_app/utilities/tree.py
@@ -17,16 +17,6 @@ def breadth_first(root: "Component", types: Type["ComponentTuple"] = None):
yield from _BreadthFirstVisitor(root, types)
-def depth_first(root: "Component", types: Type["ComponentTuple"] = None):
- """Returns a generator that walks through the tree of components depth-first.
-
- Arguments:
- root: The root component of the tree
- types: If provided, only the component types in this list will be visited.
- """
- yield from _DepthFirstVisitor(root, types)
-
-
class _BreadthFirstVisitor:
def __init__(self, root: "Component", types: Type["ComponentTuple"] = None) -> None:
self.queue = [root]
@@ -36,11 +26,23 @@ def __iter__(self):
return self
def __next__(self):
+ from lightning_app.structures import Dict
+
while self.queue:
component = self.queue.pop(0)
if isinstance(component, lightning_app.LightningFlow):
- self.queue += list(component.flows.values())
+ components = [getattr(component, el) for el in sorted(component._flows)]
+ for struct_name in sorted(component._structures):
+ structure = getattr(component, struct_name)
+ if isinstance(structure, Dict):
+ values = sorted(structure.items(), key=lambda x: x[0])
+ else:
+ values = sorted(((v.name, v) for v in structure), key=lambda x: x[0])
+ for _, value in values:
+ if isinstance(value, lightning_app.LightningFlow):
+ components.append(value)
+ self.queue += components
self.queue += component.works(recurse=False)
if any(isinstance(component, t) for t in self.types):
diff --git a/src/lightning_lite/CHANGELOG.md b/src/lightning_lite/CHANGELOG.md
index 6211a869426a7..a4c4bd26981e8 100644
--- a/src/lightning_lite/CHANGELOG.md
+++ b/src/lightning_lite/CHANGELOG.md
@@ -48,7 +48,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Fixed
--
+- Fix an issue with the SLURM `srun` detection causing permission errors ([#15485](https://github.com/Lightning-AI/lightning/issues/15485))
-
diff --git a/src/lightning_lite/__version__.py b/src/lightning_lite/__version__.py
index 5481ae875460d..0bf4a385a2903 100644
--- a/src/lightning_lite/__version__.py
+++ b/src/lightning_lite/__version__.py
@@ -1 +1 @@
-version = "1.8.0.post1"
+version = "1.9.0dev"
diff --git a/src/lightning_lite/plugins/environments/slurm.py b/src/lightning_lite/plugins/environments/slurm.py
index 18ba1cafe7cde..b7a0a1247bedb 100644
--- a/src/lightning_lite/plugins/environments/slurm.py
+++ b/src/lightning_lite/plugins/environments/slurm.py
@@ -15,8 +15,8 @@
import logging
import os
import re
+import shutil
import signal
-import subprocess
import sys
from typing import Optional
@@ -160,10 +160,8 @@ def _validate_srun_used() -> None:
"""
if _IS_WINDOWS:
return
- try:
- srun_exists = subprocess.call(["command", "-v", "srun"]) == 0
- except FileNotFoundError:
- srun_exists = False
+
+ srun_exists = shutil.which("srun") is not None
if srun_exists and not _is_srun_used():
hint = " ".join(["srun", os.path.basename(sys.executable), *sys.argv])[:64]
rank_zero_warn(
diff --git a/src/pytorch_lightning/__version__.py b/src/pytorch_lightning/__version__.py
index 5481ae875460d..0bf4a385a2903 100644
--- a/src/pytorch_lightning/__version__.py
+++ b/src/pytorch_lightning/__version__.py
@@ -1 +1 @@
-version = "1.8.0.post1"
+version = "1.9.0dev"
diff --git a/tests/tests_app/cli/test_cli.py b/tests/tests_app/cli/test_cli.py
index 044b8542da073..9ccf543f9dac7 100644
--- a/tests/tests_app/cli/test_cli.py
+++ b/tests/tests_app/cli/test_cli.py
@@ -60,6 +60,7 @@ def test_main_lightning_cli_no_arguments():
assert "delete " in res
assert "create " in res
assert "show " in res
+ assert "ssh " in res
assert "add " in res
assert "remove " in res
@@ -74,6 +75,7 @@ def test_main_lightning_cli_help():
assert "delete " in res
assert "create " in res
assert "show " in res
+ assert "ssh " in res
assert "add " in res
assert "remove " in res
diff --git a/tests/tests_app/cli/test_cloud_cli.py b/tests/tests_app/cli/test_cloud_cli.py
index c6a562c8143ba..266df96f5ed52 100644
--- a/tests/tests_app/cli/test_cloud_cli.py
+++ b/tests/tests_app/cli/test_cloud_cli.py
@@ -170,22 +170,23 @@ def run():
cloud.Body8.assert_called_once()
+class HttpHeaderDict(dict):
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.reason = kwargs["reason"]
+ self.status = kwargs["status"]
+ self.data = kwargs["data"]
+
+ def getheaders(self):
+ return {}
+
+
class FakeLightningClientException(FakeLightningClient):
def __init__(self, *args, message, api_client=None, **kwargs):
super().__init__(*args, api_client=api_client, **kwargs)
self.message = message
def lightningapp_v2_service_list_lightningapps_v2(self, *args, **kwargs):
- class HttpHeaderDict(dict):
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
- self.reason = ""
- self.status = 500
- self.data = kwargs["data"]
-
- def getheaders(self):
- return {}
-
raise ApiException(
http_resp=HttpHeaderDict(
data=self.message,
diff --git a/tests/tests_app/cli/test_cmd_apps.py b/tests/tests_app/cli/test_cmd_apps.py
index 7d89dbc75b0a5..1cfb35893cc7d 100644
--- a/tests/tests_app/cli/test_cmd_apps.py
+++ b/tests/tests_app/cli/test_cmd_apps.py
@@ -78,8 +78,8 @@ def test_list_all_apps_paginated(list_memberships: mock.MagicMock, list_instance
list_memberships.assert_called_once()
assert list_instances.mock_calls == [
- mock.call(project_id="default-project", limit=100),
- mock.call(project_id="default-project", page_token="page-2", limit=100),
+ mock.call(project_id="default-project", limit=100, phase_in=[]),
+ mock.call(project_id="default-project", page_token="page-2", limit=100, phase_in=[]),
]
@@ -94,7 +94,7 @@ def test_list_all_apps(list_memberships: mock.MagicMock, list_instances: mock.Ma
cluster_manager.list()
list_memberships.assert_called_once()
- list_instances.assert_called_once_with(project_id="default-project", limit=100)
+ list_instances.assert_called_once_with(project_id="default-project", limit=100, phase_in=[])
@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
@@ -108,4 +108,4 @@ def test_list_apps_on_cluster(list_memberships: mock.MagicMock, list_instances:
cluster_manager.list(cluster_id="12345")
list_memberships.assert_called_once()
- list_instances.assert_called_once_with(project_id="default-project", cluster_id="12345", limit=100)
+ list_instances.assert_called_once_with(project_id="default-project", cluster_id="12345", limit=100, phase_in=[])
diff --git a/tests/tests_app/cli/test_cmd_ssh.py b/tests/tests_app/cli/test_cmd_ssh.py
new file mode 100644
index 0000000000000..b553e11cb62bb
--- /dev/null
+++ b/tests/tests_app/cli/test_cmd_ssh.py
@@ -0,0 +1,159 @@
+import shutil
+from unittest import mock
+from unittest.mock import MagicMock
+
+from click.testing import CliRunner
+from lightning_cloud.openapi import (
+ Externalv1LightningappInstance,
+ Externalv1Lightningwork,
+ V1ClusterStatus,
+ V1GetClusterResponse,
+ V1LightningappInstanceSpec,
+)
+
+from lightning_app.cli.lightning_cli import ssh
+
+
+@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
+@mock.patch("inquirer.prompt")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_apps")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_components")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_app")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_cluster")
+@mock.patch("os.execv")
+def test_ssh_no_arguments(
+ os_execv: mock.MagicMock,
+ get_cluster: mock.MagicMock,
+ get_app: mock.MagicMock,
+ list_components: mock.MagicMock,
+ list_apps: mock.MagicMock,
+ list_prompt: mock.MagicMock,
+):
+ app_instance = Externalv1LightningappInstance(
+ id="test1234",
+ name="test",
+ spec=V1LightningappInstanceSpec(cluster_id="clusterA"),
+ )
+ list_apps.return_value = [app_instance]
+ list_components.return_value = [Externalv1Lightningwork(id="work1234", name="root.server")]
+ get_app.return_value = app_instance
+ get_cluster.return_value = V1GetClusterResponse(status=V1ClusterStatus(ssh_gateway_endpoint="ssh.lightning.ai"))
+ list_prompt.side_effect = [{"app_name": "test"}, {"component_name": "root.server"}]
+
+ runner = CliRunner()
+ runner.invoke(ssh, [])
+
+ ssh_path = shutil.which("ssh")
+ os_execv.assert_called_once_with(ssh_path, ["-tt", "lightningwork-work1234@ssh.lightning.ai"])
+
+
+@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
+@mock.patch("inquirer.prompt")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_apps")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_components")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_app")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_cluster")
+@mock.patch("os.execv")
+def test_ssh_app_preselected(
+ os_execv: mock.MagicMock,
+ get_cluster: mock.MagicMock,
+ get_app: mock.MagicMock,
+ list_components: mock.MagicMock,
+ list_apps: mock.MagicMock,
+ list_prompt: mock.MagicMock,
+):
+ app_instance = Externalv1LightningappInstance(
+ id="test1234",
+ name="test",
+ spec=V1LightningappInstanceSpec(cluster_id="clusterA"),
+ )
+ list_apps.return_value = [app_instance]
+ list_components.return_value = [Externalv1Lightningwork(id="work1234", name="root.server")]
+ get_app.return_value = app_instance
+ get_cluster.return_value = V1GetClusterResponse(status=V1ClusterStatus(ssh_gateway_endpoint="ssh.lightning.ai"))
+ list_prompt.return_value = {"component_name": "root.server"}
+
+ runner = CliRunner()
+ runner.invoke(ssh, ["--app-name", "test"])
+
+ ssh_path = shutil.which("ssh")
+ os_execv.assert_called_once_with(ssh_path, ["-tt", "lightningwork-work1234@ssh.lightning.ai"])
+
+
+@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_apps")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_components")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_app")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_cluster")
+@mock.patch("os.execv")
+def test_ssh_app_and_component_preselected(
+ os_execv: mock.MagicMock,
+ get_cluster: mock.MagicMock,
+ get_app: mock.MagicMock,
+ list_components: mock.MagicMock,
+ list_apps: mock.MagicMock,
+):
+ app_instance = Externalv1LightningappInstance(
+ id="test1234",
+ name="test",
+ spec=V1LightningappInstanceSpec(cluster_id="clusterA"),
+ )
+ list_apps.return_value = [app_instance]
+ list_components.return_value = [Externalv1Lightningwork(id="work1234", name="root.server")]
+ get_app.return_value = app_instance
+ get_cluster.return_value = V1GetClusterResponse(status=V1ClusterStatus(ssh_gateway_endpoint="ssh.lightning.ai"))
+
+ runner = CliRunner()
+ runner.invoke(ssh, ["--app-name", "test", "--component-name", "root.server"])
+
+ ssh_path = shutil.which("ssh")
+ os_execv.assert_called_once_with(ssh_path, ["-tt", "lightningwork-work1234@ssh.lightning.ai"])
+
+
+@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_apps")
+@mock.patch("click.ClickException")
+def test_ssh_unknown_app(
+ click_exception: mock.MagicMock,
+ list_apps: mock.MagicMock,
+):
+ app_instance = Externalv1LightningappInstance(
+ id="test1234",
+ name="test-different-name",
+ spec=V1LightningappInstanceSpec(cluster_id="clusterA"),
+ )
+ list_apps.return_value = [app_instance]
+
+ runner = CliRunner()
+ runner.invoke(ssh, ["--app-name", "unknown-app-name"])
+
+ click_exception.assert_called_once()
+
+
+@mock.patch("lightning_cloud.login.Auth.authenticate", MagicMock())
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_apps")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.list_components")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_app")
+@mock.patch("lightning_app.cli.cmd_apps._AppManager.get_cluster")
+@mock.patch("click.ClickException")
+def test_ssh_unknown_component(
+ click_exception: mock.MagicMock,
+ get_cluster: mock.MagicMock,
+ get_app: mock.MagicMock,
+ list_components: mock.MagicMock,
+ list_apps: mock.MagicMock,
+):
+ app_instance = Externalv1LightningappInstance(
+ id="test1234",
+ name="test",
+ spec=V1LightningappInstanceSpec(cluster_id="clusterA"),
+ )
+ list_apps.return_value = [app_instance]
+ list_components.return_value = [Externalv1Lightningwork(id="work1234", name="root.server")]
+ get_app.return_value = app_instance
+ get_cluster.return_value = V1GetClusterResponse(status=V1ClusterStatus(ssh_gateway_endpoint="ssh.lightning.ai"))
+
+ runner = CliRunner()
+ runner.invoke(ssh, ["--app-name", "test", "--component-name", "rot.server"])
+
+ click_exception.assert_called_once()
diff --git a/tests/tests_app/components/database/test_client_server.py b/tests/tests_app/components/database/test_client_server.py
index b36940f3ac7d1..330b5439eca4b 100644
--- a/tests/tests_app/components/database/test_client_server.py
+++ b/tests/tests_app/components/database/test_client_server.py
@@ -1,5 +1,7 @@
import os
import sys
+import tempfile
+import time
from pathlib import Path
from time import sleep
from typing import List, Optional
@@ -123,9 +125,10 @@ def test_work_database_restart():
id = str(uuid4()).split("-")[0]
class Flow(LightningFlow):
- def __init__(self, restart=False):
+ def __init__(self, db_root=".", restart=False):
super().__init__()
- self.db = Database(db_filename=id, models=[TestConfig])
+ self._db_filename = os.path.join(db_root, id)
+ self.db = Database(db_filename=self._db_filename, models=[TestConfig])
self._client = None
self.restart = restart
@@ -141,22 +144,57 @@ def run(self):
self._client.insert(TestConfig(name="echo", secrets=[Secret(name="example", value="secret")]))
self._exit()
else:
- assert os.path.exists(id)
+ assert os.path.exists(self._db_filename)
assert len(self._client.select_all()) == 1
self._exit()
- app = LightningApp(Flow())
- MultiProcessRuntime(app).dispatch()
+ with tempfile.TemporaryDirectory() as tmpdir:
+ app = LightningApp(Flow(db_root=tmpdir))
+ MultiProcessRuntime(app).dispatch()
+
+ # Note: Waiting for SIGTERM signal to be handled
+ sleep(2)
+
+ app = LightningApp(Flow(db_root=tmpdir, restart=True))
+ MultiProcessRuntime(app).dispatch()
+
+ # Note: Waiting for SIGTERM signal to be handled
+ sleep(2)
+
+
+@pytest.mark.skipif(sys.platform == "win32", reason="currently not supported for windows.")
+@pytest.mark.skipif(not _is_sqlmodel_available(), reason="sqlmodel is required for this test.")
+def test_work_database_periodic_store():
+
+ id = str(uuid4()).split("-")[0]
+
+ class Flow(LightningFlow):
+ def __init__(self, db_root="."):
+ super().__init__()
+ self._db_filename = os.path.join(db_root, id)
+ self.db = Database(db_filename=self._db_filename, models=[TestConfig], store_interval=1)
+ self._client = None
+ self._start_time = None
+
+ def run(self):
+ self.db.run()
- # Note: Waiting for SIGTERM signal to be handled
- sleep(2)
+ if not self.db.alive():
+ return
+ elif not self._client:
+ self._client = DatabaseClient(self.db.db_url, None, model=TestConfig)
- os.remove(id)
+ if self._start_time is None:
+ self._client.insert(TestConfig(name="echo", secrets=[Secret(name="example", value="secret")]))
+ self._start_time = time.time()
+ elif time.time() - self._start_time > 2:
+ assert os.path.exists(self._db_filename)
+ assert len(self._client.select_all()) == 1
+ self._exit()
- app = LightningApp(Flow(restart=True))
- MultiProcessRuntime(app).dispatch()
+ with tempfile.TemporaryDirectory() as tmpdir:
- # Note: Waiting for SIGTERM signal to be handled
- sleep(2)
+ app = LightningApp(Flow(tmpdir))
+ MultiProcessRuntime(app).dispatch()
- os.remove(id)
+ sleep(2)
diff --git a/tests/tests_app/core/lightning_app/test_configure_layout.py b/tests/tests_app/core/lightning_app/test_configure_layout.py
index 6595d28286095..5574356fdf451 100644
--- a/tests/tests_app/core/lightning_app/test_configure_layout.py
+++ b/tests/tests_app/core/lightning_app/test_configure_layout.py
@@ -126,9 +126,9 @@ def __init__(self):
root = TestContentComponent()
LightningApp(root)
assert root._layout == [
- dict(name="component0", content="root.component0"),
- dict(name="component1", content="root.component1"),
- dict(name="component2", content="root.component2"),
+ dict(name="root.component0", content="root.component0"),
+ dict(name="root.component1", content="root.component1"),
+ dict(name="root.component2", content="root.component2"),
]
diff --git a/tests/tests_app/core/test_lightning_flow.py b/tests/tests_app/core/test_lightning_flow.py
index 8089f2f77e728..c0cf780dc5eff 100644
--- a/tests/tests_app/core/test_lightning_flow.py
+++ b/tests/tests_app/core/test_lightning_flow.py
@@ -15,6 +15,8 @@
from lightning_app.runners import MultiProcessRuntime, SingleProcessRuntime
from lightning_app.storage import Path
from lightning_app.storage.path import _storage_root_dir
+from lightning_app.structures import Dict as LDict
+from lightning_app.structures import List as LList
from lightning_app.testing.helpers import EmptyFlow, EmptyWork
from lightning_app.utilities.app_helpers import (
_delta_to_app_state_delta,
@@ -307,7 +309,7 @@ def run(self):
self._exit()
flow_a = Flow_A()
- assert flow_a.named_works() == [("work_a", flow_a.work_a), ("work_b", flow_a.work_b)]
+ assert flow_a.named_works() == [("root.work_a", flow_a.work_a), ("root.work_b", flow_a.work_b)]
assert flow_a.works() == [flow_a.work_a, flow_a.work_b]
state = {
"vars": {"counter": 0, "_layout": ANY, "_paths": {}},
@@ -780,3 +782,80 @@ def test_lightning_flow_reload():
flow = RootFlowReload2()
with pytest.raises(ValueError, match="The component flow_2 wasn't instantiated for the component root"):
_load_state_dict(flow, state)
+
+
+class NestedFlow(LightningFlow):
+ def __init__(self):
+ super().__init__()
+ self.flows_dict = LDict(**{"a": EmptyFlow()})
+ self.flows_list = LList(*[EmptyFlow()])
+ self.flow = EmptyFlow()
+ assert list(self.flows) == ["root.flow", "root.flows_dict.a", "root.flows_list.0"]
+ self.w = EmptyWork()
+
+ def run(self):
+ pass
+
+
+class FlowNested2(LightningFlow):
+ def __init__(self):
+ super().__init__()
+ self.flow3 = EmptyFlow()
+ self.w = EmptyWork()
+
+ def run(self):
+ pass
+
+
+class FlowCollection(LightningFlow):
+ def __init__(self):
+ super().__init__()
+ self.flow = EmptyFlow()
+ assert self.flow.name == "root.flow"
+ self.flow2 = FlowNested2()
+ assert list(self.flow2.flows) == ["root.flow2.flow3"]
+ self.flows_dict = LDict(**{"a": NestedFlow()})
+ assert list(self.flows_dict.flows) == [
+ "root.flows_dict.a",
+ "root.flows_dict.a.flow",
+ "root.flows_dict.a.flows_dict.a",
+ "root.flows_dict.a.flows_list.0",
+ ]
+ self.flows_list = LList(*[NestedFlow()])
+ assert list(self.flows_list.flows) == [
+ "root.flows_list.0",
+ "root.flows_list.0.flow",
+ "root.flows_list.0.flows_dict.a",
+ "root.flows_list.0.flows_list.0",
+ ]
+ self.w = EmptyWork()
+
+ def run(self):
+ pass
+
+
+def test_lightning_flow_flows_and_works():
+
+ flow = FlowCollection()
+ app = LightningApp(flow)
+
+ assert list(app.root.flows.keys()) == [
+ "root.flow",
+ "root.flow2",
+ "root.flow2.flow3",
+ "root.flows_dict.a",
+ "root.flows_dict.a.flow",
+ "root.flows_dict.a.flows_dict.a",
+ "root.flows_dict.a.flows_list.0",
+ "root.flows_list.0",
+ "root.flows_list.0.flow",
+ "root.flows_list.0.flows_dict.a",
+ "root.flows_list.0.flows_list.0",
+ ]
+
+ assert [w[0] for w in app.root.named_works()] == [
+ "root.w",
+ "root.flow2.w",
+ "root.flows_dict.a.w",
+ "root.flows_list.0.w",
+ ]
diff --git a/tests/tests_app/utilities/test_load_app.py b/tests/tests_app/utilities/test_load_app.py
index dd5d8b136d555..2fdba91762f51 100644
--- a/tests/tests_app/utilities/test_load_app.py
+++ b/tests/tests_app/utilities/test_load_app.py
@@ -30,12 +30,6 @@ def test_extract_metadata_from_component():
app = load_app_from_file(os.path.join(test_script_dir, "app_metadata.py"))
metadata = extract_metadata_from_app(app)
assert metadata == [
- {
- "affiliation": ["root"],
- "cls_name": "RootFlow",
- "module": "__main__",
- "docstring": "RootFlow.",
- },
{
"affiliation": ["root", "flow_a_1"],
"cls_name": "FlowA",
@@ -48,8 +42,16 @@ def test_extract_metadata_from_component():
"module": "__main__",
"docstring": "WorkA.",
"local_build_config": {"__build_config__": ANY},
- "cloud_build_config": {"__build_config__": ANY},
- "cloud_compute": ANY,
+ "cloud_build_config": {"__build_config__": {"requirements": [], "dockerfile": [], "image": None}},
+ "cloud_compute": {
+ "type": "__cloud_compute__",
+ "name": "default",
+ "disk_size": 0,
+ "idle_timeout": None,
+ "shm_size": 0,
+ "mounts": None,
+ "_internal_id": "default",
+ },
},
{
"affiliation": ["root", "flow_a_2"],
@@ -62,23 +64,34 @@ def test_extract_metadata_from_component():
"cls_name": "WorkA",
"module": "__main__",
"docstring": "WorkA.",
- "local_build_config": {"__build_config__": ANY},
- "cloud_build_config": {"__build_config__": ANY},
- "cloud_compute": ANY,
- },
- {
- "affiliation": ["root", "flow_b"],
- "cls_name": "FlowB",
- "module": "__main__",
- "docstring": "FlowB.",
+ "local_build_config": {"__build_config__": {"requirements": [], "dockerfile": [], "image": None}},
+ "cloud_build_config": {"__build_config__": {"requirements": [], "dockerfile": [], "image": None}},
+ "cloud_compute": {
+ "type": "__cloud_compute__",
+ "name": "default",
+ "disk_size": 0,
+ "idle_timeout": None,
+ "shm_size": 0,
+ "mounts": None,
+ "_internal_id": "default",
+ },
},
+ {"affiliation": ["root", "flow_b"], "cls_name": "FlowB", "module": "__main__", "docstring": "FlowB."},
{
"affiliation": ["root", "flow_b", "work_b"],
"cls_name": "WorkB",
"module": "__main__",
"docstring": "WorkB.",
- "local_build_config": {"__build_config__": ANY},
- "cloud_build_config": {"__build_config__": ANY},
- "cloud_compute": ANY,
+ "local_build_config": {"__build_config__": {"requirements": [], "dockerfile": [], "image": None}},
+ "cloud_build_config": {"__build_config__": {"requirements": [], "dockerfile": [], "image": None}},
+ "cloud_compute": {
+ "type": "__cloud_compute__",
+ "name": "gpu",
+ "disk_size": 0,
+ "idle_timeout": None,
+ "shm_size": 0,
+ "mounts": None,
+ "_internal_id": ANY,
+ },
},
]
diff --git a/tests/tests_app/utilities/test_tree.py b/tests/tests_app/utilities/test_tree.py
index 6d69e40236440..1c5670be6f951 100644
--- a/tests/tests_app/utilities/test_tree.py
+++ b/tests/tests_app/utilities/test_tree.py
@@ -2,7 +2,7 @@
from lightning_app import LightningFlow, LightningWork
from lightning_app.testing.helpers import EmptyFlow, EmptyWork
-from lightning_app.utilities.tree import breadth_first, depth_first
+from lightning_app.utilities.tree import breadth_first
class LeafFlow(EmptyFlow):
@@ -35,74 +35,6 @@ def __init__(self):
self.mixed_right = SimpleFlowTree()
-@pytest.mark.parametrize(
- "input_tree, types,expected_sequence",
- [
- (LeafFlow(), (LightningFlow,), ["root"]),
- (LeafWork(), (LightningFlow,), []),
- (
- SimpleFlowTree(),
- (LightningFlow,),
- [
- "root",
- "root.simple_flow_right",
- "root.simple_flow_left",
- ],
- ),
- (SimpleWorkTree(), (LightningFlow,), ["root"]),
- (
- SimpleWorkTree(),
- (LightningFlow, LightningWork),
- [
- "root",
- "root.simple_work_right",
- "root.simple_work_left",
- ],
- ),
- (
- MixedTree(),
- (LightningFlow,),
- [
- "root",
- "root.work_tree",
- "root.mixed_right",
- "root.mixed_right.simple_flow_right",
- "root.mixed_right.simple_flow_left",
- "root.mixed_left",
- "root.mixed_left.simple_flow_right",
- "root.mixed_left.simple_flow_left",
- ],
- ),
- (
- MixedTree(),
- (LightningWork,),
- [
- "root.work_tree.simple_work_right",
- "root.work_tree.simple_work_left",
- ],
- ),
- (
- MixedTree(),
- (LightningFlow, LightningWork),
- [
- "root",
- "root.work_tree",
- "root.work_tree.simple_work_right",
- "root.work_tree.simple_work_left",
- "root.mixed_right",
- "root.mixed_right.simple_flow_right",
- "root.mixed_right.simple_flow_left",
- "root.mixed_left",
- "root.mixed_left.simple_flow_right",
- "root.mixed_left.simple_flow_left",
- ],
- ),
- ],
-)
-def test_depth_first(input_tree, types, expected_sequence):
- assert list(node.name for node in depth_first(input_tree, types=types)) == expected_sequence
-
-
@pytest.mark.parametrize(
"input_tree, types,expected_sequence",
[
diff --git a/tests/tests_lite/plugins/environments/test_slurm.py b/tests/tests_lite/plugins/environments/test_slurm.py
index 281e237d36f8e..768e1f468da99 100644
--- a/tests/tests_lite/plugins/environments/test_slurm.py
+++ b/tests/tests_lite/plugins/environments/test_slurm.py
@@ -126,7 +126,7 @@ def test_srun_available_and_not_used(monkeypatch):
expected = "`srun` .* available .* but is not used. HINT: .* srun python train.py --lr 0.01"
# pretend `srun` is available
- with mock.patch("lightning_lite.plugins.environments.slurm.subprocess.call", return_value=0):
+ with mock.patch("lightning_lite.plugins.environments.slurm.shutil.which", return_value="/usr/bin/srun"):
with pytest.warns(PossibleUserWarning, match=expected):
SLURMEnvironment()