Skip to content

Commit b09ae47

Browse files
author
Douglas Blank
committed
Version 2.6.0: added cometx copy --path
1 parent e49da61 commit b09ae47

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ cometx copy examples:
180180
```
181181
cometx copy SOURCE DESTINATION
182182
cometx copy --symlink SOURCE DESTINATION
183+
cometx copy --path /base/path SOURCE DESTINATION
184+
cometx copy --path ~/Downloads SOURCE DESTINATION
183185
```
184186

185187
where SOURCE is:
@@ -232,6 +234,23 @@ Not all combinations are possible:
232234
* `--quiet` - If given, don't display update info
233235
* `--symlink` - Instead of copying, create a link to an experiment in a project
234236
* `--sync` - Check to see if experiment name has been created first; if so, skip
237+
* `--path PATH` - Path to prepend to workspace_src when accessing files (supports ~ for home directory)
238+
239+
### Using --path
240+
241+
The `--path` option allows you to specify a base directory where your workspace folders are located. This is useful when your downloaded experiments are stored in a specific directory structure.
242+
243+
Examples:
244+
```bash
245+
# Copy from experiments in /data/experiments/workspace
246+
cometx copy --path /data/experiments workspace dest-workspace
247+
248+
# Copy from experiments in your home directory
249+
cometx copy --path ~ workspace dest-workspace
250+
251+
# Copy from experiments in Downloads folder
252+
cometx copy --path ~/Downloads workspace dest-workspace
253+
```
235254

236255
For more information, `cometx copy --help`
237256

cometx/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
# the express permission of Comet ML Inc.
1313
# *******************************************************
1414

15-
version_info = (2, 5, 3)
15+
version_info = (2, 6, 0)
1616
__version__ = ".".join(map(str, version_info))

cometx/cli/copy.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,21 @@ def get_parser_arguments(parser):
190190
type=int,
191191
default=None,
192192
)
193+
parser.add_argument(
194+
"--path",
195+
help="Path to prepend to workspace_src when accessing files (supports ~ for home directory)",
196+
type=str,
197+
default=None,
198+
)
193199

194200

195201
def copy(parsed_args, remaining=None):
196202
# Called via `cometx copy ...`
197203
try:
198204
copy_manager = CopyManager(
199-
max_concurrent_uploads=parsed_args.parallel, debug=parsed_args.debug
205+
max_concurrent_uploads=parsed_args.parallel,
206+
debug=parsed_args.debug,
207+
path=parsed_args.path,
200208
)
201209
copy_manager.copy(
202210
parsed_args.COMET_SOURCE,
@@ -508,7 +516,7 @@ def _create_progress_bar(self, progress, width=20):
508516

509517

510518
class CopyManager:
511-
def __init__(self, max_concurrent_uploads=None, debug=False):
519+
def __init__(self, max_concurrent_uploads=None, debug=False, path=None):
512520
"""
513521
| Destination: | WORKSPACE | WORKSPACE/PROJECT |
514522
| Source (below) | | |
@@ -522,6 +530,7 @@ def __init__(self, max_concurrent_uploads=None, debug=False):
522530

523531
self.api = API()
524532
self.debug = debug
533+
self.path = path
525534
# Calculate default number of workers based on CPU count, similar to download command
526535
self.max_concurrent_uploads = (
527536
min(32, os.cpu_count() + 4)
@@ -542,6 +551,13 @@ def __init__(self, max_concurrent_uploads=None, debug=False):
542551

543552
self._start_upload_workers()
544553

554+
def _get_path(self, workspace_src, project_src, *items):
555+
"""Get the full path, prepending self.path if provided and joining all components"""
556+
if self.path:
557+
expanded_path = os.path.expanduser(self.path)
558+
return os.path.join(expanded_path, workspace_src, project_src, *items)
559+
return os.path.join(workspace_src, project_src, *items)
560+
545561
def _start_upload_workers(self):
546562
"""Start background worker threads for handling uploads"""
547563
for i in range(self.max_concurrent_uploads):
@@ -812,7 +828,7 @@ def copy(self, source, destination, symlink, ignore, debug, sync):
812828
if project_src == "panels":
813829
# experiment_src may be "*" or filename
814830
for filename in glob.glob(
815-
os.path.join(workspace_src, project_src, experiment_src)
831+
self._get_path(workspace_src, project_src, experiment_src)
816832
):
817833
print("Uploading panel zip: %r to %r..." % (filename, workspace_dst))
818834
self.api.upload_panel_zip(workspace_dst, filename)
@@ -870,7 +886,7 @@ def copy(self, source, destination, symlink, ignore, debug, sync):
870886

871887
# Next, check if the project_dst exists:
872888
if temp_project_dst not in projects:
873-
project_metadata_path = os.path.join(
889+
project_metadata_path = self._get_path(
874890
workspace_src, project_src, "project_metadata.json"
875891
)
876892
if os.path.exists(project_metadata_path):
@@ -896,7 +912,11 @@ def copy(self, source, destination, symlink, ignore, debug, sync):
896912
)
897913
elif "experiments" not in self.ignore:
898914
self.copy_experiment_to(
899-
experiment_folder, workspace_dst, temp_project_dst
915+
experiment_folder,
916+
workspace_dst,
917+
temp_project_dst,
918+
workspace_src,
919+
folder_project,
900920
)
901921

902922
def create_experiment(self, workspace_dst, project_dst, offline=True):
@@ -953,15 +973,18 @@ def filtered_method(message):
953973
return experiment
954974

955975
def get_experiment_folders(self, workspace_src, project_src, experiment_src):
956-
for path in glob.iglob(f"{workspace_src}/{project_src}/{experiment_src}"):
976+
full_path = self._get_path(workspace_src, project_src, experiment_src)
977+
for path in glob.iglob(full_path):
957978
if any(
958979
[path.endswith("~"), path.endswith(".json"), path.endswith(".jsonl")]
959980
):
960981
continue
961982
else:
962983
yield path
963984

964-
def copy_experiment_to(self, experiment_folder, workspace_dst, project_dst):
985+
def copy_experiment_to(
986+
self, experiment_folder, workspace_dst, project_dst, workspace_src, project_src
987+
):
965988
title = experiment_folder
966989
experiment_name = None
967990
# See if there is a name:
@@ -981,10 +1004,7 @@ def copy_experiment_to(self, experiment_folder, workspace_dst, project_dst):
9811004
# Copy other project-level items to an experiment:
9821005
if "reports" not in self.ignore and not self.copied_reports:
9831006
experiment = None
984-
workspace_src, project_src, _ = experiment_folder.replace("\\", "/").split(
985-
"/"
986-
)
987-
reports = os.path.join(workspace_src, project_src, "reports", "*")
1007+
reports = self._get_path(workspace_src, project_src, "reports", "*")
9881008
for filename in glob.glob(reports):
9891009
if filename.endswith("reports_metadata.jsonl"):
9901010
continue

0 commit comments

Comments
 (0)