sl-shared-assets 1.0.0rc17__py3-none-any.whl → 1.0.0rc19__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sl-shared-assets might be problematic. Click here for more details.

@@ -15,6 +15,7 @@ import appdirs
15
15
  from ataraxis_base_utilities import LogLevel, console, ensure_directory_exists
16
16
  from ataraxis_data_structures import YamlConfig
17
17
  from ataraxis_time.time_helpers import get_timestamp
18
+ import dacite
18
19
 
19
20
  from .configuration_data import ExperimentConfiguration
20
21
 
@@ -1111,6 +1112,7 @@ class SessionData(YamlConfig):
1111
1112
  cls,
1112
1113
  session_path: Path,
1113
1114
  on_server: bool,
1115
+ make_directories: bool = True,
1114
1116
  ) -> "SessionData":
1115
1117
  """Loads the SessionData instance from the target session's session_data.yaml file.
1116
1118
 
@@ -1131,6 +1133,10 @@ class SessionData(YamlConfig):
1131
1133
  a non-server machine. Note, non-server runtimes use the same 'root' directory to store raw_data and
1132
1134
  processed_data subfolders. BioHPC server runtimes use different volumes (drives) to store these
1133
1135
  subfolders.
1136
+ make_directories: Determines whether to attempt creating any missing directories. Generally, this option
1137
+ is safe to be True for all destinations other than some specific BioHPC server runtimes, where some
1138
+ data is 'owned' by a general lab account and not the user account. These cases are only present for the
1139
+ sl-forgery library and are resolved by that library.
1134
1140
 
1135
1141
  Returns:
1136
1142
  An initialized SessionData instance for the session whose data is stored at the provided path.
@@ -1151,7 +1157,7 @@ class SessionData(YamlConfig):
1151
1157
  console.error(message=message, error=FileNotFoundError)
1152
1158
 
1153
1159
  # Loads class data from .yaml file
1154
- instance: SessionData = cls.from_yaml(file_path=session_data_path) # type: ignore
1160
+ instance: SessionData = cls._safe_load(path=session_data_path)
1155
1161
 
1156
1162
  # The method assumes that the 'donor' .yaml file is always stored inside the raw_data directory of the session
1157
1163
  # to be processed. Since the directory itself might have moved (between or even within the same PC) relative to
@@ -1162,7 +1168,6 @@ class SessionData(YamlConfig):
1162
1168
  # RAW DATA
1163
1169
  new_root = local_root.joinpath(instance.project_name, instance.animal_id, instance.session_name, "raw_data")
1164
1170
  instance.raw_data.resolve_paths(root_directory_path=new_root)
1165
- instance.raw_data.make_directories()
1166
1171
 
1167
1172
  # Uses the adjusted raw_data section to load the ProjectConfiguration instance. This is used below to resolve
1168
1173
  # all other SessionData sections, as it stores various required root directories.
@@ -1179,12 +1184,10 @@ class SessionData(YamlConfig):
1179
1184
  root_directory_path=new_root,
1180
1185
  experiment_name=instance.experiment_name,
1181
1186
  )
1182
- instance.configuration_data.make_directories()
1183
1187
 
1184
1188
  # DEEPLABCUT
1185
1189
  new_root = local_root.joinpath(instance.project_name, "deeplabcut")
1186
1190
  instance.deeplabcut_data.resolve_paths(root_directory_path=new_root)
1187
- instance.deeplabcut_data.make_directories()
1188
1191
 
1189
1192
  # Resolves the roots for all VRPC-specific sections that use the data from the ProjectConfiguration instance:
1190
1193
 
@@ -1242,25 +1245,26 @@ class SessionData(YamlConfig):
1242
1245
  instance.project_name, instance.animal_id, instance.session_name, "processed_data"
1243
1246
  )
1244
1247
  )
1245
- instance.processed_data.make_directories()
1246
-
1247
- # Ensures that project configuration and session data classes are present in both raw_data and processed_data
1248
- # directories. This ensures that all data of the session can always be traced to the parent project, animal,
1249
- # and session.
1250
- sh.copy2(
1251
- src=instance.raw_data.session_data_path,
1252
- dst=instance.processed_data.session_data_path,
1253
- )
1254
- sh.copy2(
1255
- src=instance.raw_data.project_configuration_path,
1256
- dst=instance.processed_data.project_configuration_path,
1257
- )
1258
1248
 
1259
1249
  # Generates data directory hierarchies that may be missing on the local machine
1260
- instance.raw_data.make_directories()
1261
- instance.configuration_data.make_directories()
1262
- instance.deeplabcut_data.make_directories()
1263
- instance.processed_data.make_directories()
1250
+ if make_directories:
1251
+ instance.raw_data.make_directories()
1252
+ instance.configuration_data.make_directories()
1253
+ instance.deeplabcut_data.make_directories()
1254
+ instance.processed_data.make_directories()
1255
+ instance.processed_data.make_directories()
1256
+
1257
+ # Ensures that project configuration and session data classes are present in both raw_data and
1258
+ # processed_data directories. This ensures that all data of the session can always be traced to the parent
1259
+ # project, animal, and session.
1260
+ sh.copy2(
1261
+ src=instance.raw_data.session_data_path,
1262
+ dst=instance.processed_data.session_data_path,
1263
+ )
1264
+ sh.copy2(
1265
+ src=instance.raw_data.project_configuration_path,
1266
+ dst=instance.processed_data.project_configuration_path,
1267
+ )
1264
1268
 
1265
1269
  # Returns the initialized SessionData instance to caller
1266
1270
  return instance
@@ -1274,6 +1278,8 @@ class SessionData(YamlConfig):
1274
1278
  create() method runtime.
1275
1279
  """
