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/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 AbstractVirtualApp:
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.11.0.1b9
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=x4zRGeSBS9c3LeurjR2gvEr_ipDTVpULvRFsIMfOVrs,33704
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=OhOfTXFivvb6Y3tiJAb1b9Is-OTpBfZjC18M-RvqBqk,40456
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=XisEQGMkHI7k5RiK-k4yeG8Zw00H8b-v9o2Y7mZyKb8,94548
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.11.0.1b9.dist-info/LICENSE.txt,sha256=t0_-jIjqxNnymZoNJe-OltRIuuF8qfhN0ATlHyrUJPk,1102
53
- dcicutils-7.11.0.1b9.dist-info/METADATA,sha256=MER7N-gDAB5nz6YT51jT7aIu8_rHT2x65FBF5x3DN70,3084
54
- dcicutils-7.11.0.1b9.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
55
- dcicutils-7.11.0.1b9.dist-info/entry_points.txt,sha256=Z3vezbXsTpTIY4N2F33c5e-WDVQxgz_Vsk1oV_JBN7A,146
56
- dcicutils-7.11.0.1b9.dist-info/RECORD,,
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,,
@@ -1,4 +1,5 @@
1
1
  [console_scripts]
2
2
  publish-to-pypi=dcicutils.scripts.publish_to_pypi:main
3
+ run-license-checker=dcicutils.scripts.run_license_checker:main
3
4
  show-contributors=dcicutils.contribution_scripts:show_contributors_main
4
5