Skip to content

Commit f0b462e

Browse files
tchatonthomas
authored andcommitted
[App] Add display name property to the work (#16095)
Co-authored-by: thomas <[email protected]>
1 parent f407c9c commit f0b462e

File tree

10 files changed

+102
-10
lines changed

10 files changed

+102
-10
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
venv/

examples/app_display_name/app.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import lightning as L
2+
3+
4+
class Work(L.LightningWork):
5+
def __init__(self, start_with_flow=True):
6+
super().__init__(start_with_flow=start_with_flow)
7+
8+
def run(self):
9+
pass
10+
11+
12+
class Flow(L.LightningFlow):
13+
def __init__(self):
14+
super().__init__()
15+
self.w = Work()
16+
self.w1 = Work(start_with_flow=False)
17+
self.w.display_name = "My Custom Name" # Not supported yet
18+
self.w1.display_name = "My Custom Name 1"
19+
20+
def run(self):
21+
self.w.run()
22+
self.w1.run()
23+
24+
25+
app = L.LightningApp(Flow())

src/lightning_app/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
1616

1717
- Added more datatypes to serving component ([#16018](https://github.com/Lightning-AI/lightning/pull/16018))
1818

19+
- Added `display_name` property to LightningWork for the cloud ([#16095](https://github.com/Lightning-AI/lightning/pull/16095))
20+
21+
1922
### Changed
2023

2124
-

src/lightning_app/api/http_methods.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from typing import Any, Callable, Dict, List, Optional
99
from uuid import uuid4
1010

11-
from fastapi import FastAPI, HTTPException, Request
11+
from fastapi import FastAPI, HTTPException, Request, status
1212
from lightning_utilities.core.apply_func import apply_to_collection
1313

1414
from lightning_app.api.request_types import _APIRequest, _CommandRequest, _RequestResponse
@@ -170,7 +170,10 @@ async def fn(*args, **kwargs):
170170
while request_id not in responses_store:
171171
await asyncio.sleep(0.01)
172172
if (time.time() - t0) > self.timeout:
173-
raise Exception("The response was never received.")
173+
raise HTTPException(
174+
status.HTTP_500_INTERNAL_SERVER_ERROR,
175+
detail="The response was never received.",
176+
)
174177

175178
logger.debug(f"Processed request {request_id} for route: {self.route}")
176179

src/lightning_app/core/work.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,16 @@ def __init__(
119119
" in the next version. Use `cache_calls` instead."
120120
)
121121
self._cache_calls = run_once if run_once is not None else cache_calls
122-
self._state = {"_host", "_port", "_url", "_future_url", "_internal_ip", "_restarting", "_cloud_compute"}
122+
self._state = {
123+
"_host",
124+
"_port",
125+
"_url",
126+
"_future_url",
127+
"_internal_ip",
128+
"_restarting",
129+
"_cloud_compute",
130+
"_display_name",
131+
}
123132
self._parallel = parallel
124133
self._host: str = host
125134
self._port: Optional[int] = port
@@ -129,6 +138,7 @@ def __init__(
129138
# setattr_replacement is used by the multiprocessing runtime to send the latest changes to the main coordinator
130139
self._setattr_replacement: Optional[Callable[[str, Any], None]] = None
131140
self._name = ""
141+
self._display_name = ""
132142
# The ``self._calls`` is used to track whether the run
133143
# method with a given set of input arguments has already been called.
134144
# Example of its usage:
@@ -207,6 +217,22 @@ def name(self):
207217
"""Returns the name of the LightningWork."""
208218
return self._name
209219

220+
@property
221+
def display_name(self):
222+
"""Returns the display name of the LightningWork in the cloud.
223+
224+
The display name needs to set before the run method of the work is called.
225+
"""
226+
return self._display_name
227+
228+
@display_name.setter
229+
def display_name(self, display_name: str):
230+
"""Sets the display name of the LightningWork in the cloud."""
231+
if not self.has_started:
232+
self._display_name = display_name
233+
elif self._display_name != display_name:
234+
raise RuntimeError("The display name can be set only before the work has started.")
235+
210236
@property
211237
def cache_calls(self) -> bool:
212238
"""Returns whether the ``run`` method should cache its input arguments and not run again when provided with

src/lightning_app/utilities/frontend.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ def update_index_file(ui_root: str, info: Optional[AppInfo] = None, root_path: s
2222
entry_file = Path(ui_root) / "index.html"
2323
original_file = Path(ui_root) / "index.original.html"
2424

25-
if not original_file.exists():
26-
shutil.copyfile(entry_file, original_file) # keep backup
27-
else:
28-
# revert index.html in case it was modified after creating original.html
29-
shutil.copyfile(original_file, entry_file)
25+
if root_path:
26+
if not original_file.exists():
27+
shutil.copyfile(entry_file, original_file) # keep backup
28+
else:
29+
# revert index.html in case it was modified after creating original.html
30+
shutil.copyfile(original_file, entry_file)
3031

3132
if info:
3233
with original_file.open() as f:

tests/tests_app/core/test_lightning_app.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def test_simple_app(tmpdir):
124124
"_paths": {},
125125
"_port": None,
126126
"_restarting": False,
127+
"_display_name": "",
127128
},
128129
"calls": {"latest_call_hash": None},
129130
"changes": {},
@@ -140,6 +141,7 @@ def test_simple_app(tmpdir):
140141
"_paths": {},
141142
"_port": None,
142143
"_restarting": False,
144+
"_display_name": "",
143145
},
144146
"calls": {"latest_call_hash": None},
145147
"changes": {},
@@ -969,7 +971,7 @@ def run(self):
969971
def test_state_size_constant_growth():
970972
app = LightningApp(SizeFlow())
971973
MultiProcessRuntime(app, start_server=False).dispatch()
972-
assert app.root._state_sizes[0] <= 7824
974+
assert app.root._state_sizes[0] <= 7888
973975
assert app.root._state_sizes[20] <= 26500
974976

975977

tests/tests_app/core/test_lightning_flow.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ def run(self):
329329
"_paths": {},
330330
"_restarting": False,
331331
"_internal_ip": "",
332+
"_display_name": "",
332333
"_cloud_compute": {
333334
"type": "__cloud_compute__",
334335
"name": "default",
@@ -352,6 +353,7 @@ def run(self):
352353
"_paths": {},
353354
"_restarting": False,
354355
"_internal_ip": "",
356+
"_display_name": "",
355357
"_cloud_compute": {
356358
"type": "__cloud_compute__",
357359
"name": "default",
@@ -391,6 +393,7 @@ def run(self):
391393
"_paths": {},
392394
"_restarting": False,
393395
"_internal_ip": "",
396+
"_display_name": "",
394397
"_cloud_compute": {
395398
"type": "__cloud_compute__",
396399
"name": "default",
@@ -414,6 +417,7 @@ def run(self):
414417
"_paths": {},
415418
"_restarting": False,
416419
"_internal_ip": "",
420+
"_display_name": "",
417421
"_cloud_compute": {
418422
"type": "__cloud_compute__",
419423
"name": "default",

tests/tests_app/core/test_lightning_work.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from lightning_app.storage import Path
1212
from lightning_app.testing.helpers import _MockQueue, EmptyFlow, EmptyWork
1313
from lightning_app.testing.testing import LightningTestApp
14-
from lightning_app.utilities.enum import WorkStageStatus
14+
from lightning_app.utilities.enum import make_status, WorkStageStatus
1515
from lightning_app.utilities.exceptions import LightningWorkException
1616
from lightning_app.utilities.packaging.build_config import BuildConfig
1717
from lightning_app.utilities.proxies import ProxyWorkRun, WorkRunner
@@ -384,3 +384,24 @@ def run(self):
384384
def test_lightning_app_work_start(cache_calls, parallel):
385385
app = LightningApp(FlowStart(cache_calls, parallel))
386386
MultiProcessRuntime(app, start_server=False).dispatch()
387+
388+
389+
class WorkDisplay(LightningWork):
390+
def __init__(self):
391+
super().__init__()
392+
393+
def run(self):
394+
pass
395+
396+
397+
def test_lightning_work_display_name():
398+
work = WorkDisplay()
399+
assert work.state_vars["vars"]["_display_name"] == ""
400+
work.display_name = "Hello"
401+
assert work.state_vars["vars"]["_display_name"] == "Hello"
402+
403+
work._calls["latest_call_hash"] = "test"
404+
work._calls["test"] = {"statuses": [make_status(WorkStageStatus.PENDING)]}
405+
with pytest.raises(RuntimeError, match="The display name can be set only before the work has started."):
406+
work.display_name = "HELLO"
407+
work.display_name = "Hello"

tests/tests_app/structures/test_structures.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def run(self):
4444
"_host": "127.0.0.1",
4545
"_paths": {},
4646
"_restarting": False,
47+
"_display_name": "",
4748
"_internal_ip": "",
4849
"_cloud_compute": {
4950
"type": "__cloud_compute__",
@@ -76,6 +77,7 @@ def run(self):
7677
"_host": "127.0.0.1",
7778
"_paths": {},
7879
"_restarting": False,
80+
"_display_name": "",
7981
"_internal_ip": "",
8082
"_cloud_compute": {
8183
"type": "__cloud_compute__",
@@ -108,6 +110,7 @@ def run(self):
108110
"_host": "127.0.0.1",
109111
"_paths": {},
110112
"_restarting": False,
113+
"_display_name": "",
111114
"_internal_ip": "",
112115
"_cloud_compute": {
113116
"type": "__cloud_compute__",
@@ -193,6 +196,7 @@ def run(self):
193196
"_paths": {},
194197
"_restarting": False,
195198
"_internal_ip": "",
199+
"_display_name": "",
196200
"_cloud_compute": {
197201
"type": "__cloud_compute__",
198202
"name": "default",
@@ -225,6 +229,7 @@ def run(self):
225229
"_paths": {},
226230
"_restarting": False,
227231
"_internal_ip": "",
232+
"_display_name": "",
228233
"_cloud_compute": {
229234
"type": "__cloud_compute__",
230235
"name": "default",
@@ -252,6 +257,7 @@ def run(self):
252257
"_paths": {},
253258
"_restarting": False,
254259
"_internal_ip": "",
260+
"_display_name": "",
255261
"_cloud_compute": {
256262
"type": "__cloud_compute__",
257263
"name": "default",

0 commit comments

Comments
 (0)