1276
1280
 
1281
+ # Generates a copy of the original class to avoid modifying the instance that will be used for further
1282
+ # processing
1277
1283
  origin = copy.deepcopy(self)
1278
1284
 
1279
1285
  # Resets all path fields to null. These fields are not loaded from disk when the instance is loaded, so setting
@@ -1289,5 +1295,53 @@ class SessionData(YamlConfig):
1289
1295
  origin.destinations = None # type: ignore
1290
1296
 
1291
1297
  # Saves instance data as a .YAML file
1292
- self.to_yaml(file_path=self.raw_data.session_data_path)
1293
- self.to_yaml(file_path=self.processed_data.session_data_path)
1298
+ origin.to_yaml(file_path=self.raw_data.session_data_path)
1299
+ origin.to_yaml(file_path=self.processed_data.session_data_path)
1300
+
1301
+ @classmethod
1302
+ def _safe_load(cls, path: Path) -> "SessionData":
1303
+ """Loads a SessionData class instance into memory in a way that avoids collisions with outdated SessionData
1304
+ formats.
1305
+
1306
+ This method is used instead of the default method inherited from the YamlConfig class. Primarily, this is used
1307
+ to avoid errors with old SessionData class formats that contain some data that is either no longer present or
1308
+ cannot be loaded from YAML. Using this custom method ensures we can load any SessionData class, provided it
1309
+ contains the required header fields.
1310
+
1311
+ Returns:
1312
+ The SessionData instance initialized using the resolved header data.
1313
+ """
1314
+
1315
+ # Reads the file content without using the YAML parsing methods.
1316
+ with open(path, 'r') as f:
1317
+ content = f.read()
1318
+
1319
+ # Extracts the necessary fields using regex
1320
+ fields_to_keep = {}
1321
+
1322
+ # Defines the field patterns for each field to extract
1323
+ patterns = {
1324
+ "project_name": r'project_name:\s*(.+?)(?=\n\w|\n$)',
1325
+ "animal_id": r'animal_id:\s*(.+?)(?=\n\w|\n$)',
1326
+ "session_name": r'session_name:\s*(.+?)(?=\n\w|\n$)',
1327
+ "session_type": r'session_type:\s*(.+?)(?=\n\w|\n$)',
1328
+ "experiment_name": r'experiment_name:\s*(.+?)(?=\n\w|\n$)'
1329
+ }
1330
+
1331
+ # Extracts each field
1332
+ for key, pattern in patterns.items():
1333
+ match = re.search(pattern, content)
1334
+ if match:
1335
+ fields_to_keep[key] = match.group(1).strip()
1336
+ # Solves a bug with how animal_id field is stored, where it contains both sets of quotes. May be helpful
1337
+ # to solve potential future issues with other fields too
1338
+ fields_to_keep[key] = fields_to_keep[key].replace("'", "")
1339
+ else:
1340
+ if key == "experiment_name":
1341
+ fields_to_keep[key] = "null" # Default for experiment_name
1342
+ else:
1343
+ fields_to_keep[key] = "" # Default for other fields
1344
+
1345
+ # Returns the data to caller
1346
+ return dacite.from_dict(data_class=cls, data=fields_to_keep) # type: ignore
1347
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sl-shared-assets
3
- Version: 1.0.0rc17
3
+ Version: 1.0.0rc19
4
4
  Summary: Stores assets shared between multiple Sun (NeuroAI) lab data pipelines.
5
5
  Project-URL: Homepage, https://github.com/Sun-Lab-NBB/sl-shared-assets
6
6
  Project-URL: Documentation, https://sl-shared-assets-api-docs.netlify.app/
