We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Files are read as Models
**Describe the bug**

<!--- A clear and concise description of what the bug is. -->
When a .DS_Store file is created in the `bentoml/models` folder, I think `store.py`'s `list` method tries loading it. I think the check for directories isn't working as intended (https://github.com/bentoml/BentoML/blob/4308c67f327d9524025e5c348ded22553824c1d4/bentoml/_internal/store.py#L69), but I'm not sure. Additionally, this happens when any file is created in the models folder, but not when folders are created.


**To Reproduce**

Steps to reproduce the issue:
1. Go to `~/bentoml/models/`
2. Create a `.DS_Store` file
3. Run `bentoml models list`
4. See error


**Expected behavior**

<!--- A clear and concise description of what you expected to happen. -->
All files should be skipped when scanning for models.


**Screenshots/Logs**

```shell
[19:12:41] WARNING  [boot] converting .DS_Store to lowercase: .ds_store         
Traceback (most recent call last):
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/__main__.py", line 4, in <module>
    create_bentoml_cli()()
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/cli/model_management.py", line 90, in list_models
    models = model_store.list(model_name)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py", line 63, in list
    return [
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py", line 64, in <listcomp>
    ver for _d in sorted(self._fs.listdir("/")) for ver in self.list(_d)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py", line 67, in list
    _tag = Tag.from_taglike(tag)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py", line 221, in from_taglike
    return cls.from_str(taglike)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py", line 226, in from_str
    return cls(tag_str, None)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py", line 180, in __init__
    validate_tag_str(lname)
  File "/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/utils/validation.py", line 29, in validate_tag_str
    raise InvalidArgument(f"{value} is not a valid tag: " + ", and ".join(errors))
bentoml.exceptions.InvalidArgument: .ds_store is not a valid tag: a tag's name or version must consist of alphanumeric characters, '_', '-', or '.', and must start and end with an alphanumeric character
```


**Environment:**
 - OS: MacOS 12.2.1
 - Python 3.8.9
 - BentoML 1.0.0a4


**Additional context**

MacOS creates .DS_Store files automatically, so I ran into this bug after opening the folder and sorting the files 😅


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bentoml/_internal/store.py`
Content:
```
1 import os
2 import typing as t
3 import datetime
4 from abc import ABC
5 from abc import abstractmethod
6 from contextlib import contextmanager
7 
8 import fs
9 import fs.errors
10 from fs.base import FS
11 
12 from .types import Tag
13 from .types import PathType
14 from ..exceptions import NotFound
15 from ..exceptions import BentoMLException
16 
17 T = t.TypeVar("T")
18 
19 
20 class StoreItem(ABC):
21     @property
22     @abstractmethod
23     def tag(self) -> Tag:
24         raise NotImplementedError
25 
26     @classmethod
27     @abstractmethod
28     def from_fs(cls: t.Type[T], item_fs: FS) -> T:
29         raise NotImplementedError
30 
31     @property
32     @abstractmethod
33     def creation_time(self) -> datetime.datetime:
34         raise NotImplementedError
35 
36     def __repr__(self):
37         return f'{self.__class__.__name__}(tag="{self.tag}")'
38 
39 
40 Item = t.TypeVar("Item", bound=StoreItem)
41 
42 
43 class Store(ABC, t.Generic[Item]):
44     """An FsStore manages items under the given base filesystem.
45 
46     Note that FsStore has no consistency checks; it assumes that no direct modification
47     of the files in its directory has occurred.
48 
49     """
50 
51     _fs: FS
52     _item_type: t.Type[Item]
53 
54     @abstractmethod
55     def __init__(self, base_path: t.Union[PathType, FS], item_type: t.Type[Item]):
56         self._item_type = item_type
57         if isinstance(base_path, os.PathLike):
58             base_path = base_path.__fspath__()
59         self._fs = fs.open_fs(base_path)
60 
61     def list(self, tag: t.Optional[t.Union[Tag, str]] = None) -> t.List[Item]:
62         if not tag:
63             return [
64                 ver for _d in sorted(self._fs.listdir("/")) for ver in self.list(_d)
65             ]
66 
67         _tag = Tag.from_taglike(tag)
68         if _tag.version is None:
69             if not self._fs.isdir(_tag.name):
70                 raise NotFound(
71                     f"no {self._item_type.__name__}s with name '{_tag.name}' found"
72                 )
73 
74             tags = sorted(
75                 [
76                     Tag(_tag.name, f.name)
77                     for f in self._fs.scandir(_tag.name)
78                     if f.is_dir
79                 ]
80             )
81             return [self._get_item(t) for t in tags]
82         else:
83             return [self._get_item(_tag)] if self._fs.isdir(_tag.path()) else []
84 
85     def _get_item(self, tag: Tag) -> Item:
86         """
87         Creates a new instance of Item that represents the item with tag `tag`.
88         """
89         return self._item_type.from_fs(self._fs.opendir(tag.path()))
90 
91     def get(self, tag: t.Union[Tag, str]) -> Item:
92         """
93         store.get("my_bento")
94         store.get("my_bento:v1.0.0")
95         store.get(Tag("my_bento", "latest"))
96         """
97         _tag = Tag.from_taglike(tag)
98         if _tag.version is None or _tag.version == "latest":
99             try:
100                 _tag.version = self._fs.readtext(_tag.latest_path())
101             except fs.errors.ResourceNotFound:
102                 raise NotFound(
103                     f"no {self._item_type.__name__}s with name '{_tag.name}' exist in BentoML store {self._fs}"
104                 )
105 
106         path = _tag.path()
107         if self._fs.exists(path):
108             return self._get_item(_tag)
109 
110         matches = self._fs.glob(f"{path}*/")
111         counts = matches.count().directories
112         if counts == 0:
113             raise NotFound(
114                 f"{self._item_type.__name__} '{tag}' is not found in BentoML store {self._fs}"
115             )
116         elif counts == 1:
117             match = next(iter(matches))
118             return self._get_item(Tag(_tag.name, match.info.name))
119         else:
120             vers: t.List[str] = []
121             for match in matches:
122                 vers += match.info.name
123             raise BentoMLException(
124                 f"multiple versions matched by {_tag.version}: {vers}"
125             )
126 
127     @contextmanager
128     def register(self, tag: t.Union[str, Tag]):
129         _tag = Tag.from_taglike(tag)
130 
131         item_path = _tag.path()
132         if self._fs.exists(item_path):
133             raise BentoMLException(
134                 f"Item '{_tag}' already exists in the store {self._fs}"
135             )
136         self._fs.makedirs(item_path)
137         try:
138             yield self._fs.getsyspath(item_path)
139         finally:
140             # item generation is most likely successful, link latest path
141             if (
142                 not self._fs.exists(_tag.latest_path())
143                 or self.get(_tag).creation_time > self.get(_tag.name).creation_time
144             ):
145                 with self._fs.open(_tag.latest_path(), "w") as latest_file:
146                     latest_file.write(_tag.version)
147 
148     def delete(self, tag: t.Union[str, Tag]) -> None:
149         _tag = Tag.from_taglike(tag)
150 
151         if not self._fs.exists(_tag.path()):
152             raise NotFound(f"{self._item_type.__name__} '{tag}' not found")
153 
154         self._fs.removetree(_tag.path())
155         if self._fs.isdir(_tag.name):
156             versions = self.list(_tag.name)
157             if len(versions) == 0:
158                 # if we've removed all versions, remove the directory
159                 self._fs.removetree(_tag.name)
160             else:
161                 new_latest = sorted(versions, key=lambda x: x.creation_time)[-1]
162                 # otherwise, update the latest version
163                 assert new_latest.tag.version is not None
164                 self._fs.writetext(_tag.latest_path(), new_latest.tag.version)
165
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bentoml/_internal/store.py b/bentoml/_internal/store.py
--- a/bentoml/_internal/store.py
+++ b/bentoml/_internal/store.py
@@ -61,7 +61,10 @@
     def list(self, tag: t.Optional[t.Union[Tag, str]] = None) -> t.List[Item]:
         if not tag:
             return [
-                ver for _d in sorted(self._fs.listdir("/")) for ver in self.list(_d)
+                ver
+                for _d in sorted(self._fs.listdir("/"))
+                if self._fs.isdir(_d)
+                for ver in self.list(_d)
             ]
 
         _tag = Tag.from_taglike(tag)

{"golden_diff": "diff --git a/bentoml/_internal/store.py b/bentoml/_internal/store.py\n--- a/bentoml/_internal/store.py\n+++ b/bentoml/_internal/store.py\n@@ -61,7 +61,10 @@\n     def list(self, tag: t.Optional[t.Union[Tag, str]] = None) -> t.List[Item]:\n         if not tag:\n             return [\n-                ver for _d in sorted(self._fs.listdir(\"/\")) for ver in self.list(_d)\n+                ver\n+                for _d in sorted(self._fs.listdir(\"/\"))\n+                if self._fs.isdir(_d)\n+                for ver in self.list(_d)\n             ]\n \n         _tag = Tag.from_taglike(tag)\n", "issue": "Files are read as Models\n**Describe the bug**\r\n\r\n<!--- A clear and concise description of what the bug is. -->\r\nWhen a .DS_Store file is created in the `bentoml/models` folder, I think `store.py`'s `list` method tries loading it. I think the check for directories isn't working as intended (https://github.com/bentoml/BentoML/blob/4308c67f327d9524025e5c348ded22553824c1d4/bentoml/_internal/store.py#L69), but I'm not sure. Additionally, this happens when any file is created in the models folder, but not when folders are created.\r\n\r\n\r\n**To Reproduce**\r\n\r\nSteps to reproduce the issue:\r\n1. Go to `~/bentoml/models/`\r\n2. Create a `.DS_Store` file\r\n3. Run `bentoml models list`\r\n4. See error\r\n\r\n\r\n**Expected behavior**\r\n\r\n<!--- A clear and concise description of what you expected to happen. -->\r\nAll files should be skipped when scanning for models.\r\n\r\n\r\n**Screenshots/Logs**\r\n\r\n```shell\r\n[19:12:41] WARNING  [boot] converting .DS_Store to lowercase: .ds_store         \r\nTraceback (most recent call last):\r\n  File \"/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py\", line 194, in _run_module_as_main\r\n    return _run_code(code, main_globals, None,\r\n  File \"/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/runpy.py\", line 87, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/__main__.py\", line 4, in <module>\r\n    create_bentoml_cli()()\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 1128, in __call__\r\n    return self.main(*args, **kwargs)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 1053, in main\r\n    rv = self.invoke(ctx)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 1659, in invoke\r\n    return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 1659, in invoke\r\n    return _process_result(sub_ctx.command.invoke(sub_ctx))\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 1395, in invoke\r\n    return ctx.invoke(self.callback, **ctx.params)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/click/core.py\", line 754, in invoke\r\n    return __callback(*args, **kwargs)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/cli/model_management.py\", line 90, in list_models\r\n    models = model_store.list(model_name)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py\", line 63, in list\r\n    return [\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py\", line 64, in <listcomp>\r\n    ver for _d in sorted(self._fs.listdir(\"/\")) for ver in self.list(_d)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/store.py\", line 67, in list\r\n    _tag = Tag.from_taglike(tag)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py\", line 221, in from_taglike\r\n    return cls.from_str(taglike)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py\", line 226, in from_str\r\n    return cls(tag_str, None)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/types.py\", line 180, in __init__\r\n    validate_tag_str(lname)\r\n  File \"/Users/spence/Library/Python/3.8/lib/python/site-packages/bentoml/_internal/utils/validation.py\", line 29, in validate_tag_str\r\n    raise InvalidArgument(f\"{value} is not a valid tag: \" + \", and \".join(errors))\r\nbentoml.exceptions.InvalidArgument: .ds_store is not a valid tag: a tag's name or version must consist of alphanumeric characters, '_', '-', or '.', and must start and end with an alphanumeric character\r\n```\r\n\r\n\r\n**Environment:**\r\n - OS: MacOS 12.2.1\r\n - Python 3.8.9\r\n - BentoML 1.0.0a4\r\n\r\n\r\n**Additional context**\r\n\r\nMacOS creates .DS_Store files automatically, so I ran into this bug after opening the folder and sorting the files \ud83d\ude05\r\n\n", "before_files": [{"content": "import os\nimport typing as t\nimport datetime\nfrom abc import ABC\nfrom abc import abstractmethod\nfrom contextlib import contextmanager\n\nimport fs\nimport fs.errors\nfrom fs.base import FS\n\nfrom .types import Tag\nfrom .types import PathType\nfrom ..exceptions import NotFound\nfrom ..exceptions import BentoMLException\n\nT = t.TypeVar(\"T\")\n\n\nclass StoreItem(ABC):\n    @property\n    @abstractmethod\n    def tag(self) -> Tag:\n        raise NotImplementedError\n\n    @classmethod\n    @abstractmethod\n    def from_fs(cls: t.Type[T], item_fs: FS) -> T:\n        raise NotImplementedError\n\n    @property\n    @abstractmethod\n    def creation_time(self) -> datetime.datetime:\n        raise NotImplementedError\n\n    def __repr__(self):\n        return f'{self.__class__.__name__}(tag=\"{self.tag}\")'\n\n\nItem = t.TypeVar(\"Item\", bound=StoreItem)\n\n\nclass Store(ABC, t.Generic[Item]):\n    \"\"\"An FsStore manages items under the given base filesystem.\n\n    Note that FsStore has no consistency checks; it assumes that no direct modification\n    of the files in its directory has occurred.\n\n    \"\"\"\n\n    _fs: FS\n    _item_type: t.Type[Item]\n\n    @abstractmethod\n    def __init__(self, base_path: t.Union[PathType, FS], item_type: t.Type[Item]):\n        self._item_type = item_type\n        if isinstance(base_path, os.PathLike):\n            base_path = base_path.__fspath__()\n        self._fs = fs.open_fs(base_path)\n\n    def list(self, tag: t.Optional[t.Union[Tag, str]] = None) -> t.List[Item]:\n        if not tag:\n            return [\n                ver for _d in sorted(self._fs.listdir(\"/\")) for ver in self.list(_d)\n            ]\n\n        _tag = Tag.from_taglike(tag)\n        if _tag.version is None:\n            if not self._fs.isdir(_tag.name):\n                raise NotFound(\n                    f\"no {self._item_type.__name__}s with name '{_tag.name}' found\"\n                )\n\n            tags = sorted(\n                [\n                    Tag(_tag.name, f.name)\n                    for f in self._fs.scandir(_tag.name)\n                    if f.is_dir\n                ]\n            )\n            return [self._get_item(t) for t in tags]\n        else:\n            return [self._get_item(_tag)] if self._fs.isdir(_tag.path()) else []\n\n    def _get_item(self, tag: Tag) -> Item:\n        \"\"\"\n        Creates a new instance of Item that represents the item with tag `tag`.\n        \"\"\"\n        return self._item_type.from_fs(self._fs.opendir(tag.path()))\n\n    def get(self, tag: t.Union[Tag, str]) -> Item:\n        \"\"\"\n        store.get(\"my_bento\")\n        store.get(\"my_bento:v1.0.0\")\n        store.get(Tag(\"my_bento\", \"latest\"))\n        \"\"\"\n        _tag = Tag.from_taglike(tag)\n        if _tag.version is None or _tag.version == \"latest\":\n            try:\n                _tag.version = self._fs.readtext(_tag.latest_path())\n            except fs.errors.ResourceNotFound:\n                raise NotFound(\n                    f\"no {self._item_type.__name__}s with name '{_tag.name}' exist in BentoML store {self._fs}\"\n                )\n\n        path = _tag.path()\n        if self._fs.exists(path):\n            return self._get_item(_tag)\n\n        matches = self._fs.glob(f\"{path}*/\")\n        counts = matches.count().directories\n        if counts == 0:\n            raise NotFound(\n                f\"{self._item_type.__name__} '{tag}' is not found in BentoML store {self._fs}\"\n            )\n        elif counts == 1:\n            match = next(iter(matches))\n            return self._get_item(Tag(_tag.name, match.info.name))\n        else:\n            vers: t.List[str] = []\n            for match in matches:\n                vers += match.info.name\n            raise BentoMLException(\n                f\"multiple versions matched by {_tag.version}: {vers}\"\n            )\n\n    @contextmanager\n    def register(self, tag: t.Union[str, Tag]):\n        _tag = Tag.from_taglike(tag)\n\n        item_path = _tag.path()\n        if self._fs.exists(item_path):\n            raise BentoMLException(\n                f\"Item '{_tag}' already exists in the store {self._fs}\"\n            )\n        self._fs.makedirs(item_path)\n        try:\n            yield self._fs.getsyspath(item_path)\n        finally:\n            # item generation is most likely successful, link latest path\n            if (\n                not self._fs.exists(_tag.latest_path())\n                or self.get(_tag).creation_time > self.get(_tag.name).creation_time\n            ):\n                with self._fs.open(_tag.latest_path(), \"w\") as latest_file:\n                    latest_file.write(_tag.version)\n\n    def delete(self, tag: t.Union[str, Tag]) -> None:\n        _tag = Tag.from_taglike(tag)\n\n        if not self._fs.exists(_tag.path()):\n            raise NotFound(f\"{self._item_type.__name__} '{tag}' not found\")\n\n        self._fs.removetree(_tag.path())\n        if self._fs.isdir(_tag.name):\n            versions = self.list(_tag.name)\n            if len(versions) == 0:\n                # if we've removed all versions, remove the directory\n                self._fs.removetree(_tag.name)\n            else:\n                new_latest = sorted(versions, key=lambda x: x.creation_time)[-1]\n                # otherwise, update the latest version\n                assert new_latest.tag.version is not None\n                self._fs.writetext(_tag.latest_path(), new_latest.tag.version)\n", "path": "bentoml/_internal/store.py"}], "after_files": [{"content": "import os\nimport typing as t\nimport datetime\nfrom abc import ABC\nfrom abc import abstractmethod\nfrom contextlib import contextmanager\n\nimport fs\nimport fs.errors\nfrom fs.base import FS\n\nfrom .types import Tag\nfrom .types import PathType\nfrom ..exceptions import NotFound\nfrom ..exceptions import BentoMLException\n\nT = t.TypeVar(\"T\")\n\n\nclass StoreItem(ABC):\n    @property\n    @abstractmethod\n    def tag(self) -> Tag:\n        raise NotImplementedError\n\n    @classmethod\n    @abstractmethod\n    def from_fs(cls: t.Type[T], item_fs: FS) -> T:\n        raise NotImplementedError\n\n    @property\n    @abstractmethod\n    def creation_time(self) -> datetime.datetime:\n        raise NotImplementedError\n\n    def __repr__(self):\n        return f'{self.__class__.__name__}(tag=\"{self.tag}\")'\n\n\nItem = t.TypeVar(\"Item\", bound=StoreItem)\n\n\nclass Store(ABC, t.Generic[Item]):\n    \"\"\"An FsStore manages items under the given base filesystem.\n\n    Note that FsStore has no consistency checks; it assumes that no direct modification\n    of the files in its directory has occurred.\n\n    \"\"\"\n\n    _fs: FS\n    _item_type: t.Type[Item]\n\n    @abstractmethod\n    def __init__(self, base_path: t.Union[PathType, FS], item_type: t.Type[Item]):\n        self._item_type = item_type\n        if isinstance(base_path, os.PathLike):\n            base_path = base_path.__fspath__()\n        self._fs = fs.open_fs(base_path)\n\n    def list(self, tag: t.Optional[t.Union[Tag, str]] = None) -> t.List[Item]:\n        if not tag:\n            return [\n                ver\n                for _d in sorted(self._fs.listdir(\"/\"))\n                if self._fs.isdir(_d)\n                for ver in self.list(_d)\n            ]\n\n        _tag = Tag.from_taglike(tag)\n        if _tag.version is None:\n            if not self._fs.isdir(_tag.name):\n                raise NotFound(\n                    f\"no {self._item_type.__name__}s with name '{_tag.name}' found\"\n                )\n\n            tags = sorted(\n                [\n                    Tag(_tag.name, f.name)\n                    for f in self._fs.scandir(_tag.name)\n                    if f.is_dir\n                ]\n            )\n            return [self._get_item(t) for t in tags]\n        else:\n            return [self._get_item(_tag)] if self._fs.isdir(_tag.path()) else []\n\n    def _get_item(self, tag: Tag) -> Item:\n        \"\"\"\n        Creates a new instance of Item that represents the item with tag `tag`.\n        \"\"\"\n        return self._item_type.from_fs(self._fs.opendir(tag.path()))\n\n    def get(self, tag: t.Union[Tag, str]) -> Item:\n        \"\"\"\n        store.get(\"my_bento\")\n        store.get(\"my_bento:v1.0.0\")\n        store.get(Tag(\"my_bento\", \"latest\"))\n        \"\"\"\n        _tag = Tag.from_taglike(tag)\n        if _tag.version is None or _tag.version == \"latest\":\n            try:\n                _tag.version = self._fs.readtext(_tag.latest_path())\n            except fs.errors.ResourceNotFound:\n                raise NotFound(\n                    f\"no {self._item_type.__name__}s with name '{_tag.name}' exist in BentoML store {self._fs}\"\n                )\n\n        path = _tag.path()\n        if self._fs.exists(path):\n            return self._get_item(_tag)\n\n        matches = self._fs.glob(f\"{path}*/\")\n        counts = matches.count().directories\n        if counts == 0:\n            raise NotFound(\n                f\"{self._item_type.__name__} '{tag}' is not found in BentoML store {self._fs}\"\n            )\n        elif counts == 1:\n            match = next(iter(matches))\n            return self._get_item(Tag(_tag.name, match.info.name))\n        else:\n            vers: t.List[str] = []\n            for match in matches:\n                vers += match.info.name\n            raise BentoMLException(\n                f\"multiple versions matched by {_tag.version}: {vers}\"\n            )\n\n    @contextmanager\n    def register(self, tag: t.Union[str, Tag]):\n        _tag = Tag.from_taglike(tag)\n\n        item_path = _tag.path()\n        if self._fs.exists(item_path):\n            raise BentoMLException(\n                f\"Item '{_tag}' already exists in the store {self._fs}\"\n            )\n        self._fs.makedirs(item_path)\n        try:\n            yield self._fs.getsyspath(item_path)\n        finally:\n            # item generation is most likely successful, link latest path\n            if (\n                not self._fs.exists(_tag.latest_path())\n                or self.get(_tag).creation_time > self.get(_tag.name).creation_time\n            ):\n                with self._fs.open(_tag.latest_path(), \"w\") as latest_file:\n                    latest_file.write(_tag.version)\n\n    def delete(self, tag: t.Union[str, Tag]) -> None:\n        _tag = Tag.from_taglike(tag)\n\n        if not self._fs.exists(_tag.path()):\n            raise NotFound(f\"{self._item_type.__name__} '{tag}' not found\")\n\n        self._fs.removetree(_tag.path())\n        if self._fs.isdir(_tag.name):\n            versions = self.list(_tag.name)\n            if len(versions) == 0:\n                # if we've removed all versions, remove the directory\n                self._fs.removetree(_tag.name)\n            else:\n                new_latest = sorted(versions, key=lambda x: x.creation_time)[-1]\n                # otherwise, update the latest version\n                assert new_latest.tag.version is not None\n                self._fs.writetext(_tag.latest_path(), new_latest.tag.version)\n", "path": "bentoml/_internal/store.py"}]}