Coretex
_folder_manager.py
1 # Copyright (C) 2023 Coretex LLC
2 
3 # This file is part of Coretex.ai
4 
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
14 
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 
18 from typing import Iterator, Optional, Union
19 from pathlib import Path
20 from contextlib import contextmanager
21 
22 import os
23 import shutil
24 import uuid
25 
26 
28 
29  """
30  Used for handling everything related to local storage
31  when working with Coretex
32 
33  Contains
34  --------
35  samplesFolder : Path
36  folder where samples are stored
37  modelsFolder : Path
38  folder where models are stored
39  temp : Path
40  folder where temp files and folders are stored,
41  this is deleted when the run has finished executing
42  datasetsFolder : Path
43  folder where datasets are stored (samples are symlinked for datasets)
44  cache : Path
45  folder where cache module stores items
46  logs : Path
47  folder where node and run logs are stored
48  environments : Path
49  folder where node stores python environments
50  """
51 
52  def __init__(self, storagePath: Union[Path, str]):
53  if isinstance(storagePath, str):
54  storagePath = Path(storagePath)
55 
56  self._root_root = storagePath.expanduser()
57 
58  self.samplesFoldersamplesFolder = self._createFolder_createFolder("samples")
59  self.modelsFoldermodelsFolder = self._createFolder_createFolder("models")
60  self.datasetsFolderdatasetsFolder = self._createFolder_createFolder("datasets")
61  self.cachecache = self._createFolder_createFolder("cache")
62  self.logslogs = self._createFolder_createFolder("logs")
63  self.environmentsenvironments = self._createFolder_createFolder("environments")
64  self.temptemp = self._createFolder_createFolder("temp")
65  self._artifactsFolder_artifactsFolder = self._createFolder_createFolder("artifacts")
66 
67  self.runsLogDirectoryrunsLogDirectory = self.logslogs / "runs"
68  self.runsLogDirectoryrunsLogDirectory.mkdir(exist_ok = True)
69 
70  self.coretexpylibLogscoretexpylibLogs = self.logslogs / "coretexpylib"
71  self.coretexpylibLogscoretexpylibLogs.mkdir(exist_ok = True)
72 
73  def _createFolder(self, name: str) -> Path:
74  path = self._root_root / name
75 
76  if not path.exists():
77  path.mkdir(parents = True, exist_ok = True)
78 
79  return path
80 
81  def createTempFolder(self, name: str) -> Path:
82  """
83  Creates temp folder which is deleted once
84  the run has finished executing
85 
86  Parameters
87  ----------
88  name : str
89  name of the folder
90 
91  Returns
92  -------
93  Path -> path to the created folder
94 
95  Raises
96  ------
97  FileExistsError -> if the temp folder already exists
98 
99  Example
100  -------
101  >>> from coretex import folder_manager
102  \b
103  >>> dummyFolderPath = folder_manager.createTempFolder("dummyTempFolder")
104  >>> print(dummyFolderPath)
105  "/Users/X/.coretex/temp/dummyTempFolder"
106  """
107 
108  tempFolderPath = self.temptemp / name
109 
110  if tempFolderPath.exists():
111  raise FileExistsError
112 
113  tempFolderPath.mkdir()
114  return tempFolderPath
115 
116  def getArtifactsFolder(self, taskRunId: int) -> Path:
117  """
118  Retrieves the path to where the artifacts are stored
119  for the specified TaskRuns
120 
121  Parameters
122  ----------
123  taskRunId : int
124  id of the TaskRun
125 
126  Returns
127  -------
128  Path -> path to the TaskRun artifacts local storage
129 
130  Example
131  -------
132  >>> from coretex.folder_management import FolderManager
133  \b
134  >>> artifactsFolderPath = FolderManager.instance().getArtifactsFolder(1023)
135  >>> print(artifactsFolderPath)
136  Path("/Users/bogdanbm/.coretex/artifacts/1023")
137  """
138 
139  return self._artifactsFolder_artifactsFolder / str(taskRunId)
140 
141  def clearDirectory(self, path: Path) -> None:
142  shutil.rmtree(path)
143  path.mkdir()
144 
145  def clearTempFiles(self) -> None:
146  """
147  Deletes all temp files and folders (including artifacts)
148  """
149 
150  self.clearDirectoryclearDirectory(self.temptemp)
151  self.clearDirectoryclearDirectory(self._artifactsFolder_artifactsFolder)
152 
153  def getRunLogsDir(self, taskRunId: int) -> Path:
154  taskRunLogsDir = self.runsLogDirectoryrunsLogDirectory / str(taskRunId)
155  taskRunLogsDir.mkdir(parents = True, exist_ok = True)
156 
157  return taskRunLogsDir
158 
159  @contextmanager
160  def tempFile(self, name: Optional[str] = None) -> Iterator[Path]:
161  """
162  Returns a path to temporary file and deletes
163  it if it exists once the context is exited.
164 
165  Parameters
166  ----------
167  name : Optional[str]
168  Name of the file. If not specified a random uuid4
169  will be generated and used as the name
170 
171  Returns
172  -------
173  Iterator[Path] -> path to the file
174  """
175 
176  if name is None:
177  name = str(uuid.uuid4())
178 
179  path = self.temptemp / name
180  if path.exists():
181  raise FileExistsError(path)
182  try:
183  yield path
184  finally:
185  path.unlink(missing_ok = True)
186 
187 
188 folder_manager = FolderManager(os.environ["CTX_STORAGE_PATH"])
Path getArtifactsFolder(self, int taskRunId)
Iterator[Path] tempFile(self, Optional[str] name=None)