@@ -695,6 +695,7 @@ Requires-Dist: ataraxis-base-utilities<4,>=3
695
695
  Requires-Dist: ataraxis-data-structures<4,>=3.1.1
696
696
  Requires-Dist: ataraxis-time<4,>=3
697
697
  Requires-Dist: click<9,>=8
698
+ Requires-Dist: dacite<2,>=1
698
699
  Requires-Dist: paramiko<4,>=3.5.1
699
700
  Requires-Dist: simple-slurm<1,>=0
700
701
  Requires-Dist: tqdm<5,>=4
@@ -716,6 +717,7 @@ Requires-Dist: types-tqdm<5,>=4; extra == 'conda'
716
717
  Provides-Extra: condarun
717
718
  Requires-Dist: appdirs<2,>=1; extra == 'condarun'
718
719
  Requires-Dist: click<9,>=8; extra == 'condarun'
720
+ Requires-Dist: dacite<2,>=1; extra == 'condarun'
719
721
  Requires-Dist: paramiko<4,>=3.5.1; extra == 'condarun'
720
722
  Requires-Dist: tqdm<5,>=4; extra == 'condarun'
721
723
  Provides-Extra: dev
@@ -4,7 +4,7 @@ sl_shared_assets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  sl_shared_assets/data_classes/__init__.py,sha256=pq-iyd4eyv1CPVcLcQQJBVAm7XCDWuZqxurrLOMW3e0,1702
5
5
  sl_shared_assets/data_classes/configuration_data.py,sha256=zKZ3cE2pZFDRiQ7off8hu2nV9JsBly9Phc5goY4qCH4,4163
6
6
  sl_shared_assets/data_classes/runtime_data.py,sha256=jSCvZG01gkcSUexFiKITjTJ8ZoF18qRfxiwhyrWW7-I,13964
7
- sl_shared_assets/data_classes/session_data.py,sha256=Xn7t6kbhQfif7oneT2SLppBGXCfmDGtYOKj3HM7t64U,79135
7
+ sl_shared_assets/data_classes/session_data.py,sha256=sRHgHNR4x1hc0dKLVteyz2tmYJrF2pKP9wzoqG1lxTg,81866
8
8
  sl_shared_assets/data_classes/surgery_data.py,sha256=Z4QZAZCz0_w7qrGMMzYn-fwwwycw3ki9SPJU0kD5Ap4,7425
9
9
  sl_shared_assets/server/__init__.py,sha256=nyX6-9ACcrQeRQOCNvBVrWSTHGjRPANIG_u0aq7HPTg,426
10
10
  sl_shared_assets/server/job.py,sha256=M7ZytqhluEV-YQPM9VQV3SqK-F9egQ3UcLc1SLBH4rA,7885
@@ -16,8 +16,8 @@ sl_shared_assets/tools/__init__.py,sha256=UWrNfseGupOrY4OK2PgDEJ-Q3LbSrPLC2pfaLm
16
16
  sl_shared_assets/tools/ascension_tools.py,sha256=y2w72Czpbw9LwgsbdEx_ckzMKTZ78cgKPTIk6vRYmAk,15877
17
17
  sl_shared_assets/tools/packaging_tools.py,sha256=LOKCKvT6UD_cidCONaI4ctWyej5zEwwdhhgwYrj60Kg,6746
18
18
  sl_shared_assets/tools/transfer_tools.py,sha256=J26kwOp_NpPSY0-xu5FTw9udte-rm_mW1FJyaTNoqQI,6606
19
- sl_shared_assets-1.0.0rc17.dist-info/METADATA,sha256=71y5EAy43UddnuutTvU2PGjupezOo8haw-PmMYQ30PM,47807
20
- sl_shared_assets-1.0.0rc17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
21
- sl_shared_assets-1.0.0rc17.dist-info/entry_points.txt,sha256=bdnmVAcK3nrKi9QEYeNMrCLFH5LQ4BMBfwbLIgLPtq4,222
22
- sl_shared_assets-1.0.0rc17.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
23
- sl_shared_assets-1.0.0rc17.dist-info/RECORD,,
19
+ sl_shared_assets-1.0.0rc19.dist-info/METADATA,sha256=7V58TU4cUqBvoc6f9az3PuPSj46D11UYHQ_mC_lBsNU,47884
20
+ sl_shared_assets-1.0.0rc19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
21
+ sl_shared_assets-1.0.0rc19.dist-info/entry_points.txt,sha256=bdnmVAcK3nrKi9QEYeNMrCLFH5LQ4BMBfwbLIgLPtq4,222
22
+ sl_shared_assets-1.0.0rc19.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
23
+ sl_shared_assets-1.0.0rc19.dist-info/RECORD,,