|
1 | 1 | from pathlib import Path |
2 | 2 |
|
3 | 3 | import pytest |
| 4 | +from PIL import Image as ImagePIL |
4 | 5 |
|
5 | 6 | from dvclive import Live |
6 | 7 | from dvclive.env import DVC_EXP_BASELINE_REV, DVC_EXP_NAME |
7 | | -from dvclive.plots import Metric |
| 8 | +from dvclive.plots import Image, Metric |
| 9 | +from dvclive.studio import _adapt_image |
8 | 10 |
|
9 | 11 |
|
10 | 12 | def test_post_to_studio(tmp_dir, mocked_dvc_repo, mocked_studio_post): |
@@ -378,3 +380,36 @@ def test_post_to_studio_inside_subdir_dvc_exp( |
378 | 380 | def test_post_to_studio_requires_exp(tmp_dir, mocked_dvc_repo, mocked_studio_post): |
379 | 381 | assert Live()._studio_events_to_skip == {"start", "data", "done"} |
380 | 382 | assert not Live(save_dvc_exp=True)._studio_events_to_skip |
| 383 | + |
| 384 | + |
| 385 | +def test_post_to_studio_images(tmp_dir, mocked_dvc_repo, mocked_studio_post): |
| 386 | + mocked_post, _ = mocked_studio_post |
| 387 | + |
| 388 | + live = Live(save_dvc_exp=True) |
| 389 | + live.log_image("foo.png", ImagePIL.new("RGB", (10, 10), (0, 0, 0))) |
| 390 | + live.next_step() |
| 391 | + |
| 392 | + dvc_path = Path(live.dvc_file).as_posix() |
| 393 | + metrics_path = Path(live.metrics_file).as_posix() |
| 394 | + foo_path = (Path(live.plots_dir) / Image.subfolder / "foo.png").as_posix() |
| 395 | + |
| 396 | + mocked_post.assert_called_with( |
| 397 | + "https://0.0.0.0/api/live", |
| 398 | + json={ |
| 399 | + "type": "data", |
| 400 | + "repo_url": "STUDIO_REPO_URL", |
| 401 | + "baseline_sha": live._baseline_rev, |
| 402 | + "name": live._exp_name, |
| 403 | + "step": 0, |
| 404 | + "metrics": {f"{metrics_path}": {"data": {"step": 0}}}, |
| 405 | + "plots": { |
| 406 | + f"{dvc_path}::{foo_path}": {"image": _adapt_image(foo_path)}, |
| 407 | + }, |
| 408 | + "client": "dvclive", |
| 409 | + }, |
| 410 | + headers={ |
| 411 | + "Authorization": "token STUDIO_TOKEN", |
| 412 | + "Content-type": "application/json", |
| 413 | + }, |
| 414 | + timeout=5, |
| 415 | + ) |
0 commit comments