rda-python-common 3.0.25__tar.gz → 3.0.26__tar.gz
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.
- {rda_python_common-3.0.25/src/rda_python_common.egg-info → rda_python_common-3.0.26}/PKG-INFO +2 -2
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/README.md +1 -1
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/pyproject.toml +1 -1
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/__init__.py +1 -1
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_file.py +45 -13
- {rda_python_common-3.0.25 → rda_python_common-3.0.26/src/rda_python_common.egg-info}/PKG-INFO +2 -2
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/LICENSE +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/setup.cfg +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgCMD.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgDBI.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgFile.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgLOG.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgLock.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgOPT.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgSIG.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgSplit.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/PgUtil.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_cmd.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_dbi.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_lock.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_log.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_opt.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_password.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_sig.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_split.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pg_util.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pgpassword.py +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common/pgpassword.usg +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/SOURCES.txt +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/dependency_links.txt +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/entry_points.txt +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/requires.txt +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/top_level.txt +0 -0
- {rda_python_common-3.0.25 → rda_python_common-3.0.26}/test/test_common.py +0 -0
{rda_python_common-3.0.25/src/rda_python_common.egg-info → rda_python_common-3.0.26}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_common
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.26
|
|
4
4
|
Summary: RDA Python common library codes shared by other RDA python packages
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-common
|
|
@@ -189,7 +189,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
|
|
|
189
189
|
python -c "import rda_python_common; print(rda_python_common.__version__)"
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
You should see the installed version (currently `3.0.
|
|
192
|
+
You should see the installed version (currently `3.0.26`). If the import
|
|
193
193
|
fails, double-check that the active Python environment is the one where you
|
|
194
194
|
ran `pip install`.
|
|
195
195
|
|
|
@@ -165,7 +165,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
|
|
|
165
165
|
python -c "import rda_python_common; print(rda_python_common.__version__)"
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
You should see the installed version (currently `3.0.
|
|
168
|
+
You should see the installed version (currently `3.0.26`). If the import
|
|
169
169
|
fails, double-check that the active Python environment is the one where you
|
|
170
170
|
ran `pip install`.
|
|
171
171
|
|
|
@@ -794,7 +794,7 @@ class PgFile(PgUtil, PgSIG):
|
|
|
794
794
|
# tofile - target file name
|
|
795
795
|
# fromfile - source file name
|
|
796
796
|
# bucket - bucket name on Object store
|
|
797
|
-
def object_copy_local(self, tofile, fromfile, bucket = None, logact = 0):
|
|
797
|
+
def object_copy_local(self, tofile, fromfile, bucket = None, logact = 0, finfo = None):
|
|
798
798
|
"""Download a file from the object store to the local filesystem.
|
|
799
799
|
|
|
800
800
|
Changes to the target directory, downloads using isd_s3_cli, verifies size,
|
|
@@ -807,31 +807,42 @@ class PgFile(PgUtil, PgSIG):
|
|
|
807
807
|
fromfile (str): Object key (source path in the bucket).
|
|
808
808
|
bucket (str | None): Source bucket; defaults to PGLOG['OBJCTBKT'].
|
|
809
809
|
logact (int): Logging action flags; default 0.
|
|
810
|
+
finfo (dict | None): check_object_file() info for fromfile, from a call
|
|
811
|
+
with opt bit 1, when the caller already has it;
|
|
812
|
+
saves listing the object a second time.
|
|
810
813
|
|
|
811
814
|
Returns:
|
|
812
815
|
int: self.SUCCESS on success, self.FAILURE on error.
|
|
813
816
|
"""
|
|
814
817
|
ret = self.FAILURE
|
|
815
818
|
if not bucket: bucket = self.PGLOG['OBJCTBKT']
|
|
816
|
-
|
|
819
|
+
# opt 1 adds the LastModified the 'lo' listing already carries, which
|
|
820
|
+
# object_get_local needs to tell whether tofile is staged already
|
|
821
|
+
if not finfo: finfo = self.check_object_file(fromfile, bucket, 1, logact)
|
|
817
822
|
if not finfo:
|
|
818
823
|
if finfo != None: return ret
|
|
819
824
|
return self.lmsg(fromfile, "{}-{} to copy to {}".format(self.OHOST, self.PGLOG['MISSFILE'], tofile), logact)
|
|
820
|
-
if not finfo['isfile']:
|
|
821
|
-
|
|
825
|
+
if not finfo['isfile']:
|
|
826
|
+
return self.object_copy_local_directory(tofile, fromfile, bucket, logact, finfo.get('flist'))
|
|
827
|
+
return self.object_get_local(tofile, fromfile, finfo, bucket, logact)
|
|
822
828
|
|
|
823
829
|
# Download a single object of a known size to a local file
|
|
824
830
|
# tofile - target file name
|
|
825
831
|
# fromfile - source object key name
|
|
826
|
-
#
|
|
832
|
+
# finfo - check_object_file() info of the object, to verify the download against
|
|
827
833
|
# bucket - bucket name on Object store
|
|
828
|
-
def object_get_local(self, tofile, fromfile,
|
|
834
|
+
def object_get_local(self, tofile, fromfile, finfo, bucket, logact = 0):
|
|
829
835
|
"""Download one object key to a local file and verify its size.
|
|
830
836
|
|
|
837
|
+
Nothing is fetched when tofile is already staged at the object's size and
|
|
838
|
+
no older than the object itself, unless logact carries OVRIDE, so the
|
|
839
|
+
second copy into the same file (dsarch makes one when it tars) is free.
|
|
840
|
+
|
|
831
841
|
Args:
|
|
832
842
|
tofile (str): Destination local file path.
|
|
833
843
|
fromfile (str): Object key (source path in the bucket).
|
|
834
|
-
|
|
844
|
+
finfo (dict): check_object_file() info of the object; 'data_size' is
|
|
845
|
+
required, 'date_modified'/'time_modified' enable the skip.
|
|
835
846
|
bucket (str): Source bucket.
|
|
836
847
|
logact (int): Logging action flags; default 0.
|
|
837
848
|
|
|
@@ -839,6 +850,13 @@ class PgFile(PgUtil, PgSIG):
|
|
|
839
850
|
int: self.SUCCESS on success, self.FAILURE on error.
|
|
840
851
|
"""
|
|
841
852
|
ret = self.FAILURE
|
|
853
|
+
fsize = finfo['data_size']
|
|
854
|
+
if not logact&self.OVRIDE and 'date_modified' in finfo:
|
|
855
|
+
linfo = self.check_local_file(tofile, 1, logact)
|
|
856
|
+
if linfo and linfo['isfile'] and linfo['data_size'] == fsize and \
|
|
857
|
+
self.cmptime(linfo['date_modified'], linfo['time_modified'],
|
|
858
|
+
finfo['date_modified'], finfo['time_modified']) >= 0:
|
|
859
|
+
return self.SUCCESS
|
|
842
860
|
ocmd = self.OBJCTCMD
|
|
843
861
|
cmd = "{} go -k {} -b {}".format(ocmd, fromfile, bucket)
|
|
844
862
|
fromname = op.basename(fromfile)
|
|
@@ -871,7 +889,8 @@ class PgFile(PgUtil, PgSIG):
|
|
|
871
889
|
# todir - target local directory name
|
|
872
890
|
# fromdir - source object key prefix
|
|
873
891
|
# bucket - bucket name on Object store
|
|
874
|
-
|
|
892
|
+
# flist - member listing from check_object_file(), if the caller has it
|
|
893
|
+
def object_copy_local_directory(self, todir, fromdir, bucket = None, logact = 0, flist = None):
|
|
875
894
|
"""Download every object under a key prefix into a local directory.
|
|
876
895
|
|
|
877
896
|
The object store has no directories; a zarr store and the like is a set of
|
|
@@ -889,6 +908,9 @@ class PgFile(PgUtil, PgSIG):
|
|
|
889
908
|
fromdir (str): Object key prefix (source path in the bucket).
|
|
890
909
|
bucket (str | None): Source bucket; defaults to PGLOG['OBJCTBKT'].
|
|
891
910
|
logact (int): Logging action flags; default 0.
|
|
911
|
+
flist (dict | None): Mapping of key → object info with LastModified, as
|
|
912
|
+
check_object_file() keeps it for a key prefix;
|
|
913
|
+
listed here when not given.
|
|
892
914
|
|
|
893
915
|
Returns:
|
|
894
916
|
int: self.SUCCESS on success, self.FAILURE on error.
|
|
@@ -896,10 +918,11 @@ class PgFile(PgUtil, PgSIG):
|
|
|
896
918
|
if not bucket: bucket = self.PGLOG['OBJCTBKT']
|
|
897
919
|
ms = re.match(r'^(.+)/$', fromdir)
|
|
898
920
|
if ms: fromdir = ms.group(1)
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
921
|
+
if flist is None:
|
|
922
|
+
# opt 1 adds the LastModified the 'lo' listing already carries; it is only
|
|
923
|
+
# bits 2 and 8 that would cost a metadata call per key
|
|
924
|
+
flist = self.object_glob(fromdir, bucket, 1, logact)
|
|
925
|
+
if flist == self.FAILURE: return self.FAILURE
|
|
903
926
|
prefix = fromdir + '/'
|
|
904
927
|
keys = [key for key in flist if key.startswith(prefix)]
|
|
905
928
|
if not keys:
|
|
@@ -2452,6 +2475,8 @@ class PgFile(PgUtil, PgSIG):
|
|
|
2452
2475
|
|
|
2453
2476
|
Strips trailing '/'. Uses opt bit 64 to skip the retry. Fetches metadata
|
|
2454
2477
|
(uhash) when opt includes bits 2, 4, or 8. Resets ECNTS['O'] on success.
|
|
2478
|
+
Only the key itself, or the keys under it as a directory, count as a
|
|
2479
|
+
match; other keys that merely start with the same characters are ignored.
|
|
2455
2480
|
|
|
2456
2481
|
Args:
|
|
2457
2482
|
file (str): Object key to check.
|
|
@@ -2477,7 +2502,11 @@ class PgFile(PgUtil, PgSIG):
|
|
|
2477
2502
|
if buf:
|
|
2478
2503
|
if re.match(r'^\[\]', buf): break
|
|
2479
2504
|
if re.match(r'^\[\{', buf):
|
|
2480
|
-
|
|
2505
|
+
# 'lo' matches by key prefix, so x.zarr also lists a sibling x.zarr2/...
|
|
2506
|
+
# and a.nc lists a.nc.bak; keep only the key itself and keys under it
|
|
2507
|
+
prefix = file + '/'
|
|
2508
|
+
ary = [a for a in json.loads(buf) if a['Key'] == file or a['Key'].startswith(prefix)]
|
|
2509
|
+
if not ary: break
|
|
2481
2510
|
cnt = len(ary)
|
|
2482
2511
|
isdir = (cnt > 1 or ary[0]['Key'] != file)
|
|
2483
2512
|
# a key prefix has no timestamp of its own; report the newest member's
|
|
@@ -2495,6 +2524,9 @@ class PgFile(PgUtil, PgSIG):
|
|
|
2495
2524
|
for a in ary:
|
|
2496
2525
|
size += int(a['Size'])
|
|
2497
2526
|
ret['data_size'] = size
|
|
2527
|
+
# keep the member listing, as object_glob(file, bucket, 1) builds it,
|
|
2528
|
+
# so a download of the prefix does not list it a second time
|
|
2529
|
+
ret['flist'] = {a['Key']: self.object_file_stat(a, None, 1) for a in ary}
|
|
2498
2530
|
uhash = None
|
|
2499
2531
|
break
|
|
2500
2532
|
if opt&64: return self.FAILURE
|
{rda_python_common-3.0.25 → rda_python_common-3.0.26/src/rda_python_common.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rda_python_common
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.26
|
|
4
4
|
Summary: RDA Python common library codes shared by other RDA python packages
|
|
5
5
|
Author-email: Zaihua Ji <zji@ucar.edu>
|
|
6
6
|
Project-URL: Homepage, https://github.com/NCAR/rda-python-common
|
|
@@ -189,7 +189,7 @@ PgLOG.pglog("hello", PgLOG.LOGWRN)
|
|
|
189
189
|
python -c "import rda_python_common; print(rda_python_common.__version__)"
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
-
You should see the installed version (currently `3.0.
|
|
192
|
+
You should see the installed version (currently `3.0.26`). If the import
|
|
193
193
|
fails, double-check that the active Python environment is the one where you
|
|
194
194
|
ran `pip install`.
|
|
195
195
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/requires.txt
RENAMED
|
File without changes
|
{rda_python_common-3.0.25 → rda_python_common-3.0.26}/src/rda_python_common.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|