Skip to content

Commit 9d01397

Browse files
yurijmikhalevichBorda
authored andcommitted
fix(cloud): detect and ignore venv (#16056)
Co-authored-by: Ethan Harris <[email protected]> (cherry picked from commit 3b323c8)
1 parent ba0af63 commit 9d01397

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/lightning_app/runners/cloud.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,15 @@ def dispatch(
216216
root = Path(self.entrypoint_file).absolute().parent
217217
cleanup_handle = _prepare_lightning_wheels_and_requirements(root)
218218
self.app._update_index_file()
219+
220+
# Create a default dotignore if it doesn't exist
221+
if not (root / DOT_IGNORE_FILENAME).is_file():
222+
with open(root / DOT_IGNORE_FILENAME, "w") as f:
223+
f.write("venv/\n")
224+
if (root / "bin" / "activate").is_file() or (root / "pyvenv.cfg").is_file():
225+
# the user is developing inside venv
226+
f.write("bin/\ninclude/\nlib/\npyvenv.cfg\n")
227+
219228
repo = LocalSourceCodeDir(path=root)
220229
self._check_uploaded_folder(root, repo)
221230
requirements_file = root / "requirements.txt"

tests/tests_app/runners/test_cloud.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,56 @@ def run(self):
14881488
_validate_build_spec_and_compute(Work())
14891489

14901490

1491+
def test_default_lightningignore(monkeypatch, caplog, tmpdir):
1492+
mock_client = mock.MagicMock()
1493+
mock_client.projects_service_list_memberships.return_value = V1ListMembershipsResponse(
1494+
memberships=[V1Membership(name="test-project", project_id="test-project-id")]
1495+
)
1496+
mock_client.lightningapp_instance_service_list_lightningapp_instances.return_value = (
1497+
V1ListLightningappInstancesResponse(lightningapps=[])
1498+
)
1499+
mock_client.lightningapp_v2_service_create_lightningapp_release.return_value = V1LightningappRelease(
1500+
cluster_id="test"
1501+
)
1502+
cloud_backend = mock.MagicMock(client=mock_client)
1503+
monkeypatch.setattr(backends, "CloudBackend", mock.MagicMock(return_value=cloud_backend))
1504+
1505+
class MyWork(LightningWork):
1506+
def run(self):
1507+
pass
1508+
1509+
app = LightningApp(MyWork())
1510+
1511+
path = Path(tmpdir)
1512+
cloud_runtime = cloud.CloudRuntime(app=app, entrypoint_file=path / "entrypoint.py")
1513+
monkeypatch.setattr(LocalSourceCodeDir, "upload", mock.MagicMock())
1514+
1515+
# write some files
1516+
write_file_of_size(path / "a.txt", 5 * 1000 * 1000)
1517+
write_file_of_size(path / "venv" / "foo.txt", 4 * 1000 * 1000)
1518+
1519+
assert not (path / ".lightningignore").exists()
1520+
1521+
with mock.patch(
1522+
"lightning_app.runners.cloud._parse_lightningignore", wraps=_parse_lightningignore
1523+
) as parse_mock, mock.patch(
1524+
"lightning_app.source_code.local._copytree", wraps=_copytree
1525+
) as copy_mock, caplog.at_level(
1526+
logging.WARN
1527+
):
1528+
cloud_runtime.dispatch()
1529+
1530+
parse_mock.assert_called_once_with(())
1531+
assert copy_mock.mock_calls[0].kwargs["ignore_functions"][0].args[1] == set()
1532+
1533+
assert (path / ".lightningignore").exists()
1534+
1535+
assert f"Your application folder '{path.absolute()}' is more than 2 MB" in caplog.text
1536+
assert "The total size is 5.0 MB" in caplog.text
1537+
assert "2 files were uploaded" # a.txt and .lightningignore
1538+
assert "files:\n5.0 MB: a.txt\nPerhaps" in caplog.text # only this file appears
1539+
1540+
14911541
@pytest.mark.parametrize(
14921542
"lightning_app_instance, lightning_cloud_url, expected_url",
14931543
[

0 commit comments

Comments
 (0)