mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
Add API to add artifacts (#9345)
* api call to add/write artifact * return dvcyaml path on add * create dir for dvc.yaml if needed * create dir for dvc.yaml if needed - fix * allow nested artifact names * make dvc get download artifacts * Apply suggestions from code review Co-authored-by: Oded Messer <[email protected]> * use feedback * remove 'dvc get' from this PR, keep only adding artifacts * allow first char of artifact name to be a number * add note about constants * fix parsing artifact name * remove 'parse_name' and write tests for 'add' * Apply suggestions from code review Co-authored-by: Oded Messer <[email protected]> * updates from comments * fix for studio * fix again * making check_name_format to raise an exception * Update dvc/repo/artifacts.py --------- Co-authored-by: Oded Messer <[email protected]>
This commit is contained in:
co-authored by
Oded Messer
parent
915dd5062e
commit
45181504ea
@@ -3,6 +3,7 @@ import os
|
||||
import pytest
|
||||
|
||||
from dvc.annotations import Artifact
|
||||
from dvc.exceptions import InvalidArgumentError
|
||||
from dvc.repo.artifacts import name_is_compatible
|
||||
from dvc.utils.strictyaml import YAMLSyntaxError, YAMLValidationError
|
||||
|
||||
@@ -21,7 +22,7 @@ dvcyaml = {
|
||||
}
|
||||
|
||||
|
||||
def test_reading_artifacts_subdir(tmp_dir, dvc):
|
||||
def test_artifacts_read_subdir(tmp_dir, dvc):
|
||||
(tmp_dir / "dvc.yaml").dump(dvcyaml)
|
||||
|
||||
subdir = tmp_dir / "subdir"
|
||||
@@ -38,6 +39,55 @@ def test_reading_artifacts_subdir(tmp_dir, dvc):
|
||||
}
|
||||
|
||||
|
||||
def test_artifacts_add_subdir(tmp_dir, dvc):
|
||||
subdir = tmp_dir / "subdir"
|
||||
subdir.mkdir()
|
||||
|
||||
(subdir / "dvc.yaml").dump(dvcyaml)
|
||||
|
||||
new_art = Artifact(path="path")
|
||||
tmp_dir.dvc.artifacts.add("new", new_art, dvcfile="subdir/dvc.yaml")
|
||||
|
||||
artifacts = {
|
||||
name: Artifact(**values) for name, values in dvcyaml["artifacts"].items()
|
||||
}
|
||||
artifacts["new"] = new_art
|
||||
assert tmp_dir.dvc.artifacts.read() == {
|
||||
f"subdir{os.path.sep}dvc.yaml": artifacts,
|
||||
}
|
||||
|
||||
|
||||
def test_artifacts_add_abspath(tmp_dir, dvc):
|
||||
subdir = tmp_dir / "subdir"
|
||||
subdir.mkdir()
|
||||
|
||||
new_art = Artifact(path="path")
|
||||
tmp_dir.dvc.artifacts.add(
|
||||
"new", new_art, dvcfile=os.path.abspath("subdir/dvc.yaml")
|
||||
)
|
||||
|
||||
assert tmp_dir.dvc.artifacts.read() == {
|
||||
f"subdir{os.path.sep}dvc.yaml": {"new": new_art},
|
||||
}
|
||||
|
||||
|
||||
def test_artifacts_add_fails_on_dvc_subrepo(tmp_dir, dvc):
|
||||
# adding artifact to the DVC subrepo from the parent DVC repo
|
||||
# shouldn't work
|
||||
subdir = tmp_dir / "subdir"
|
||||
(subdir / ".dvc").mkdir(parents=True)
|
||||
|
||||
with pytest.raises(InvalidArgumentError):
|
||||
tmp_dir.dvc.artifacts.add(
|
||||
"failing", Artifact(path="path"), dvcfile="subdir/dvc.yaml"
|
||||
)
|
||||
|
||||
with pytest.raises(InvalidArgumentError):
|
||||
tmp_dir.dvc.artifacts.add(
|
||||
"failing", Artifact(path="path"), dvcfile="subdir/dvclive/dvc.yaml"
|
||||
)
|
||||
|
||||
|
||||
bad_dvcyaml_extra_field = {
|
||||
"artifacts": {
|
||||
"lol": {"kek": "cheburek", "path": "lol"},
|
||||
@@ -71,7 +121,7 @@ artifacts:
|
||||
"""
|
||||
|
||||
|
||||
def test_broken_dvcyaml_id_duplication(tmp_dir, dvc):
|
||||
def test_artifacts_read_fails_on_id_duplication(tmp_dir, dvc):
|
||||
with open(tmp_dir / "dvc.yaml", "w") as f:
|
||||
f.write(bad_dvcyaml_id_duplication)
|
||||
|
||||
@@ -79,32 +129,19 @@ def test_broken_dvcyaml_id_duplication(tmp_dir, dvc):
|
||||
tmp_dir.dvc.artifacts.read()
|
||||
|
||||
|
||||
dvcyaml_redirecting = {"artifacts": "artifacts.yaml"}
|
||||
|
||||
|
||||
def test_read_artifacts_yaml(tmp_dir, dvc):
|
||||
(tmp_dir / "dvc.yaml").dump(dvcyaml_redirecting)
|
||||
(tmp_dir / "artifacts.yaml").dump(dvcyaml["artifacts"])
|
||||
|
||||
artifacts = {
|
||||
name: Artifact(**values) for name, values in dvcyaml["artifacts"].items()
|
||||
}
|
||||
assert tmp_dir.dvc.artifacts.read() == {
|
||||
"dvc.yaml": artifacts,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"name",
|
||||
[
|
||||
"1",
|
||||
"m",
|
||||
"nn",
|
||||
"m1",
|
||||
"1nn",
|
||||
"model-prod",
|
||||
"model-prod-v1",
|
||||
],
|
||||
)
|
||||
def test_check_name_is_valid(name):
|
||||
def test_name_is_compatible(name):
|
||||
assert name_is_compatible(name)
|
||||
|
||||
|
||||
@@ -112,10 +149,8 @@ def test_check_name_is_valid(name):
|
||||
"name",
|
||||
[
|
||||
"",
|
||||
"1",
|
||||
"m/",
|
||||
"/m",
|
||||
"1nn",
|
||||
"###",
|
||||
"@@@",
|
||||
"a model",
|
||||
@@ -125,8 +160,7 @@ def test_check_name_is_valid(name):
|
||||
"model@1",
|
||||
"model#1",
|
||||
"@namespace/model",
|
||||
"namespace/model",
|
||||
],
|
||||
)
|
||||
def test_check_name_is_invalid(name):
|
||||
def test_name_is_compatible_fails(name):
|
||||
assert not name_is_compatible(name)
|
||||
|
||||
Reference in New Issue
Block a user