dcicutils 7.11.0.1b9__py3-none-any.whl → 7.12.0.1b4__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dcicutils might be problematic. Click here for more details.
- dcicutils/glacier_utils.py +16 -4
- dcicutils/license_utils.py +677 -165
- dcicutils/misc_utils.py +9 -97
- dcicutils/scripts/run_license_checker.py +77 -0
- {dcicutils-7.11.0.1b9.dist-info → dcicutils-7.12.0.1b4.dist-info}/METADATA +1 -3
- {dcicutils-7.11.0.1b9.dist-info → dcicutils-7.12.0.1b4.dist-info}/RECORD +9 -9
- {dcicutils-7.11.0.1b9.dist-info → dcicutils-7.12.0.1b4.dist-info}/entry_points.txt +1 -0
- dcicutils/sheet_utils.py +0 -1131
- {dcicutils-7.11.0.1b9.dist-info → dcicutils-7.12.0.1b4.dist-info}/LICENSE.txt +0 -0
- {dcicutils-7.11.0.1b9.dist-info → dcicutils-7.12.0.1b4.dist-info}/WHEEL +0 -0
dcicutils/misc_utils.py
CHANGED
@@ -7,11 +7,11 @@ import datetime
|
|
7
7
|
import functools
|
8
8
|
import hashlib
|
9
9
|
import inspect
|
10
|
-
import math
|
11
10
|
import io
|
12
11
|
import json
|
13
|
-
import os
|
14
12
|
import logging
|
13
|
+
import math
|
14
|
+
import os
|
15
15
|
import pytz
|
16
16
|
import re
|
17
17
|
import rfc3986.validators
|
@@ -21,8 +21,8 @@ import warnings
|
|
21
21
|
import webtest # importing the library makes it easier to mock testing
|
22
22
|
|
23
23
|
from collections import defaultdict
|
24
|
-
from dateutil.parser import parse as dateutil_parse
|
25
24
|
from datetime import datetime as datetime_type
|
25
|
+
from dateutil.parser import parse as dateutil_parse
|
26
26
|
from typing import Optional
|
27
27
|
|
28
28
|
|
@@ -192,11 +192,7 @@ class _VirtualAppHelper(webtest.TestApp):
|
|
192
192
|
pass
|
193
193
|
|
194
194
|
|
195
|
-
class
|
196
|
-
pass
|
197
|
-
|
198
|
-
|
199
|
-
class VirtualApp(AbstractVirtualApp):
|
195
|
+
class VirtualApp:
|
200
196
|
"""
|
201
197
|
Wrapper class for TestApp, to allow custom control over submitting Encoded requests,
|
202
198
|
simulating a number of conditions, including permissions.
|
@@ -1315,6 +1311,11 @@ def file_contents(filename, binary=False):
|
|
1315
1311
|
return fp.read()
|
1316
1312
|
|
1317
1313
|
|
1314
|
+
def json_file_contents(filename):
|
1315
|
+
with io.open(filename, 'r') as fp:
|
1316
|
+
return json.load(fp)
|
1317
|
+
|
1318
|
+
|
1318
1319
|
def camel_case_to_snake_case(s, separator='_'):
|
1319
1320
|
"""
|
1320
1321
|
Converts CamelCase to snake_case.
|
@@ -1357,25 +1358,6 @@ def capitalize1(s):
|
|
1357
1358
|
return s[:1].upper() + s[1:]
|
1358
1359
|
|
1359
1360
|
|
1360
|
-
"""
|
1361
|
-
Python's UUID ignores all dashes, whereas Postgres is more strict
|
1362
|
-
http://www.postgresql.org/docs/9.2/static/datatype-uuid.html
|
1363
|
-
See also http://www.postgresql.org/docs/9.2/static/datatype-uuid.html
|
1364
|
-
And, anyway, this pattern is what our portals have been doing
|
1365
|
-
for quite a while, so it's the most stable choice for us now.
|
1366
|
-
"""
|
1367
|
-
|
1368
|
-
uuid_re = re.compile(r'(?i)[{]?(?:[0-9a-f]{4}-?){8}[}]?')
|
1369
|
-
|
1370
|
-
|
1371
|
-
def is_uuid(instance):
|
1372
|
-
"""
|
1373
|
-
Predicate returns true for any group of 32 hex characters with optional hyphens every four characters.
|
1374
|
-
We insist on lowercase to make matching faster. See other notes on this design choice above.
|
1375
|
-
"""
|
1376
|
-
return bool(uuid_re.match(instance))
|
1377
|
-
|
1378
|
-
|
1379
1361
|
def string_list(s):
|
1380
1362
|
"""
|
1381
1363
|
Turns a comma-separated list into an actual list, trimming whitespace and ignoring nulls.
|
@@ -2337,73 +2319,3 @@ def parse_in_radix(text: str, *, radix: int):
|
|
2337
2319
|
except Exception:
|
2338
2320
|
pass
|
2339
2321
|
raise ValueError(f"Unable to parse: {text!r}")
|
2340
|
-
|
2341
|
-
|
2342
|
-
def pad_to(target_size: int, data: list, *, padding=None):
|
2343
|
-
"""
|
2344
|
-
This will pad to a given target size, a list of a potentially different actual size, using given padding.
|
2345
|
-
e.g., pad_to(3, [1, 2]) will return [1, 2, None]
|
2346
|
-
"""
|
2347
|
-
actual_size = len(data)
|
2348
|
-
if actual_size < target_size:
|
2349
|
-
data = data + [padding] * (target_size - actual_size)
|
2350
|
-
return data
|
2351
|
-
|
2352
|
-
|
2353
|
-
class JsonLinesReader:
|
2354
|
-
|
2355
|
-
def __init__(self, fp, padded=False, padding=None):
|
2356
|
-
"""
|
2357
|
-
Given an fp (the conventional name for a "file pointer", the thing a call to io.open returns,
|
2358
|
-
this creates an object that can be used to iterate across the lines in the JSON lines file
|
2359
|
-
that the fp is reading from.
|
2360
|
-
|
2361
|
-
There are two possible formats that this will return.
|
2362
|
-
|
2363
|
-
For files that contain a series of dictionaries, such as:
|
2364
|
-
{"something": 1, "else": "a"}
|
2365
|
-
{"something": 2, "else": "b"}
|
2366
|
-
...etc
|
2367
|
-
this will just return thos those dictionaries one-by-one when iterated over.
|
2368
|
-
|
2369
|
-
The same set of dictionaries will also be yielded by a file containing:
|
2370
|
-
["something", "else"]
|
2371
|
-
[1, "a"]
|
2372
|
-
[2, "b"]
|
2373
|
-
...etc
|
2374
|
-
this will just return thos those dictionaries one-by-one when iterated over.
|
2375
|
-
|
2376
|
-
NOTES:
|
2377
|
-
|
2378
|
-
* In the second case, shorter lists on subsequent lines return only partial dictionaries.
|
2379
|
-
* In the second case, longer lists on subsequent lines will quietly drop any extra elements.
|
2380
|
-
"""
|
2381
|
-
|
2382
|
-
self.fp = fp
|
2383
|
-
self.padded: bool = padded
|
2384
|
-
self.padding = padding
|
2385
|
-
self.headers = None # Might change after we see first line
|
2386
|
-
|
2387
|
-
def __iter__(self):
|
2388
|
-
first_line = True
|
2389
|
-
n_headers = 0
|
2390
|
-
for raw_line in self.fp:
|
2391
|
-
line = json.loads(raw_line)
|
2392
|
-
if first_line:
|
2393
|
-
first_line = False
|
2394
|
-
if isinstance(line, list):
|
2395
|
-
self.headers = line
|
2396
|
-
n_headers = len(line)
|
2397
|
-
continue
|
2398
|
-
# If length of line is more than we expect, ignore it. Let user put comments beyond our table
|
2399
|
-
# But if length of line is less than we expect, extend the line with None
|
2400
|
-
if self.headers:
|
2401
|
-
if not isinstance(line, list):
|
2402
|
-
raise Exception("If the first line is a list, all lines must be.")
|
2403
|
-
if self.padded and len(line) < n_headers:
|
2404
|
-
line = pad_to(n_headers, line, padding=self.padding)
|
2405
|
-
yield dict(zip(self.headers, line))
|
2406
|
-
elif isinstance(line, dict):
|
2407
|
-
yield line
|
2408
|
-
else:
|
2409
|
-
raise Exception(f"If the first line is not a list, all lines must be dictionaries: {line!r}")
|
@@ -0,0 +1,77 @@
|
|
1
|
+
import argparse
|
2
|
+
|
3
|
+
from dcicutils.command_utils import script_catch_errors, ScriptFailure
|
4
|
+
from dcicutils.lang_utils import there_are, conjoined_list
|
5
|
+
from dcicutils.license_utils import LicenseOptions, LicenseCheckerRegistry, LicenseChecker, LicenseCheckFailure
|
6
|
+
from dcicutils.misc_utils import PRINT, get_error_message
|
7
|
+
from typing import Optional, Type
|
8
|
+
|
9
|
+
|
10
|
+
EPILOG = __doc__
|
11
|
+
|
12
|
+
|
13
|
+
ALL_CHECKER_NAMES = LicenseCheckerRegistry.all_checker_names()
|
14
|
+
NEWLINE = '\n'
|
15
|
+
|
16
|
+
|
17
|
+
def main():
|
18
|
+
|
19
|
+
parser = argparse.ArgumentParser(
|
20
|
+
description="Runs a license checker",
|
21
|
+
epilog=EPILOG,
|
22
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
23
|
+
)
|
24
|
+
parser.add_argument("name", type=str, default=None, nargs='?',
|
25
|
+
help=f"The name of a checker to run. "
|
26
|
+
+ there_are(ALL_CHECKER_NAMES, kind='available checker',
|
27
|
+
show=True, joiner=conjoined_list, punctuate=True))
|
28
|
+
parser.add_argument("--brief", '-b', default=False, action="store_true",
|
29
|
+
help="Requests brief output.")
|
30
|
+
parser.add_argument("--debug", '-q', default=False, action="store_true",
|
31
|
+
help="Requests additional debugging output.")
|
32
|
+
parser.add_argument("--conda-prefix", "--conda_prefix", "--cp", default=LicenseOptions.CONDA_PREFIX,
|
33
|
+
help=(f"Overrides the CONDA_PREFIX (default {LicenseOptions.CONDA_PREFIX!r})."))
|
34
|
+
|
35
|
+
args = parser.parse_args()
|
36
|
+
|
37
|
+
with script_catch_errors():
|
38
|
+
run_license_checker(name=args.name, verbose=not args.brief, debug=args.debug, conda_prefix=args.conda_prefix)
|
39
|
+
|
40
|
+
|
41
|
+
def show_help_for_choosing_license_checker():
|
42
|
+
PRINT("")
|
43
|
+
PRINT(there_are(ALL_CHECKER_NAMES, kind='available checker', show=False, punctuation_mark=':'))
|
44
|
+
PRINT("")
|
45
|
+
wid = max(len(x) for x in ALL_CHECKER_NAMES) + 1
|
46
|
+
for checker_name in ALL_CHECKER_NAMES:
|
47
|
+
checker_class = LicenseCheckerRegistry.lookup_checker(checker_name)
|
48
|
+
checker_doc = (checker_class.__doc__ or '<missing doc>').strip(' \t\n\r')
|
49
|
+
PRINT(f"{(checker_name + ':').ljust(wid)} {checker_doc.split(NEWLINE)[0]}")
|
50
|
+
PRINT("")
|
51
|
+
PRINT("=" * 42, "NOTES & DISCLAIMERS", "=" * 42)
|
52
|
+
PRINT("Park Lab is a research laboratory in the Department of Biomedical Informatics at Harvard Medical School.")
|
53
|
+
PRINT("Park Lab checkers are intended for internal use and may not be suitable for other purposes.")
|
54
|
+
PRINT("External organizations must make their own independent choices about license acceptability.")
|
55
|
+
PRINT("Such choices can be integrated with this tool as follows:")
|
56
|
+
PRINT(" * Import LicenseChecker and LicenseCheckerRegistry from dcicutils.license_utils.")
|
57
|
+
PRINT(" * Make your own subclass of LicenseChecker, specifying a doc string and appropriate constraints.")
|
58
|
+
PRINT(" * Decorate your subclass with an appropriate call to LicenseCheckerRegistry.register_checker.")
|
59
|
+
PRINT("")
|
60
|
+
|
61
|
+
|
62
|
+
def run_license_checker(name: Optional[str],
|
63
|
+
verbose=LicenseOptions.VERBOSE,
|
64
|
+
debug=LicenseOptions.DEBUG,
|
65
|
+
conda_prefix=LicenseOptions.CONDA_PREFIX):
|
66
|
+
if name is None:
|
67
|
+
show_help_for_choosing_license_checker()
|
68
|
+
else:
|
69
|
+
try:
|
70
|
+
checker_class: Type[LicenseChecker] = LicenseCheckerRegistry.lookup_checker(name)
|
71
|
+
except Exception as e:
|
72
|
+
raise ScriptFailure(str(e))
|
73
|
+
try:
|
74
|
+
with LicenseOptions.selected_options(verbose=verbose, debug=debug, conda_prefix=conda_prefix):
|
75
|
+
checker_class.validate()
|
76
|
+
except LicenseCheckFailure as e:
|
77
|
+
raise ScriptFailure(get_error_message(e))
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: dcicutils
|
3
|
-
Version: 7.
|
3
|
+
Version: 7.12.0.1b4
|
4
4
|
Summary: Utility package for interacting with the 4DN Data Portal and other 4DN resources
|
5
5
|
Home-page: https://github.com/4dn-dcic/utils
|
6
6
|
License: MIT
|
@@ -25,11 +25,9 @@ Requires-Dist: PyYAML (>=5.1,<5.5)
|
|
25
25
|
Requires-Dist: aws-requests-auth (>=0.4.2,<1)
|
26
26
|
Requires-Dist: boto3 (>=1.17.39,<2.0.0)
|
27
27
|
Requires-Dist: botocore (>=1.20.39,<2.0.0)
|
28
|
-
Requires-Dist: chardet (>=5.2.0,<6.0.0)
|
29
28
|
Requires-Dist: docker (>=4.4.4,<5.0.0)
|
30
29
|
Requires-Dist: elasticsearch (==7.13.4)
|
31
30
|
Requires-Dist: gitpython (>=3.1.2,<4.0.0)
|
32
|
-
Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
|
33
31
|
Requires-Dist: opensearch-py (>=2.0.1,<3.0.0)
|
34
32
|
Requires-Dist: pyOpenSSL (>=23.1.1,<24.0.0)
|
35
33
|
Requires-Dist: pytz (>=2020.4)
|
@@ -25,14 +25,14 @@ dcicutils/exceptions.py,sha256=4giQGtpak-omQv7BP6Ckeu91XK5fnDosC8gfdmN_ccA,9931
|
|
25
25
|
dcicutils/ff_mocks.py,sha256=6RKS4eUiu_Wl8yP_8V0CaV75w4ZdWxdCuL1CVlnMrek,36918
|
26
26
|
dcicutils/ff_utils.py,sha256=3-0AD1FVKmpI7qleMoIqBLPubBAgH5qBmQGVo6-gWnk,72419
|
27
27
|
dcicutils/function_cache_decorator.py,sha256=XMyiEGODVr2WoAQ68vcoX_9_Xb9p8pZXdXl7keU8i2g,10026
|
28
|
-
dcicutils/glacier_utils.py,sha256=
|
28
|
+
dcicutils/glacier_utils.py,sha256=Q4CVXsZCbP-SoZIsZ5NMcawDfelOLzbQnIlQn-GdlTo,34149
|
29
29
|
dcicutils/jh_utils.py,sha256=Gpsxb9XEzggF_-Eq3ukjKvTnuyb9V1SCSUXkXsES4Kg,11502
|
30
30
|
dcicutils/kibana/dashboards.json,sha256=wHMB_mpJ8OaYhRRgvpZuihaB2lmSF64ADt_8hkBWgQg,16225
|
31
31
|
dcicutils/kibana/readme.md,sha256=3KmHF9FH6A6xwYsNxRFLw27q0XzHYnjZOlYUnn3VkQQ,2164
|
32
32
|
dcicutils/lang_utils.py,sha256=cVLRUGyYeSPJAq3z_RJjA6miajHrXoi6baxF8HzHmLc,27797
|
33
|
-
dcicutils/license_utils.py,sha256=
|
33
|
+
dcicutils/license_utils.py,sha256=AJ7AwUb7YsXwrrncuS5bLwz3B0YYOHAqKwgf1JPLj6w,63798
|
34
34
|
dcicutils/log_utils.py,sha256=7pWMc6vyrorUZQf-V-M3YC6zrPgNhuV_fzm9xqTPph0,10883
|
35
|
-
dcicutils/misc_utils.py,sha256=
|
35
|
+
dcicutils/misc_utils.py,sha256=d30xwLFW41FwZVDAEYulWwyZUcLEzmD-pxsMlKH3mF4,91148
|
36
36
|
dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmjw,5963
|
37
37
|
dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
|
38
38
|
dcicutils/project_utils.py,sha256=qPdCaFmWUVBJw4rw342iUytwdQC0P-XKpK4mhyIulMM,31250
|
@@ -42,15 +42,15 @@ dcicutils/redis_tools.py,sha256=rqGtnVUjNjTlCdL1EMKuEhEMAgRJMiXZJkrKuX255QA,6509
|
|
42
42
|
dcicutils/redis_utils.py,sha256=VJ-7g8pOZqR1ZCtdcjKz3-6as2DMUcs1b1zG6wSprH4,6462
|
43
43
|
dcicutils/s3_utils.py,sha256=a9eU3Flh8Asc8xPWLGP16A6UQ_FVwhoFQNqm4ZYgSQ4,28852
|
44
44
|
dcicutils/scripts/publish_to_pypi.py,sha256=qmWyjrg5bNQNfpNKFTZdyMXpRmrECnRV9VmNQddUPQA,13576
|
45
|
+
dcicutils/scripts/run_license_checker.py,sha256=psv3c1Of7h4V4yvh93iyI2F3JFPzdzQakKdq97JThRw,3653
|
45
46
|
dcicutils/secrets_utils.py,sha256=8dppXAsiHhJzI6NmOcvJV5ldvKkQZzh3Fl-cb8Wm7MI,19745
|
46
|
-
dcicutils/sheet_utils.py,sha256=bnnefjeTUL4ES7gtqThISXJKeli1AIFryu4h7Dt9dxw,47040
|
47
47
|
dcicutils/snapshot_utils.py,sha256=ymP7PXH6-yEiXAt75w0ldQFciGNqWBClNxC5gfX2FnY,22961
|
48
48
|
dcicutils/ssl_certificate_utils.py,sha256=F0ifz_wnRRN9dfrfsz7aCp4UDLgHEY8LaK7PjnNvrAQ,9707
|
49
49
|
dcicutils/task_utils.py,sha256=MF8ujmTD6-O2AC2gRGPHyGdUrVKgtr8epT5XU8WtNjk,8082
|
50
50
|
dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
|
51
51
|
dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
|
52
|
-
dcicutils-7.
|
53
|
-
dcicutils-7.
|
54
|
-
dcicutils-7.
|
55
|
-
dcicutils-7.
|
56
|
-
dcicutils-7.
|
52
|
+
dcicutils-7.12.0.1b4.dist-info/LICENSE.txt,sha256=t0_-jIjqxNnymZoNJe-OltRIuuF8qfhN0ATlHyrUJPk,1102
|
53
|
+
dcicutils-7.12.0.1b4.dist-info/METADATA,sha256=WBf2fEjWMlOtieSs4nq5zbiThbHAYzQliH7gmJ_0L04,3003
|
54
|
+
dcicutils-7.12.0.1b4.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
55
|
+
dcicutils-7.12.0.1b4.dist-info/entry_points.txt,sha256=8wbw5csMIgBXhkwfgsgJeuFcoUc0WsucUxmOyml2aoA,209
|
56
|
+
dcicutils-7.12.0.1b4.dist-info/RECORD,,
|