Skip to content

Commit 0326167

Browse files
ekka0002wagn0033
andauthored
Wagn0033 (#1)
* added unittests for misc and get image * Add "post" method for RestApiV1 library * added init with get image and get countries * Added hashbang line to script * Added "post" to RestApiV1 * added more GET unit tests * Adding capability to get images _get_binary added to RestApiV1 * more unit tests under get_tests * Updated RestApiV1 "post" * change line endings to unix-style * Update .gitignore updated .gitignore to not include .swp, .pyc * more unit tests/edits * Change default REST API url * Converted RestApiV1 unit tests to use new functions instead of _get * Preparing for release 1.1 Release 1.1 allows using External ID and allows attaching subcomponents * Fixed bug with institution list --------- Co-authored-by: wagn0033 <[email protected]>
1 parent a315885 commit 0326167

File tree

134 files changed

+24338
-879
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+24338
-879
lines changed

.DS_Store

6 KB
Binary file not shown.

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
lib/Sisyphus/__pycache__/__init__.cpython-39.pyc
3+
*.pyc
4+
Examples/upload-docket/Tutorial/Example01/.~lock.HWItems.xlsx\#
5+
*.pyc
6+
*.pyc
7+
*.swp
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[codestyle]
2+
indentation = True
3+
edge_line = True
4+
edge_line_columns = 79
5+
6+
[main]
7+
version = 0.2.0
8+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[encoding]
2+
text_encoding = utf-8
3+
4+
[main]
5+
version = 0.2.0
6+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[vcs]
2+
use_version_control = False
3+
version_control_system =
4+
5+
[main]
6+
version = 0.2.0
7+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[workspace]
2+
restore_data_on_startup = True
3+
save_data_on_exit = True
4+
save_history = True
5+
save_non_project_files = False
6+
project_type = 'empty-project-type'
7+
recent_files = ['lib/Sisyphus/RestApiV1/__init__.py', 'test/RestApiV1/Test__get_misc.py']
8+
9+
[main]
10+
version = 0.2.0
11+
recent_files = []
12+

.spyproject/config/codestyle.ini

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[codestyle]
2+
indentation = True
3+
edge_line = True
4+
edge_line_columns = 79
5+
6+
[main]
7+
version = 0.2.0
8+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[codestyle]
2+
indentation = True
3+
edge_line = True
4+
edge_line_columns = 79
5+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[encoding]
2+
text_encoding = utf-8
3+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[vcs]
2+
use_version_control = False
3+
version_control_system =
4+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[workspace]
2+
restore_data_on_startup = True
3+
save_data_on_exit = True
4+
save_history = True
5+
save_non_project_files = False
6+

.spyproject/config/encoding.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[encoding]
2+
text_encoding = utf-8
3+
4+
[main]
5+
version = 0.2.0
6+

.spyproject/config/vcs.ini

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[vcs]
2+
use_version_control = False
3+
version_control_system =
4+
5+
[main]
6+
version = 0.2.0
7+

.spyproject/config/workspace.ini

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[workspace]
2+
restore_data_on_startup = True
3+
save_data_on_exit = True
4+
save_history = True
5+
save_non_project_files = False
6+
project_type = 'empty-project-type'
7+
recent_files = ['lib/Sisyphus/RestApiV1/__init__.py', 'test/RestApiV1/Test__get_misc.py', 'lib/Sisyphus/RestApi/__init__.py', 'scratch/scratch-01.py']
8+
9+
[main]
10+
version = 0.2.0
11+
recent_files = []
12+

bin/advanced-upload-docket.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""
4+
bin/advanced-upload-docket.py
5+
Copyright (c) 2023 Regents of the University of Minnesota
6+
Author: Alex Wagner <[email protected]>, Dept. of Physics and Astronomy
7+
"""
8+
9+
import sys
10+
import argparse
11+
import json, json5
12+
from Sisyphus.HWDBUploader import Docket
13+
14+
def parse_args(argv):
15+
16+
description = "TBD"
17+
18+
arg_table = [
19+
(('docket',), {"metavar": "filename", "nargs": 1}),
20+
#(('--docket',), {"dest": "docket", "required": True, "metavar": "filename"}),
21+
(('--submit',), {"dest": "submit", "action": "store_true"}),
22+
#(('--ignore-warnings',), {"dest": "ignore", "action": "store_true"}),
23+
]
24+
25+
parser = argparse.ArgumentParser(description=description, add_help=True)
26+
27+
for args, kwargs in arg_table:
28+
parser.add_argument(*args, **kwargs)
29+
30+
# THIS IS BROKEN... I want to pass argv to it, but it just doesn't behave the same.
31+
# but I don't need to fix this right now.
32+
args = parser.parse_args()
33+
return args
34+
35+
36+
def main(argv):
37+
args = parse_args(argv)
38+
39+
docket_file = args.docket[0]
40+
ext = docket_file.split('.')[-1]
41+
42+
try:
43+
with open(docket_file, "r") as f:
44+
contents = f.read()
45+
except Exception as ex:
46+
print(f"Exception: {type(ex)} {ex}")
47+
raise ex
48+
49+
if ext.lower() in ["json", "json5"]:
50+
docket_def = json5.loads(contents)
51+
elif ext.lower() in ["py",]:
52+
_locals = {}
53+
exec(contents, globals(), _locals)
54+
docket_def = _locals["contents"]
55+
56+
docket = Docket(docket_def)
57+
58+
docket.process_sources()
59+
if args.submit:
60+
docket.update_hwdb()
61+
else:
62+
docket.display_plan()
63+
64+
65+
if __name__ == '__main__':
66+
sys.exit(main(sys.argv))

bin/configure.py

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,53 @@
1010
import argparse
1111
import Sisyphus.Configuration as Config
1212

13-
14-
1513
def parse(command_line_args=sys.argv):
1614
parser = argparse.ArgumentParser(
15+
add_help=True,
16+
parents=[Config.config.arg_parser],
1717
description='Saves authentication info in ~/.sisyphus/config.json')
18-
parser.add_argument('--reset',
18+
19+
group = parser.add_argument_group(
20+
'Configuration Utility Options',
21+
'All configuration options above will be permanent, and the '
22+
'following additional options are available.')
23+
24+
group.add_argument('--reset',
1925
dest='reset',
2026
action='store_true',
2127
required=False,
2228
help='resets everything in the configuration '
2329
'(i.e., reset the configuration, then add everything '
2430
'else provided in this command line')
25-
parser.add_argument('--set-active',
31+
group.add_argument('--set-active',
2632
dest='set_active',
2733
action='store_true',
2834
required=False,
2935
help='set this profile to be the default')
3036
args = parser.parse_known_args(command_line_args)
3137
return args
32-
33-
38+
39+
def check_server(config):
40+
# we wait until here to import because we want to process arguments and
41+
# update the configuration before accessing the HWDB.
42+
from Sisyphus.RestApiV1 import session, whoami
43+
44+
# if the config is invalid or incomplete, "session" will be None
45+
if session is None:
46+
msg = "Server check not attempted"
47+
config.logger.info(msg)
48+
else:
49+
resp = whoami(timeout=10)
50+
if resp['status'] != "OK":
51+
msg = "Failed to contact server to validate certificate"
52+
config.logger.warning(msg)
53+
else:
54+
user = f"{(resp['data']['full_name'])} ({resp['data']['username']})"
55+
msg = f"REST API 'whoami' returned {user}"
56+
config.logger.info(msg)
57+
return msg
58+
59+
3460
def show_summary(config):
3561
print()
3662
print("Configuration Summary:")
@@ -41,22 +67,39 @@ def show_summary(config):
4167
else:
4268
default_info_msg = f"(default is {config.default_profile})"
4369

44-
print(f"profile: {config.profile_name} {default_info_msg}")
45-
print(f"REST API: {config.rest_api}")
70+
print(f"profile: {config.profile_name} {default_info_msg}")
71+
72+
if config.rest_api == Config.API_DEV:
73+
rest_api_msg = "(development)"
74+
elif config.rest_api == Config.API_PROD:
75+
rest_api_msg = "(PRODUCTION)"
76+
else:
77+
rest_api_msg = "(custom)"
78+
79+
print(f"REST API: {config.rest_api} {rest_api_msg}")
4680

4781
if config.cert_type is None:
48-
print( "certificate: None, all commands will require '--cert <certificate>' to function")
82+
print( "certificate: None, all commands will require '--cert <certificate>' to function")
4983
elif config.cert_type == Config.KW_P12:
50-
print(f"certificate: {Config.KW_P12}, all commands will require '--password <password> to function")
84+
print(f"certificate: {Config.KW_P12}, all commands will require '--password <password> to function")
5185
else:
52-
print(f"certificate: {Config.KW_PEM}")
86+
print(f"certificate: {Config.KW_PEM}")
5387

5488
if config.cert_type == Config.KW_PEM:
55-
print(f"cert info: {config.cert_fullname} ({config.cert_username})")
89+
print(f"cert info: {config.cert_fullname} ({config.cert_username})")
5690
if config.cert_has_expired:
57-
print("cert status: Expired")
91+
print("cert status: Expired")
5892
else:
59-
print(f"cert status: Expires in {config.cert_days_left} days")
93+
print(f"cert status: Expires in {config.cert_days_left} days")
94+
95+
#print(f"server check: {check_server(config)}")
96+
sys.stdout.write("server check: (please wait)")
97+
sys.stdout.flush()
98+
check_result = check_server(config)
99+
sys.stdout.write(f"\rserver check: {check_result}\033[K\n")
100+
101+
102+
print()
60103

61104
def main():
62105

bin/list-institutions.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""
4+
bin/list-institutions.py
5+
Copyright (c) 2023 Regents of the University of Minnesota
6+
Author: Alex Wagner <[email protected]>, Dept. of Physics and Astronomy
7+
"""
8+
9+
from Sisyphus.Configuration import config
10+
logger = config.getLogger()
11+
12+
from Sisyphus.RestApiV1 import get_institutions
13+
from Sisyphus.Utils.Terminal import Style
14+
import sys
15+
import json
16+
import argparse
17+
18+
def parse(command_line_args=sys.argv):
19+
parser = argparse.ArgumentParser(
20+
add_help=True,
21+
parents=[config.arg_parser],
22+
description='Displays a list of available institution codes')
23+
parser.add_argument('--country',
24+
dest='country',
25+
metavar='<country code or name>',
26+
required=False,
27+
help='display only countries matching (or partially matching) string')
28+
parser.add_argument('--inst-name', '--institution-name',
29+
dest='name',
30+
metavar='<institution name>',
31+
required=False,
32+
help='display only institutions matching (or partially matching) string')
33+
parser.add_argument('--inst-id',
34+
dest='id',
35+
metavar='<institution id>',
36+
required=False,
37+
help='find the specific institution ID')
38+
args = parser.parse_known_args(command_line_args)
39+
return args
40+
41+
def main():
42+
logger.info("Listing institutions")
43+
44+
args, unknowns = parse()
45+
46+
resp = get_institutions()
47+
48+
if resp['status'] != "OK":
49+
print("There was an error obtaining a list of institutions from the server")
50+
return 1
51+
52+
# Separate by country
53+
inst_by_country = {}
54+
countries = []
55+
for inst in resp['data']:
56+
country_code = inst['country']['code']
57+
country_name = inst['country']['name']
58+
inst_id = inst['id']
59+
inst_name = inst['name']
60+
61+
country_display_name = f"{country_name} ({country_code})"
62+
63+
if args.country is not None:
64+
if args.country.upper() not in country_display_name.upper():
65+
# skip this institution
66+
continue
67+
if args.name is not None:
68+
if args.name.upper() not in inst_name.upper():
69+
# skip this institution
70+
continue
71+
if args.id is not None:
72+
if args.id != str(inst_id):
73+
# skip this institution
74+
continue
75+
76+
if country_code not in inst_by_country.keys():
77+
inst_by_country[country_code] = []
78+
countries.append((country_code, country_display_name))
79+
inst_by_country[country_code].append((inst_id, inst_name))
80+
81+
countries = [ (a, b) for (b, a) in
82+
sorted([(b, a) for (a, b) in countries]) ]
83+
84+
if len(countries) == 0:
85+
print()
86+
print("No institutions found matching criteria")
87+
print()
88+
else:
89+
print()
90+
print("Institutions found:")
91+
print()
92+
for country_code, country_display_name in countries:
93+
94+
institutions = [ (a, b) for (b, a) in
95+
sorted([(b, a) for (a, b) in inst_by_country[country_code]]) ]
96+
97+
if args.country is None:
98+
print(country_display_name)
99+
else:
100+
print(Style.highlight(country_display_name, args.country))
101+
102+
print("="*len(country_display_name))
103+
for inst_id, inst_name in institutions:
104+
if args.name is None:
105+
print(f"{inst_id:3d} {inst_name}")
106+
else:
107+
print(f"{inst_id:3d} {Style.highlight(inst_name, args.name)}")
108+
print()
109+
110+
111+
if __name__ == '__main__':
112+
sys.exit(main())
113+

0 commit comments

Comments
 (0)