ugbio_cloud_utils 1.4.3.post0__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 ugbio_cloud_utils might be problematic. Click here for more details.

File without changes
@@ -0,0 +1,161 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import os
5
+ import sys
6
+
7
+ import boto3
8
+ from google.cloud import storage
9
+
10
+
11
+ def dir_path(string, *, check_cloud_path=False):
12
+ if os.path.isdir(string):
13
+ return string
14
+
15
+ if check_cloud_path:
16
+ if not string.startswith("gs://") and not string.startswith("s3://"):
17
+ raise ValueError(f"Invalid cloud path {string}\nMust be an s3 or gs path")
18
+ return string
19
+
20
+ raise NotADirectoryError(string)
21
+
22
+
23
+ def download_from_gs(bucket_name, source_blob_name, destination_file_name):
24
+ """Downloads a blob from the bucket."""
25
+ # bucket_name = "your-bucket-name"
26
+ # source_blob_name = "storage-object-name"
27
+ # destination_file_name = "local/path/to/file"
28
+
29
+ storage_client = storage.Client()
30
+
31
+ bucket = storage_client.bucket(bucket_name)
32
+ blob = bucket.blob(source_blob_name)
33
+ blob.download_to_filename(destination_file_name)
34
+
35
+
36
+ def download_from_s3(bucket_name, object_name, destination_file_name):
37
+ client = boto3.Session(profile_name="default").client("s3")
38
+ client.download_file(bucket_name, object_name, destination_file_name)
39
+
40
+
41
+ def optional_cloud_sync(
42
+ cloud_path_in,
43
+ local_dir_in="/data",
44
+ *,
45
+ print_output=False,
46
+ force_download=False,
47
+ raise_error_is_file_exists=False,
48
+ dry_run=False,
49
+ ):
50
+ if cloud_path_in.startswith(("gs://", "s3://")):
51
+ return cloud_sync(
52
+ cloud_path_in, local_dir_in, print_output, force_download, raise_error_is_file_exists, dry_run
53
+ )
54
+ return cloud_path_in
55
+
56
+
57
+ def cloud_sync( # noqa C901,PLR0912
58
+ cloud_path_in,
59
+ local_dir_in="/data",
60
+ *,
61
+ print_output=False,
62
+ force_download=False,
63
+ raise_error_is_file_exists=False,
64
+ dry_run=False,
65
+ ):
66
+ """Download a file from the cloud to a respective local directory with the same name
67
+
68
+ Parameters
69
+ ----------
70
+ cloud_path_in: str
71
+ Path to a file on the cloud (gs / s3), can also be a local file in which case nothing will happen
72
+ local_dir_in: str, optional
73
+ Local directory to which files will be downloaded, under subdirectory "cloud_sync"
74
+ print_output: bool, optional
75
+ Print log messages
76
+ force_download: bool, optional
77
+ If True, download file again even if file with the target name exists (default False)
78
+ raise_error_is_file_exists: bool, optional
79
+ If True and local file already exists, raise ValueError (default False)
80
+ dry_run: bool, optional
81
+ If True, return local path without downloading (default False)
82
+ :raises NotADirectoryError: Not a directory
83
+ :raises FileExistsError: Target local file exists
84
+ :raises NotImplementedError: Unsupported cloud service
85
+ :raises KeyboardInterrupt: Keyboard interrupt
86
+ :returns: a local path to which file was downloaded. If cloud_path_in was an existing local
87
+ file it is returned as is
88
+ -------
89
+
90
+ """
91
+ if os.path.isfile(cloud_path_in):
92
+ return cloud_path_in
93
+ if not os.path.isdir(local_dir_in):
94
+ raise NotADirectoryError(local_dir_in)
95
+ dir_path(cloud_path_in, check_cloud_path=True)
96
+ cloud_service = cloud_path_in.split(":")[0]
97
+ bucket = cloud_path_in.split("/")[2]
98
+ blob = "/".join(cloud_path_in.split("/")[3:])
99
+ local_path = os.path.join(
100
+ local_dir_in,
101
+ "cloud_sync",
102
+ cloud_service,
103
+ bucket,
104
+ blob,
105
+ )
106
+ if dry_run:
107
+ return local_path
108
+ if not force_download and os.path.isfile(local_path):
109
+ if raise_error_is_file_exists:
110
+ raise FileExistsError(f"target local file {local_path} exists")
111
+ if print_output:
112
+ sys.stdout.write(f"Local file {local_path} already exists, skipping...\n")
113
+ else:
114
+ try:
115
+ if print_output:
116
+ sys.stdout.write(f"Downloading to {local_path}\n")
117
+ os.makedirs(os.path.dirname(local_path), exist_ok=True)
118
+ if cloud_service == "gs":
119
+ download_from_gs(bucket, blob, local_path)
120
+ elif cloud_service == "s3":
121
+ download_from_s3(bucket, blob, local_path)
122
+ else:
123
+ raise NotImplementedError()
124
+ except KeyboardInterrupt:
125
+ if os.path.isfile(local_path):
126
+ sys.stdout.write(f"Keyboard Interrupt - removing incomplete file {local_path}\n")
127
+ os.remove(local_path)
128
+ raise
129
+
130
+ return local_path
131
+
132
+
133
+ def parse_args(argv):
134
+ parser = argparse.ArgumentParser(description=run.__doc__)
135
+ parser.add_argument("cloud_path", type=str, help="full path to aws s3 / google storage file")
136
+ parser.add_argument(
137
+ "--local_dir",
138
+ type=dir_path,
139
+ default="/data",
140
+ help="local directory the files will sync to",
141
+ )
142
+ args = parser.parse_args(argv[1:])
143
+ return args
144
+
145
+
146
+ def run(argv: list[str]):
147
+ """Download aws s3 or google storage file to a respective local path"""
148
+ args = parse_args(argv)
149
+ cloud_path = args.cloud_path
150
+ local_dir = args.local_dir
151
+ if not os.path.isdir(local_dir):
152
+ raise ValueError(f"local_dir {local_dir} does not exist")
153
+ cloud_sync(cloud_path, local_dir, print_output=True)
154
+
155
+
156
+ def main():
157
+ run(sys.argv)
158
+
159
+
160
+ if __name__ == "__main__":
161
+ run(sys.argv)
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.1
2
+ Name: ugbio_cloud_utils
3
+ Version: 1.4.3.post0
4
+ Summary: Ultima Genomics cloud python utils
5
+ Author-email: Avigail Moldovam <avigail.moldovan@ultimagen.com>
6
+ Requires-Python: >=3.11
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: boto3>=1.35.66
9
+ Requires-Dist: google-cloud>=0.34.0
10
+
11
+ # ugbio_cloud_utils
12
+
13
+ This module includes cloud (AWS/GS) python utils for bioinformatics pipelines.
@@ -0,0 +1,7 @@
1
+ ugbio_cloud_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ ugbio_cloud_utils/cloud_sync.py,sha256=Q4iN_IkEQlyIs3sPo2iyCRh0Qhihp9oDeadnnLuYcLI,5228
3
+ ugbio_cloud_utils-1.4.3.post0.dist-info/METADATA,sha256=LfrrsCvOTLa6Z5pamQ98ITdBCzdyXYMXRSEzSbFtsCg,407
4
+ ugbio_cloud_utils-1.4.3.post0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
5
+ ugbio_cloud_utils-1.4.3.post0.dist-info/entry_points.txt,sha256=HEctXBVCAXP9qorkrhKidMG2Rq5aA0O6A_LZmhN6X4g,89
6
+ ugbio_cloud_utils-1.4.3.post0.dist-info/top_level.txt,sha256=RA9O5nTwkzMa9Bvab5CNRKw5WPkgvI4rA6TjFcREny0,18
7
+ ugbio_cloud_utils-1.4.3.post0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.6.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ cloud_sync = ugbio_cloud_utils.cloud_sync:main
3
+ run_tests = pytest:main
@@ -0,0 +1 @@
1
+ ugbio_cloud_utils