From 273fd76fe353efcbc1286d0a4cd8d5e4500ee0fd Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Mon, 5 Aug 2024 14:57:54 +0100 Subject: [PATCH 01/10] Add endpoint to hide or unhide an environment in the frontend. --- softpack_core/artifacts.py | 11 +++++- softpack_core/schemas/environment.py | 57 +++++++++++++++++++++++++-- tests/integration/test_environment.py | 36 +++++++++++++++++ 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/softpack_core/artifacts.py b/softpack_core/artifacts.py index ab2558c..cc7932d 100644 --- a/softpack_core/artifacts.py +++ b/softpack_core/artifacts.py @@ -156,12 +156,19 @@ def spec(self) -> Box: map(lambda p: Package.from_name(p), info.packages) ) + metadata = self.metadata() + + info["tags"] = getattr(metadata, "tags", []) + info["hidden"] = getattr(metadata, "hidden", False) + + return info + + def metadata(self) -> Box: meta = Box() if Artifacts.meta_file in self.obj: meta = Box.from_yaml(self.obj[Artifacts.meta_file].data) - info["tags"] = getattr(meta, "tags", []) - return info + return meta def __iter__(self) -> Iterator["Artifacts.Object"]: """A generator for returning items under an artifacts. diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 4421083..125a78e 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -13,6 +13,7 @@ from traceback import format_exception_only from typing import List, Optional, Tuple, Union, cast +from box import Box import httpx import starlette.datastructures import strawberry @@ -56,6 +57,9 @@ class UpdateEnvironmentSuccess(Success): class AddTagSuccess(Success): """Successfully added tag to environment.""" +@strawberry.type +class HiddenSuccess(Success): + """Successfully set hidden status on environment.""" @strawberry.type class DeleteEnvironmentSuccess(Success): @@ -124,6 +128,15 @@ class BuilderError(Error): ], ) +HiddenResponse = strawberry.union( + "AddTagResponse", + [ + HiddenSuccess, + InvalidInputError, + EnvironmentNotFoundError, + ], +) + DeleteResponse = strawberry.union( "DeleteResponse", [ @@ -306,6 +319,7 @@ class Environment: packages: list[Package] state: Optional[State] tags: list[str] + hidden: bool requested: Optional[datetime.datetime] = None build_start: Optional[datetime.datetime] = None @@ -374,6 +388,7 @@ def from_artifact(cls, obj: Artifacts.Object) -> Optional["Environment"]: readme=spec.get("readme", ""), type=spec.get("type", ""), tags=spec.tags, + hidden=spec.hidden, ) except KeyError: return None @@ -586,12 +601,46 @@ def add_tag( return AddTagSuccess(message="Tag already present") tags.add(tag) - metadata = yaml.dump({"tags": sorted(tags)}) + metadata = cls.read_metadata(path, name) + metadata.tags = sorted(tags) + + cls.store_metadata(environment_path, metadata) + + return AddTagSuccess(message="Tag successfully added") + + @classmethod + def read_metadata(cls, path: str, name: str) -> Box: + return artifacts.get(path, name).metadata() + + @classmethod + def store_metadata(cls, environment_path: str, metadata: Box): tree_oid = artifacts.create_file( - environment_path, artifacts.meta_file, metadata, overwrite=True + environment_path, + artifacts.meta_file, + metadata.to_yaml(), + overwrite=True ) - artifacts.commit_and_push(tree_oid, "create environment folder") - return AddTagSuccess(message="Tag successfully added") + + artifacts.commit_and_push(tree_oid, "update metadata") + + @classmethod + def set_hidden(cls, name: str, path: str, hidden: bool) -> HiddenResponse: # type: ignore + environment_path = Path(path, name) + response: Optional[Error] = cls.check_env_exists(environment_path) + if response is not None: + return response + + metadata = cls.read_metadata(path, name) + + if metadata.get("hidden") == hidden: + return HiddenSuccess(message="Hidden metadata already set") + + metadata.hidden = hidden + + cls.store_metadata(environment_path, metadata) + + return HiddenSuccess(message="Hidden metadata set") + @classmethod def delete(cls, name: str, path: str) -> DeleteResponse: # type: ignore diff --git a/tests/integration/test_environment.py b/tests/integration/test_environment.py index ca00fc3..71d2328 100644 --- a/tests/integration/test_environment.py +++ b/tests/integration/test_environment.py @@ -24,6 +24,7 @@ EnvironmentAlreadyExistsError, EnvironmentInput, EnvironmentNotFoundError, + HiddenSuccess, InvalidInputError, Package, State, @@ -553,3 +554,38 @@ def test_tagging(httpx_post, testable_env_input: EnvironmentInput) -> None: example_env = Environment.iter()[0] assert example_env.tags == ["second test", "test"] + +def test_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: + example_env = Environment.iter()[0] + assert example_env.hidden == False + name, path = example_env.name, example_env.path + + result = Environment.set_hidden(name, path, True) + assert isinstance(result, HiddenSuccess) + assert result.message == "Hidden metadata set" + example_env = Environment.iter()[0] + assert example_env.hidden == True + + result = Environment.set_hidden(name, path, True) + assert isinstance(result, HiddenSuccess) + assert result.message == "Hidden metadata already set" + example_env = Environment.iter()[0] + assert example_env.hidden == True + + result = Environment.set_hidden(name, path, False) + assert isinstance(result, HiddenSuccess) + assert result.message == "Hidden metadata set" + example_env = Environment.iter()[0] + assert example_env.hidden == False + + result = Environment.set_hidden(name, path, False) + assert isinstance(result, HiddenSuccess) + assert result.message == "Hidden metadata already set" + example_env = Environment.iter()[0] + assert example_env.hidden == False + + result = Environment.set_hidden(name, path, True) + assert isinstance(result, HiddenSuccess) + assert result.message == "Hidden metadata set" + example_env = Environment.iter()[0] + assert example_env.hidden == True From be097b3a1d387e3b54fd4de9e37da843fbe22ceb Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Mon, 5 Aug 2024 15:18:50 +0100 Subject: [PATCH 02/10] Add admin only option to force hide an environment. --- softpack_core/artifacts.py | 1 + softpack_core/schemas/environment.py | 4 +++- tests/integration/test_environment.py | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/softpack_core/artifacts.py b/softpack_core/artifacts.py index cc7932d..2e7abae 100644 --- a/softpack_core/artifacts.py +++ b/softpack_core/artifacts.py @@ -160,6 +160,7 @@ def spec(self) -> Box: info["tags"] = getattr(metadata, "tags", []) info["hidden"] = getattr(metadata, "hidden", False) + info["force_hidden"] = getattr(metadata, "force_hidden", False) return info diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 125a78e..6bab9fc 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -320,6 +320,7 @@ class Environment: state: Optional[State] tags: list[str] hidden: bool + force_hidden: bool requested: Optional[datetime.datetime] = None build_start: Optional[datetime.datetime] = None @@ -352,7 +353,7 @@ def iter(cls) -> list["Environment"]: environment_folders = artifacts.iter() environment_objects = list( - filter(None, map(cls.from_artifact, environment_folders)) + filter(lambda e : not e.force_hidden, map(cls.from_artifact, environment_folders)) ) for env in environment_objects: @@ -389,6 +390,7 @@ def from_artifact(cls, obj: Artifacts.Object) -> Optional["Environment"]: type=spec.get("type", ""), tags=spec.tags, hidden=spec.hidden, + force_hidden=spec.force_hidden, ) except KeyError: return None diff --git a/tests/integration/test_environment.py b/tests/integration/test_environment.py index 71d2328..23b8ca1 100644 --- a/tests/integration/test_environment.py +++ b/tests/integration/test_environment.py @@ -589,3 +589,13 @@ def test_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: assert result.message == "Hidden metadata set" example_env = Environment.iter()[0] assert example_env.hidden == True + +def test_force_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: + first_env = Environment.iter()[0] + metadata = Environment.read_metadata(first_env.path, first_env.name) + metadata.force_hidden = True + Environment.store_metadata(Path(first_env.path, first_env.name), metadata) + + new_first = Environment.iter()[0] + + assert first_env.path != new_first.path or first_env.name != new_first.name From 2b7edf5934e8e73986643373e95d1e29a9e0cef8 Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Mon, 5 Aug 2024 16:43:15 +0100 Subject: [PATCH 03/10] Remove force_hide from the Environment type. --- schema.graphql | 8 ++++++++ softpack_core/schemas/environment.py | 10 ++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/schema.graphql b/schema.graphql index 443d4ed..5184ce9 100644 --- a/schema.graphql +++ b/schema.graphql @@ -38,6 +38,7 @@ type Environment { packages: [Package!]! state: State tags: [String!]! + hidden: Boolean! requested: DateTime buildStart: DateTime buildDone: DateTime @@ -72,6 +73,12 @@ type Group { name: String! } +union HiddenResponse = HiddenSuccess | InvalidInputError | EnvironmentNotFoundError + +type HiddenSuccess implements Success { + message: String! +} + type InvalidInputError implements Error { message: String! } @@ -95,6 +102,7 @@ type SchemaMutation { createEnvironment(env: EnvironmentInput!): CreateResponse! deleteEnvironment(name: String!, path: String!): DeleteResponse! addTag(name: String!, path: String!, tag: String!): AddTagResponse! + setHidden(name: String!, path: String!, hidden: Boolean!): HiddenResponse! createFromModule(file: Upload!, modulePath: String!, environmentPath: String!): CreateResponse! updateFromModule(file: Upload!, modulePath: String!, environmentPath: String!): UpdateResponse! } diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 6bab9fc..9f98ea2 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -129,7 +129,7 @@ class BuilderError(Error): ) HiddenResponse = strawberry.union( - "AddTagResponse", + "HiddenResponse", [ HiddenSuccess, InvalidInputError, @@ -320,7 +320,6 @@ class Environment: state: Optional[State] tags: list[str] hidden: bool - force_hidden: bool requested: Optional[datetime.datetime] = None build_start: Optional[datetime.datetime] = None @@ -353,7 +352,7 @@ def iter(cls) -> list["Environment"]: environment_folders = artifacts.iter() environment_objects = list( - filter(lambda e : not e.force_hidden, map(cls.from_artifact, environment_folders)) + filter(None, map(cls.from_artifact, environment_folders)) ) for env in environment_objects: @@ -379,6 +378,9 @@ def from_artifact(cls, obj: Artifacts.Object) -> Optional["Environment"]: """ try: spec = obj.spec() + if spec.force_hidden: + return None + return Environment( id=obj.oid, name=obj.name, @@ -390,7 +392,6 @@ def from_artifact(cls, obj: Artifacts.Object) -> Optional["Environment"]: type=spec.get("type", ""), tags=spec.tags, hidden=spec.hidden, - force_hidden=spec.force_hidden, ) except KeyError: return None @@ -898,6 +899,7 @@ class Mutation: createEnvironment: CreateResponse = Environment.create # type: ignore deleteEnvironment: DeleteResponse = Environment.delete # type: ignore addTag: AddTagResponse = Environment.add_tag # type: ignore + setHidden: HiddenResponse = Environment.set_hidden # type: ignore # writeArtifact: WriteArtifactResponse = ( # type: ignore # Environment.write_artifact # ) From 1f3e0fde663a3911a54119a22f3a23d63fa537ad Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:08:28 +0100 Subject: [PATCH 04/10] Delint. --- softpack_core/artifacts.py | 7 +++++++ softpack_core/schemas/environment.py | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/softpack_core/artifacts.py b/softpack_core/artifacts.py index 2e7abae..96fae0d 100644 --- a/softpack_core/artifacts.py +++ b/softpack_core/artifacts.py @@ -165,6 +165,13 @@ def spec(self) -> Box: return info def metadata(self) -> Box: + """Returns the metadata for an Environment. + + Should contain keys: + - tags: list[string] + - hidden: boolean + - force_hidden: boolean + """ meta = Box() if Artifacts.meta_file in self.obj: meta = Box.from_yaml(self.obj[Artifacts.meta_file].data) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 9f98ea2..0e3b24a 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -613,10 +613,16 @@ def add_tag( @classmethod def read_metadata(cls, path: str, name: str) -> Box: + """This method returns the metadata for an environment with the given + path and name. + """ return artifacts.get(path, name).metadata() @classmethod def store_metadata(cls, environment_path: str, metadata: Box): + """This method writes the given metadata to the repo for the environment + path given. + """ tree_oid = artifacts.create_file( environment_path, artifacts.meta_file, @@ -627,7 +633,10 @@ def store_metadata(cls, environment_path: str, metadata: Box): artifacts.commit_and_push(tree_oid, "update metadata") @classmethod - def set_hidden(cls, name: str, path: str, hidden: bool) -> HiddenResponse: # type: ignore + def set_hidden( + cls, name: str, path: str, hidden: bool + ) -> HiddenResponse: # type: ignore + """This method sets the hidden status for the given environment.""" environment_path = Path(path, name) response: Optional[Error] = cls.check_env_exists(environment_path) if response is not None: From 44277b707de5450c68d06bdd49d1ede2a9effe3f Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:25:29 +0100 Subject: [PATCH 05/10] Delint. --- softpack_core/schemas/environment.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 0e3b24a..15900d3 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -616,13 +616,15 @@ def read_metadata(cls, path: str, name: str) -> Box: """This method returns the metadata for an environment with the given path and name. """ + return artifacts.get(path, name).metadata() @classmethod def store_metadata(cls, environment_path: str, metadata: Box): - """This method writes the given metadata to the repo for the environment - path given. + """This method writes the given metadata to the repo for the + environment path given. """ + tree_oid = artifacts.create_file( environment_path, artifacts.meta_file, @@ -637,6 +639,7 @@ def set_hidden( cls, name: str, path: str, hidden: bool ) -> HiddenResponse: # type: ignore """This method sets the hidden status for the given environment.""" + environment_path = Path(path, name) response: Optional[Error] = cls.check_env_exists(environment_path) if response is not None: From ef8c4ca80deb3fae8c403fbad570acc8bc62b4b0 Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:32:53 +0100 Subject: [PATCH 06/10] Delint. --- softpack_core/schemas/environment.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 15900d3..e4fdb35 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -616,15 +616,13 @@ def read_metadata(cls, path: str, name: str) -> Box: """This method returns the metadata for an environment with the given path and name. """ - return artifacts.get(path, name).metadata() @classmethod def store_metadata(cls, environment_path: str, metadata: Box): - """This method writes the given metadata to the repo for the - environment path given. + """This method writes the given metadata to the repo for the environment + path given. """ - tree_oid = artifacts.create_file( environment_path, artifacts.meta_file, @@ -638,8 +636,8 @@ def store_metadata(cls, environment_path: str, metadata: Box): def set_hidden( cls, name: str, path: str, hidden: bool ) -> HiddenResponse: # type: ignore - """This method sets the hidden status for the given environment.""" - + """This method sets the hidden status for the given environment. + """ environment_path = Path(path, name) response: Optional[Error] = cls.check_env_exists(environment_path) if response is not None: From f96a37ef1de89a02c6dddd88eafff5a45454fa0a Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:35:58 +0100 Subject: [PATCH 07/10] Delint. --- softpack_core/schemas/environment.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index e4fdb35..758e127 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -613,15 +613,19 @@ def add_tag( @classmethod def read_metadata(cls, path: str, name: str) -> Box: - """This method returns the metadata for an environment with the given + """Read an environments metadata. + + This method returns the metadata for an environment with the given path and name. """ return artifacts.get(path, name).metadata() @classmethod def store_metadata(cls, environment_path: str, metadata: Box): - """This method writes the given metadata to the repo for the environment - path given. + """Store an environments metadata. + + This method writes the given metadata to the repo for the + environment path given. """ tree_oid = artifacts.create_file( environment_path, From 58fa29460bfe2f5e60f18ccd7bde19958a85d3d9 Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:39:40 +0100 Subject: [PATCH 08/10] Delint. --- tests/integration/test_environment.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/integration/test_environment.py b/tests/integration/test_environment.py index 23b8ca1..a1f692c 100644 --- a/tests/integration/test_environment.py +++ b/tests/integration/test_environment.py @@ -557,39 +557,38 @@ def test_tagging(httpx_post, testable_env_input: EnvironmentInput) -> None: def test_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: example_env = Environment.iter()[0] - assert example_env.hidden == False + assert not example_env.hidden name, path = example_env.name, example_env.path result = Environment.set_hidden(name, path, True) assert isinstance(result, HiddenSuccess) assert result.message == "Hidden metadata set" example_env = Environment.iter()[0] - assert example_env.hidden == True + assert example_env.hidden result = Environment.set_hidden(name, path, True) assert isinstance(result, HiddenSuccess) assert result.message == "Hidden metadata already set" example_env = Environment.iter()[0] - assert example_env.hidden == True + assert example_env.hidden result = Environment.set_hidden(name, path, False) assert isinstance(result, HiddenSuccess) assert result.message == "Hidden metadata set" example_env = Environment.iter()[0] - assert example_env.hidden == False + assert not example_env.hidden result = Environment.set_hidden(name, path, False) assert isinstance(result, HiddenSuccess) assert result.message == "Hidden metadata already set" example_env = Environment.iter()[0] - assert example_env.hidden == False + assert not example_env.hidden result = Environment.set_hidden(name, path, True) assert isinstance(result, HiddenSuccess) assert result.message == "Hidden metadata set" example_env = Environment.iter()[0] - assert example_env.hidden == True - + assert example_env.hidden def test_force_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: first_env = Environment.iter()[0] metadata = Environment.read_metadata(first_env.path, first_env.name) From a60f1117a49a3ab9a8ed0b2a39b6ba2f9c5ed78c Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:51:36 +0100 Subject: [PATCH 09/10] Delint. --- softpack_core/schemas/environment.py | 23 ++++++++++++++--------- tests/integration/test_environment.py | 7 ++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 758e127..834e255 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -13,11 +13,11 @@ from traceback import format_exception_only from typing import List, Optional, Tuple, Union, cast -from box import Box import httpx import starlette.datastructures import strawberry import yaml +from box import Box from fastapi import UploadFile from strawberry.file_uploads import Upload @@ -57,10 +57,12 @@ class UpdateEnvironmentSuccess(Success): class AddTagSuccess(Success): """Successfully added tag to environment.""" + @strawberry.type class HiddenSuccess(Success): """Successfully set hidden status on environment.""" + @strawberry.type class DeleteEnvironmentSuccess(Success): """Environment successfully deleted.""" @@ -618,10 +620,15 @@ def read_metadata(cls, path: str, name: str) -> Box: This method returns the metadata for an environment with the given path and name. """ - return artifacts.get(path, name).metadata() + arts = artifacts.get(path, name) + + if arts is not None: + return arts.metadata() + + return Box() @classmethod - def store_metadata(cls, environment_path: str, metadata: Box): + def store_metadata(cls, environment_path: Path, metadata: Box) -> None: """Store an environments metadata. This method writes the given metadata to the repo for the @@ -631,17 +638,16 @@ def store_metadata(cls, environment_path: str, metadata: Box): environment_path, artifacts.meta_file, metadata.to_yaml(), - overwrite=True + overwrite=True, ) artifacts.commit_and_push(tree_oid, "update metadata") @classmethod def set_hidden( - cls, name: str, path: str, hidden: bool - ) -> HiddenResponse: # type: ignore - """This method sets the hidden status for the given environment. - """ + cls, name: str, path: str, hidden: bool + ) -> HiddenResponse: # type: ignore + """This method sets the hidden status for the given environment.""" environment_path = Path(path, name) response: Optional[Error] = cls.check_env_exists(environment_path) if response is not None: @@ -658,7 +664,6 @@ def set_hidden( return HiddenSuccess(message="Hidden metadata set") - @classmethod def delete(cls, name: str, path: str) -> DeleteResponse: # type: ignore """Delete an Environment. diff --git a/tests/integration/test_environment.py b/tests/integration/test_environment.py index a1f692c..949ff4f 100644 --- a/tests/integration/test_environment.py +++ b/tests/integration/test_environment.py @@ -555,6 +555,7 @@ def test_tagging(httpx_post, testable_env_input: EnvironmentInput) -> None: example_env = Environment.iter()[0] assert example_env.tags == ["second test", "test"] + def test_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: example_env = Environment.iter()[0] assert not example_env.hidden @@ -589,7 +590,11 @@ def test_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: assert result.message == "Hidden metadata set" example_env = Environment.iter()[0] assert example_env.hidden -def test_force_hidden(httpx_post, testable_env_input: EnvironmentInput) -> None: + + +def test_force_hidden( + httpx_post, testable_env_input: EnvironmentInput +) -> None: first_env = Environment.iter()[0] metadata = Environment.read_metadata(first_env.path, first_env.name) metadata.force_hidden = True From 455d27bb538cc5950ae7c86973577ceeca734444 Mon Sep 17 00:00:00 2001 From: Michael Woolnough Date: Tue, 6 Aug 2024 14:55:12 +0100 Subject: [PATCH 10/10] Delint. --- softpack_core/schemas/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 834e255..c25697e 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -620,7 +620,7 @@ def read_metadata(cls, path: str, name: str) -> Box: This method returns the metadata for an environment with the given path and name. """ - arts = artifacts.get(path, name) + arts = artifacts.get(Path(path), name) if arts is not None: return arts.metadata()