vswmc-cli 2.0.9__tar.gz → 2.2.0__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.
Files changed (40) hide show
  1. vswmc_cli-2.2.0/PKG-INFO +173 -0
  2. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/README.md +23 -5
  3. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/setup.py +3 -3
  4. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/__main__.py +3 -2
  5. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/cp.py +17 -4
  6. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/logs.py +1 -1
  7. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/ls.py +18 -1
  8. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/run.py +1 -1
  9. vswmc_cli-2.2.0/vswmc/cli/save.py +35 -0
  10. vswmc_cli-2.2.0/vswmc/cli/utils.py +60 -0
  11. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/client.py +40 -43
  12. vswmc_cli-2.2.0/vswmc/core/auth.py +3 -0
  13. vswmc_cli-2.2.0/vswmc_cli.egg-info/PKG-INFO +173 -0
  14. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/entry_points.txt +0 -1
  15. vswmc-cli-2.0.9/PKG-INFO +0 -140
  16. vswmc-cli-2.0.9/vswmc/cli/save.py +0 -18
  17. vswmc-cli-2.0.9/vswmc/cli/utils.py +0 -85
  18. vswmc-cli-2.0.9/vswmc/core/auth.py +0 -4
  19. vswmc-cli-2.0.9/vswmc_cli.egg-info/PKG-INFO +0 -140
  20. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/LICENSE +0 -0
  21. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/MANIFEST.in +0 -0
  22. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/setup.cfg +0 -0
  23. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/__init__.py +0 -0
  24. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/__init__.py +0 -0
  25. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/models.py +0 -0
  26. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/products.py +0 -0
  27. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/ps.py +0 -0
  28. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/rm.py +0 -0
  29. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/simulations.py +0 -0
  30. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/cli/stop.py +0 -0
  31. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/core/__init__.py +0 -0
  32. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/core/exceptions.py +0 -0
  33. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/core/helpers.py +0 -0
  34. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc/sockjs.py +0 -0
  35. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/SOURCES.txt +0 -0
  36. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/dependency_links.txt +0 -0
  37. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/namespace_packages.txt +0 -0
  38. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/not-zip-safe +0 -0
  39. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/requires.txt +0 -0
  40. {vswmc-cli-2.0.9 → vswmc_cli-2.2.0}/vswmc_cli.egg-info/top_level.txt +0 -0
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: vswmc-cli
3
+ Version: 2.2.0
4
+ Summary: VSWMC Command-Line Tools
5
+ Home-page: https://spaceweather.hpc.kuleuven.be
6
+ Author: Rays of Space
7
+ Author-email: info@raysofspace.com
8
+ License: LGPL
9
+ Platform: Posix; MacOS X; Windows
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 2
15
+ Classifier: Programming Language :: Python :: 2.7
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.4
18
+ Classifier: Programming Language :: Python :: 3.5
19
+ Classifier: Programming Language :: Python :: 3.6
20
+ Classifier: Programming Language :: Python :: 3.7
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Operating System :: OS Independent
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: six
28
+ Requires-Dist: requests
29
+ Requires-Dist: setuptools
30
+ Dynamic: author
31
+ Dynamic: author-email
32
+ Dynamic: classifier
33
+ Dynamic: description
34
+ Dynamic: description-content-type
35
+ Dynamic: home-page
36
+ Dynamic: license
37
+ Dynamic: license-file
38
+ Dynamic: platform
39
+ Dynamic: requires-dist
40
+ Dynamic: summary
41
+
42
+ # VSWMC Command-Line Interface
43
+
44
+ Install with pip:
45
+
46
+ pip install --upgrade vswmc-cli
47
+
48
+ This will install a `vswmc` command on your system. The `vswmc` command uses an S2P OAuth access token for authentication. Obtain the token outside the CLI, for example with the OAuth 2.0 Client Credentials flow described in the SSO migration guide, then provide it with one of:
49
+
50
+ `VSWMC_ACCESS_TOKEN`
51
+
52
+     Read the access token from the environment.
53
+
54
+ `--token TOKEN`
55
+
56
+     Read the access token from the command line.
57
+
58
+ `--token-file FILE`
59
+
60
+     Read the access token from a file.
61
+
62
+ Example token request:
63
+
64
+ curl \
65
+ -d 'client_id=<M2M_CLIENT_ID>' \
66
+ -d 'client_secret=<M2M_CLIENT_SECRET>' \
67
+ -d 'grant_type=client_credentials' \
68
+ -d 'scope=<VSWMC_RESOURCE_SERVER_CLIENT_ID>' \
69
+ 'https://sso.s2p.esa.int/realms/swe/protocol/openid-connect/token'
70
+
71
+ Example CLI usage:
72
+
73
+ export VSWMC_ACCESS_TOKEN=<ACCESS_TOKEN>
74
+ vswmc simulations list
75
+
76
+ ## List available simulations
77
+ vswmc simulations list
78
+
79
+ This shows the parameters that a run requires.
80
+
81
+
82
+ ## Start a run
83
+ vswmc run [--param-file PARAM_FILE] [--param PARAM=VALUE ...] -- SIMULATION
84
+
85
+ This command returns the ID of the new run via stdout. You can use this ID to fetch the log or fetch result files.
86
+
87
+ OPTIONS
88
+ <dl>
89
+ <dt><tt>--param-file PARAM_FILE</tt></dt>
90
+ <dd>Read parameters from a file.</dd>
91
+ <dt><tt>--param PARAM=VALUE ...</tt></dt>
92
+ <dd>Set parameters.</dd>
93
+ </dl>
94
+
95
+ Each simulation supports different parameters. To know what parameters you need for a particular simulation, run:
96
+
97
+ vswmc simulations describe SIMULATION
98
+
99
+
100
+ ## List runs
101
+ vswmc ps [--simulation SIMULATION] [-a, --all]
102
+
103
+ OPTIONS
104
+ <dl>
105
+ <dt><tt>--simulation SIMULATION</tt></dt>
106
+ <dd>Filter on simulation.</dd>
107
+ <dt><tt>-a, --all</tt></dt>
108
+ <dd>List all runs (default shows only ongoing)</dd>
109
+ </dl>
110
+
111
+
112
+ ## Copy a result file to disk
113
+ vswmc cp SRC DST
114
+
115
+ Downloads a remote result file to local disk. The source should be specified in the format <tt>RUN:FILE</tt>. The <tt>DST</tt> argument can be a local file or directory.
116
+
117
+
118
+ ## Fetch the logs of a run
119
+ vswmc logs RUN
120
+
121
+
122
+ ## List the results of a run
123
+ vswmc ls [-l] RUN
124
+
125
+ OPTIONS
126
+ <dl>
127
+ <dt><tt>-l</tt></dt>
128
+ <dd>Print long listing</dd>
129
+ </dl>
130
+
131
+
132
+ ## Save all results of a run
133
+ vswmc save RUN
134
+
135
+ Saves all result files of a run. The results of each individual task in this run are compressed and saved into a zip archive named after the model for that task.
136
+
137
+
138
+ ## Stop one or more runs
139
+ vswmc stop RUN ...
140
+
141
+
142
+ ## Remove one or more runs
143
+ vswmc rm RUN ...
144
+
145
+
146
+ ## Create a product
147
+ vswmc products create [--metadata-file FILE] [--metadata PARAM=VALUE ...] [--attach FILE ...] -- PRODUCT_TYPE
148
+
149
+ OPTIONS
150
+ <dl>
151
+ <dt><tt>--param-file PARAM_FILE</tt></dt>
152
+ <dd>Read parameters from a file.</dd>
153
+ <dt><tt>--param PARAM=VALUE ...</tt></dt>
154
+ <dd>Set parameters.</dd>
155
+ <dt><tt>--attach FILE ...</tt></dt>
156
+ <dd>Attach product files</dd>
157
+ </dl>
158
+
159
+ EXAMPLE
160
+
161
+ vswmc products create --metadata test=123 --attach ../testdata/solar_wind_boundary.dat -- MHD0.1-1
162
+
163
+ Returns the ID of the created product.
164
+
165
+
166
+ ## Start a run using a product as input
167
+
168
+ vswmc run --param corona=6273ce7678eeb43c60d2eb8f \
169
+ --param grid=test_light \
170
+ --param cmes=examples/resources/cme_list.dat \
171
+ -- euhforia-heliosphere-standalone
172
+
173
+ The `corona` parameter expects a product identifier.
@@ -4,16 +4,33 @@ Install with pip:
4
4
 
5
5
  pip install --upgrade vswmc-cli
6
6
 
7
- This will install a `vswmc` command on your system. The `vswmc` command has a few global options:
7
+ This will install a `vswmc` command on your system. The `vswmc` command uses an S2P OAuth access token for authentication. Obtain the token outside the CLI, for example with the OAuth 2.0 Client Credentials flow described in the SSO migration guide, then provide it with one of:
8
8
 
9
- `-u USER`
9
+ `VSWMC_ACCESS_TOKEN`
10
10
 
11
- &nbsp;&nbsp;&nbsp; SSA Username
11
+ &nbsp;&nbsp;&nbsp; Read the access token from the environment.
12
12
 
13
- `-p PASSWORD`
13
+ `--token TOKEN`
14
14
 
15
- &nbsp;&nbsp;&nbsp; SSA Password
15
+ &nbsp;&nbsp;&nbsp; Read the access token from the command line.
16
16
 
17
+ `--token-file FILE`
18
+
19
+ &nbsp;&nbsp;&nbsp; Read the access token from a file.
20
+
21
+ Example token request:
22
+
23
+ curl \
24
+ -d 'client_id=<M2M_CLIENT_ID>' \
25
+ -d 'client_secret=<M2M_CLIENT_SECRET>' \
26
+ -d 'grant_type=client_credentials' \
27
+ -d 'scope=<VSWMC_RESOURCE_SERVER_CLIENT_ID>' \
28
+ 'https://sso.s2p.esa.int/realms/swe/protocol/openid-connect/token'
29
+
30
+ Example CLI usage:
31
+
32
+ export VSWMC_ACCESS_TOKEN=<ACCESS_TOKEN>
33
+ vswmc simulations list
17
34
 
18
35
  ## List available simulations
19
36
  vswmc simulations list
@@ -99,6 +116,7 @@ OPTIONS
99
116
  </dl>
100
117
 
101
118
  EXAMPLE
119
+
102
120
  vswmc products create --metadata test=123 --attach ../testdata/solar_wind_boundary.dat -- MHD0.1-1
103
121
 
104
122
  Returns the ID of the created product.
@@ -11,13 +11,13 @@ packages = [
11
11
 
12
12
  setuptools.setup(
13
13
  name="vswmc-cli",
14
- version="2.0.9",
14
+ version="2.2.0",
15
15
  description="VSWMC Command-Line Tools",
16
16
  long_description=readme,
17
17
  long_description_content_type="text/markdown",
18
18
  url="https://spaceweather.hpc.kuleuven.be",
19
- author="Space Applications Services",
20
- author_email="info@spaceapplications.com",
19
+ author="Rays of Space",
20
+ author_email="info@raysofspace.com",
21
21
  license="LGPL",
22
22
  packages=packages,
23
23
  namespace_packages=["vswmc"],
@@ -39,10 +39,11 @@ def main():
39
39
  version=dist.version,
40
40
  help="Print version information and quit",
41
41
  )
42
+ parser.add_argument("--token", help="S2P OAuth access token")
42
43
  parser.add_argument(
43
- "-u", metavar="USER", dest="user", required=True, help="SSA Username"
44
+ "--token-file",
45
+ help="Read the S2P OAuth access token from a file",
44
46
  )
45
- parser.add_argument("-p", metavar="PASSWORD", dest="password", help="SSA Password")
46
47
  parser.add_argument("--dev", action="store_true", help=argparse.SUPPRESS)
47
48
  parser.add_argument("--debug", action="store_true", help=argparse.SUPPRESS)
48
49
  parser.add_argument(
@@ -23,9 +23,22 @@ def do_cp(args):
23
23
  f.write(content)
24
24
 
25
25
 
26
+ def do_cp_new(args):
27
+ client = utils.create_client(args)
28
+ run, src_file = args.src.split(":")
29
+ content = client.get_run_output_presign_content(run, src_file)
30
+ _, src_filename = os.path.split(src_file)
31
+
32
+ if os.path.isdir(args.dst):
33
+ target_file = os.path.join(args.dst, src_filename)
34
+ else:
35
+ target_file = args.dst
36
+
37
+ with open(target_file, "wb") as f:
38
+ f.write(content)
39
+
40
+
26
41
  def configure_parser(parser):
27
- parser.set_defaults(func=do_cp)
28
- parser.add_argument(
29
- "src", metavar="SRC", type=str, help="file in the format RUN:FILE"
30
- )
42
+ parser.set_defaults(func=do_cp_new)
43
+ parser.add_argument("src", metavar="SRC", type=str, help="file in the format RUN:FILE")
31
44
  parser.add_argument("dst", metavar="DST", type=str, help="target file or directory")
@@ -17,7 +17,7 @@ def do_logs(args):
17
17
  print(content.strip())
18
18
 
19
19
  if args.follow:
20
- subscription = client.follow_logs(args.user, args.run, on_data=on_data)
20
+ subscription = client.follow_logs(args.run, on_data=on_data)
21
21
  subscription.result()
22
22
 
23
23
 
@@ -21,7 +21,24 @@ def do_ls(args):
21
21
  utils.print_table(rows)
22
22
 
23
23
 
24
+ def do_ls_new(args):
25
+ client = utils.create_client(args)
26
+ outputs = client.list_run_outputs(args.run)
27
+ rows = []
28
+ for result in outputs:
29
+ if args.l:
30
+ rows.append(
31
+ [
32
+ str(result["size"]),
33
+ result["path"],
34
+ ]
35
+ )
36
+ else:
37
+ rows.append([result["path"]])
38
+ utils.print_table(rows)
39
+
40
+
24
41
  def configure_parser(parser):
25
- parser.set_defaults(func=do_ls)
42
+ parser.set_defaults(func=do_ls_new)
26
43
  parser.add_argument("run", metavar="RUN", help="The run to query")
27
44
  parser.add_argument("-l", action="store_true", help="Print long listing")
@@ -53,7 +53,7 @@ def do_run(args):
53
53
  content = client.download_logs(run["id"]).strip()
54
54
  if content:
55
55
  print(content)
56
- subscription = client.follow_logs(args.user, run["id"], on_data=on_data)
56
+ subscription = client.follow_logs(run["id"], on_data=on_data)
57
57
  subscription.result()
58
58
  else:
59
59
  print(run["id"])
@@ -0,0 +1,35 @@
1
+ from __future__ import print_function
2
+
3
+ import os
4
+
5
+ from vswmc.cli import utils
6
+
7
+
8
+ def do_save(args):
9
+ client = utils.create_client(args)
10
+ content = client.download_results(args.run)
11
+
12
+ target_file = args.run + ".zip"
13
+ print("Saving {}".format(target_file))
14
+ with open(target_file, "wb") as f:
15
+ f.write(content)
16
+
17
+
18
+ def do_save_new(args):
19
+ client = utils.create_client(args)
20
+ outputs = client.list_run_outputs(args.run)
21
+ if not outputs:
22
+ print("No outputs available for run {}".format(args.run))
23
+ return
24
+ os.path.makedirs(args.run, exist_ok=True)
25
+ for output in outputs:
26
+ content = client.get_run_output_presign_content(args.run, output["path"])
27
+ target_file = os.path.join(args.run, output["path"])
28
+ print("Saving {}".format(target_file))
29
+ with open(target_file, "wb") as f:
30
+ f.write(content)
31
+
32
+
33
+ def configure_parser(parser):
34
+ parser.set_defaults(func=do_save_new)
35
+ parser.add_argument("run", metavar="RUN", help="The run to save")
@@ -0,0 +1,60 @@
1
+ from __future__ import print_function
2
+
3
+ import os
4
+
5
+ from vswmc.client import VswmcClient
6
+ from vswmc.core import auth
7
+
8
+
9
+ def create_client(args):
10
+ # Bypass auth for local development
11
+ if args.dev:
12
+ return VswmcClient("http://localhost:3000")
13
+
14
+ token = resolve_token(args)
15
+ if not token:
16
+ raise Exception(
17
+ "Missing access token. Provide --token, --token-file, or VSWMC_ACCESS_TOKEN."
18
+ )
19
+
20
+ credentials = auth.TokenCredentials(token=token)
21
+ return VswmcClient(args.url, credentials=credentials)
22
+
23
+
24
+ def resolve_token(args):
25
+ if args.token:
26
+ return args.token.strip()
27
+
28
+ if args.token_file:
29
+ with open(os.path.expanduser(args.token_file), "r") as f:
30
+ return f.read().strip()
31
+
32
+ token = os.environ.get("VSWMC_ACCESS_TOKEN")
33
+ return token.strip() if token else None
34
+
35
+
36
+ def print_table(rows, header=False):
37
+ widths = list(map(len, rows[0]))
38
+ for row in rows:
39
+ for idx, col in enumerate(row):
40
+ widths[idx] = max(len(str(col)), widths[idx])
41
+
42
+ separator = " "
43
+
44
+ total_width = 0
45
+ for width in widths:
46
+ total_width += width
47
+ total_width += len(separator) * (len(widths) - 1)
48
+
49
+ data = rows[1:] if header else rows
50
+ if header and data:
51
+ cols = separator.join(
52
+ [str.ljust(str(col), width) for col, width in zip(rows[0], widths)]
53
+ )
54
+ print(cols)
55
+ if data:
56
+ for row in data:
57
+ cols = separator.join(
58
+ [str.ljust(str(col), width) for col, width in zip(row, widths)]
59
+ )
60
+ print(cols)
@@ -5,8 +5,6 @@ import requests
5
5
  from vswmc.core.exceptions import NotFound, Unauthorized, VswmcError
6
6
  from vswmc.sockjs import SockJSSession
7
7
 
8
- SSO_URL = "https://sso.ssa.esa.int/am/json/authenticate"
9
-
10
8
 
11
9
  class VswmcClient(object):
12
10
  def __init__(self, address, credentials=None):
@@ -17,37 +15,30 @@ class VswmcClient(object):
17
15
 
18
16
  self.session = requests.Session()
19
17
  if credentials:
20
- self.login(credentials)
18
+ self.authenticate(credentials)
21
19
 
22
- def login(self, credentials):
23
- self.session.cookies.clear()
20
+ def authenticate(self, credentials):
21
+ token = credentials.token.strip() if credentials.token else None
22
+ if not token:
23
+ raise Unauthorized("Missing access token")
24
24
 
25
- res = self.session.post(
26
- SSO_URL,
27
- headers={
28
- "X-OpenAM-Username": credentials.username,
29
- "X-OpenAM-Password": credentials.password,
30
- },
25
+ self.session.cookies.clear()
26
+ authorization = (
27
+ token if token.lower().startswith("bearer ") else "Bearer " + token
31
28
  )
29
+ self.session.headers.update({"Authorization": authorization})
32
30
 
33
- msg = res.json()
34
- if "tokenId" not in msg:
35
- code = msg["code"]
36
- reason = msg["reason"]
37
- message = msg["message"]
38
- if code == 401:
39
- raise Unauthorized("Authentication Failed")
40
- else:
41
- raise VswmcError(reason + ": " + message)
42
-
43
- token = msg["tokenId"]
44
- self.session.cookies.set("iPlanetDirectoryPro", token)
45
- self.session.cookies.set("esa-ssa-sso-cookie", token)
31
+ def login(self, credentials):
32
+ self.authenticate(credentials)
46
33
 
47
34
  def list_models(self):
48
35
  path = "{}/models".format(self.api_root)
49
36
  return self._request("get", path=path).json()["models"]
50
37
 
38
+ def get_current_user(self):
39
+ path = "{}/user".format(self.api_root)
40
+ return self._request("get", path=path).json()
41
+
51
42
  def get_model(self, name):
52
43
  path = "{}/models/{}".format(self.api_root, name)
53
44
  return self._request("get", path=path).json()
@@ -106,6 +97,22 @@ class VswmcClient(object):
106
97
  path = "{}/runs/{}".format(self.api_root, run)
107
98
  return self._request("get", path=path).json()
108
99
 
100
+ def list_run_outputs(self, run):
101
+ path = "{}/runs/{}/outputs".format(self.api_root, run)
102
+ return self._request("get", path=path).json()
103
+
104
+ def get_run_output(self, run, name):
105
+ path = "{}/runs/{}/outputs/{}".format(self.api_root, run, name)
106
+ return self._request("get", path=path).content
107
+
108
+ def get_run_output_presign_url(self, run, name):
109
+ path = "{}/runs/{}/outputs/{}/presign".format(self.api_root, run, name)
110
+ return self._request("get", path=path).json()
111
+
112
+ def get_run_output_presign_content(self, run, name):
113
+ presign = self.get_run_output_presign_url(run, name)
114
+ return requests.get(url=presign["url"]).content
115
+
109
116
  def download_logs(self, run):
110
117
  path = "{}/runs/{}/log".format(self.api_root, run)
111
118
  return self._request("get", path=path, params={"raw": "yes"}).content
@@ -118,11 +125,12 @@ class VswmcClient(object):
118
125
  path = "{}/runs/{}/results".format(self.api_root, run)
119
126
  return self._request("get", path=path).content
120
127
 
121
- def follow_logs(self, user, run, on_data):
128
+ def follow_logs(self, run, on_data):
122
129
  def filter_(msg, sess):
123
130
  if run == msg["headers"]["runId"]:
124
131
  on_data(msg["body"], sess)
125
132
 
133
+ user = self.get_current_user()["subject"]
126
134
  session = SockJSSession(self.address, on_data=filter_, session=self.session)
127
135
  session.send(
128
136
  json.dumps(
@@ -147,24 +155,14 @@ class VswmcClient(object):
147
155
  return "localhost" in self.address or "spaceweather2" in self.address
148
156
 
149
157
  def upload_magnetogram(self, f, name):
150
- if self.is_test():
151
- upload = self.upload_file(f, name)
152
- path = "{}/products/magnetograms/USER/{}".format(self.api_root, upload)
153
- return self._request("get", path=path).json()
154
- else:
155
- path = "{}/products/magnetograms".format(self.api_root)
156
- files = {"file": (name, f, "application/octet-stream")}
157
- return self._request("post", path=path, files=files).json()
158
+ upload = self.upload_file(f, name)
159
+ path = "{}/products/magnetograms/USER/{}".format(self.api_root, upload)
160
+ return self._request("get", path=path).json()
158
161
 
159
162
  def upload_cme_file(self, f, name):
160
- if self.is_test():
161
- upload = self.upload_file(f, name)
162
- path = "{}/products/cme/{}".format(self.api_root, upload)
163
- return self._request("get", path=path).json()
164
- else:
165
- path = "{}/products/cme".format(self.api_root)
166
- files = {"file": (name, f, "application/octet-stream")}
167
- return self._request("post", path=path, files=files).json()
163
+ upload = self.upload_file(f, name)
164
+ path = "{}/products/cme/{}".format(self.api_root, upload)
165
+ return self._request("get", path=path).json()
168
166
 
169
167
  def upload_file(self, f, name):
170
168
  path = "{}/uploads".format(self.api_root)
@@ -175,8 +173,7 @@ class VswmcClient(object):
175
173
  response = self.session.request(method, path, **kwargs)
176
174
 
177
175
  if response.headers.get("content-type", "").startswith("text/html"):
178
- if "OpenAM" in response.text:
179
- raise Unauthorized("Invalid session")
176
+ raise Unauthorized("Invalid or expired access token")
180
177
 
181
178
  if 200 <= response.status_code < 300:
182
179
  return response
@@ -0,0 +1,3 @@
1
+ class TokenCredentials(object):
2
+ def __init__(self, token=None):
3
+ self.token = token
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: vswmc-cli
3
+ Version: 2.2.0
4
+ Summary: VSWMC Command-Line Tools
5
+ Home-page: https://spaceweather.hpc.kuleuven.be
6
+ Author: Rays of Space
7
+ Author-email: info@raysofspace.com
8
+ License: LGPL
9
+ Platform: Posix; MacOS X; Windows
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 2
15
+ Classifier: Programming Language :: Python :: 2.7
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.4
18
+ Classifier: Programming Language :: Python :: 3.5
19
+ Classifier: Programming Language :: Python :: 3.6
20
+ Classifier: Programming Language :: Python :: 3.7
21
+ Classifier: Programming Language :: Python :: 3.8
22
+ Classifier: Programming Language :: Python :: 3.9
23
+ Classifier: Programming Language :: Python :: 3.10
24
+ Classifier: Operating System :: OS Independent
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: six
28
+ Requires-Dist: requests
29
+ Requires-Dist: setuptools
30
+ Dynamic: author
31
+ Dynamic: author-email
32
+ Dynamic: classifier
33
+ Dynamic: description
34
+ Dynamic: description-content-type
35
+ Dynamic: home-page
36
+ Dynamic: license
37
+ Dynamic: license-file
38
+ Dynamic: platform
39
+ Dynamic: requires-dist
40
+ Dynamic: summary
41
+
42
+ # VSWMC Command-Line Interface
43
+
44
+ Install with pip:
45
+
46
+ pip install --upgrade vswmc-cli
47
+
48
+ This will install a `vswmc` command on your system. The `vswmc` command uses an S2P OAuth access token for authentication. Obtain the token outside the CLI, for example with the OAuth 2.0 Client Credentials flow described in the SSO migration guide, then provide it with one of:
49
+
50
+ `VSWMC_ACCESS_TOKEN`
51
+
52
+ &nbsp;&nbsp;&nbsp; Read the access token from the environment.
53
+
54
+ `--token TOKEN`
55
+
56
+ &nbsp;&nbsp;&nbsp; Read the access token from the command line.
57
+
58
+ `--token-file FILE`
59
+
60
+ &nbsp;&nbsp;&nbsp; Read the access token from a file.
61
+
62
+ Example token request:
63
+
64
+ curl \
65
+ -d 'client_id=<M2M_CLIENT_ID>' \
66
+ -d 'client_secret=<M2M_CLIENT_SECRET>' \
67
+ -d 'grant_type=client_credentials' \
68
+ -d 'scope=<VSWMC_RESOURCE_SERVER_CLIENT_ID>' \
69
+ 'https://sso.s2p.esa.int/realms/swe/protocol/openid-connect/token'
70
+
71
+ Example CLI usage:
72
+
73
+ export VSWMC_ACCESS_TOKEN=<ACCESS_TOKEN>
74
+ vswmc simulations list
75
+
76
+ ## List available simulations
77
+ vswmc simulations list
78
+
79
+ This shows the parameters that a run requires.
80
+
81
+
82
+ ## Start a run
83
+ vswmc run [--param-file PARAM_FILE] [--param PARAM=VALUE ...] -- SIMULATION
84
+
85
+ This command returns the ID of the new run via stdout. You can use this ID to fetch the log or fetch result files.
86
+
87
+ OPTIONS
88
+ <dl>
89
+ <dt><tt>--param-file PARAM_FILE</tt></dt>
90
+ <dd>Read parameters from a file.</dd>
91
+ <dt><tt>--param PARAM=VALUE ...</tt></dt>
92
+ <dd>Set parameters.</dd>
93
+ </dl>
94
+
95
+ Each simulation supports different parameters. To know what parameters you need for a particular simulation, run:
96
+
97
+ vswmc simulations describe SIMULATION
98
+
99
+
100
+ ## List runs
101
+ vswmc ps [--simulation SIMULATION] [-a, --all]
102
+
103
+ OPTIONS
104
+ <dl>
105
+ <dt><tt>--simulation SIMULATION</tt></dt>
106
+ <dd>Filter on simulation.</dd>
107
+ <dt><tt>-a, --all</tt></dt>
108
+ <dd>List all runs (default shows only ongoing)</dd>
109
+ </dl>
110
+
111
+
112
+ ## Copy a result file to disk
113
+ vswmc cp SRC DST
114
+
115
+ Downloads a remote result file to local disk. The source should be specified in the format <tt>RUN:FILE</tt>. The <tt>DST</tt> argument can be a local file or directory.
116
+
117
+
118
+ ## Fetch the logs of a run
119
+ vswmc logs RUN
120
+
121
+
122
+ ## List the results of a run
123
+ vswmc ls [-l] RUN
124
+
125
+ OPTIONS
126
+ <dl>
127
+ <dt><tt>-l</tt></dt>
128
+ <dd>Print long listing</dd>
129
+ </dl>
130
+
131
+
132
+ ## Save all results of a run
133
+ vswmc save RUN
134
+
135
+ Saves all result files of a run. The results of each individual task in this run are compressed and saved into a zip archive named after the model for that task.
136
+
137
+
138
+ ## Stop one or more runs
139
+ vswmc stop RUN ...
140
+
141
+
142
+ ## Remove one or more runs
143
+ vswmc rm RUN ...
144
+
145
+
146
+ ## Create a product
147
+ vswmc products create [--metadata-file FILE] [--metadata PARAM=VALUE ...] [--attach FILE ...] -- PRODUCT_TYPE
148
+
149
+ OPTIONS
150
+ <dl>
151
+ <dt><tt>--param-file PARAM_FILE</tt></dt>
152
+ <dd>Read parameters from a file.</dd>
153
+ <dt><tt>--param PARAM=VALUE ...</tt></dt>
154
+ <dd>Set parameters.</dd>
155
+ <dt><tt>--attach FILE ...</tt></dt>
156
+ <dd>Attach product files</dd>
157
+ </dl>
158
+
159
+ EXAMPLE
160
+
161
+ vswmc products create --metadata test=123 --attach ../testdata/solar_wind_boundary.dat -- MHD0.1-1
162
+
163
+ Returns the ID of the created product.
164
+
165
+
166
+ ## Start a run using a product as input
167
+
168
+ vswmc run --param corona=6273ce7678eeb43c60d2eb8f \
169
+ --param grid=test_light \
170
+ --param cmes=examples/resources/cme_list.dat \
171
+ -- euhforia-heliosphere-standalone
172
+
173
+ The `corona` parameter expects a product identifier.
@@ -1,3 +1,2 @@
1
1
  [console_scripts]
2
2
  vswmc = vswmc.cli.__main__:main
3
-
vswmc-cli-2.0.9/PKG-INFO DELETED
@@ -1,140 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: vswmc-cli
3
- Version: 2.0.9
4
- Summary: VSWMC Command-Line Tools
5
- Home-page: https://spaceweather.hpc.kuleuven.be
6
- Author: Space Applications Services
7
- Author-email: info@spaceapplications.com
8
- License: LGPL
9
- Description: # VSWMC Command-Line Interface
10
-
11
- Install with pip:
12
-
13
- pip install --upgrade vswmc-cli
14
-
15
- This will install a `vswmc` command on your system. The `vswmc` command has a few global options:
16
-
17
- `-u USER`
18
-
19
- &nbsp;&nbsp;&nbsp; SSA Username
20
-
21
- `-p PASSWORD`
22
-
23
- &nbsp;&nbsp;&nbsp; SSA Password
24
-
25
-
26
- ## List available simulations
27
- vswmc simulations list
28
-
29
- This shows the parameters that a run requires.
30
-
31
-
32
- ## Start a run
33
- vswmc run [--param-file PARAM_FILE] [--param PARAM=VALUE ...] -- SIMULATION
34
-
35
- This command returns the ID of the new run via stdout. You can use this ID to fetch the log or fetch result files.
36
-
37
- OPTIONS
38
- <dl>
39
- <dt><tt>--param-file PARAM_FILE</tt></dt>
40
- <dd>Read parameters from a file.</dd>
41
- <dt><tt>--param PARAM=VALUE ...</tt></dt>
42
- <dd>Set parameters.</dd>
43
- </dl>
44
-
45
- Each simulation supports different parameters. To know what parameters you need for a particular simulation, run:
46
-
47
- vswmc simulations describe SIMULATION
48
-
49
-
50
- ## List runs
51
- vswmc ps [--simulation SIMULATION] [-a, --all]
52
-
53
- OPTIONS
54
- <dl>
55
- <dt><tt>--simulation SIMULATION</tt></dt>
56
- <dd>Filter on simulation.</dd>
57
- <dt><tt>-a, --all</tt></dt>
58
- <dd>List all runs (default shows only ongoing)</dd>
59
- </dl>
60
-
61
-
62
- ## Copy a result file to disk
63
- vswmc cp SRC DST
64
-
65
- Downloads a remote result file to local disk. The source should be specified in the format <tt>RUN:FILE</tt>. The <tt>DST</tt> argument can be a local file or directory.
66
-
67
-
68
- ## Fetch the logs of a run
69
- vswmc logs RUN
70
-
71
-
72
- ## List the results of a run
73
- vswmc ls [-l] RUN
74
-
75
- OPTIONS
76
- <dl>
77
- <dt><tt>-l</tt></dt>
78
- <dd>Print long listing</dd>
79
- </dl>
80
-
81
-
82
- ## Save all results of a run
83
- vswmc save RUN
84
-
85
- Saves all result files of a run. The results of each individual task in this run are compressed and saved into a zip archive named after the model for that task.
86
-
87
-
88
- ## Stop one or more runs
89
- vswmc stop RUN ...
90
-
91
-
92
- ## Remove one or more runs
93
- vswmc rm RUN ...
94
-
95
-
96
- ## Create a product
97
- vswmc products create [--metadata-file FILE] [--metadata PARAM=VALUE ...] [--attach FILE ...] -- PRODUCT_TYPE
98
-
99
- OPTIONS
100
- <dl>
101
- <dt><tt>--param-file PARAM_FILE</tt></dt>
102
- <dd>Read parameters from a file.</dd>
103
- <dt><tt>--param PARAM=VALUE ...</tt></dt>
104
- <dd>Set parameters.</dd>
105
- <dt><tt>--attach FILE ...</tt></dt>
106
- <dd>Attach product files</dd>
107
- </dl>
108
-
109
- EXAMPLE
110
- vswmc products create --metadata test=123 --attach ../testdata/solar_wind_boundary.dat -- MHD0.1-1
111
-
112
- Returns the ID of the created product.
113
-
114
-
115
- ## Start a run using a product as input
116
-
117
- vswmc run --param corona=6273ce7678eeb43c60d2eb8f \
118
- --param grid=test_light \
119
- --param cmes=examples/resources/cme_list.dat \
120
- -- euhforia-heliosphere-standalone
121
-
122
- The `corona` parameter expects a product identifier.
123
-
124
- Platform: Posix; MacOS X; Windows
125
- Classifier: Development Status :: 4 - Beta
126
- Classifier: Intended Audience :: Developers
127
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
128
- Classifier: Programming Language :: Python
129
- Classifier: Programming Language :: Python :: 2
130
- Classifier: Programming Language :: Python :: 2.7
131
- Classifier: Programming Language :: Python :: 3
132
- Classifier: Programming Language :: Python :: 3.4
133
- Classifier: Programming Language :: Python :: 3.5
134
- Classifier: Programming Language :: Python :: 3.6
135
- Classifier: Programming Language :: Python :: 3.7
136
- Classifier: Programming Language :: Python :: 3.8
137
- Classifier: Programming Language :: Python :: 3.9
138
- Classifier: Programming Language :: Python :: 3.10
139
- Classifier: Operating System :: OS Independent
140
- Description-Content-Type: text/markdown
@@ -1,18 +0,0 @@
1
- from __future__ import print_function
2
-
3
- from vswmc.cli import utils
4
-
5
-
6
- def do_save(args):
7
- client = utils.create_client(args)
8
- content = client.download_results(args.run)
9
-
10
- target_file = args.run + ".zip"
11
- print("Saving {}".format(target_file))
12
- with open(target_file, "wb") as f:
13
- f.write(content)
14
-
15
-
16
- def configure_parser(parser):
17
- parser.set_defaults(func=do_save)
18
- parser.add_argument("run", metavar="RUN", help="The run to save")
@@ -1,85 +0,0 @@
1
- from __future__ import print_function
2
-
3
- import os
4
- import pickle
5
- from getpass import getpass
6
-
7
- from vswmc.client import VswmcClient
8
- from vswmc.core import auth
9
-
10
- HOME = os.path.expanduser("~")
11
- CONFIG_DIR = os.path.join(os.path.join(HOME, ".config"), "vswmc-cli")
12
- CREDENTIALS_FILE = os.path.join(CONFIG_DIR, "credentials")
13
-
14
-
15
- def create_client(args):
16
- # Bypass auth for local development
17
- if args.dev:
18
- return VswmcClient("http://localhost:3000")
19
-
20
- client = VswmcClient(args.url)
21
-
22
- logged_in = False
23
- if os.path.exists(CREDENTIALS_FILE):
24
- with open(CREDENTIALS_FILE, "rb") as f:
25
- creds = pickle.load(f)
26
- if creds["username"] == args.user:
27
- client.session.cookies.update(creds["cookies"])
28
- # Quick check to test if this session is still functional
29
- try:
30
- client.list_models()
31
- logged_in = True
32
- except:
33
- pass
34
- if not logged_in:
35
- password = args.password or getpass("Password: ")
36
- if not password:
37
- print("*** Password may not be null")
38
- return False
39
-
40
- credentials = auth.Credentials(username=args.user, password=password)
41
- client.login(credentials)
42
- save_session(args.user, client.session.cookies)
43
-
44
- return client
45
-
46
-
47
- def save_session(username, cookies):
48
- if not os.path.exists(CONFIG_DIR):
49
- os.makedirs(CONFIG_DIR)
50
-
51
- with open(CREDENTIALS_FILE, "wb") as f:
52
- pickle.dump(
53
- {
54
- "username": username,
55
- "cookies": cookies,
56
- },
57
- f,
58
- )
59
-
60
-
61
- def print_table(rows, header=False):
62
- widths = list(map(len, rows[0]))
63
- for row in rows:
64
- for idx, col in enumerate(row):
65
- widths[idx] = max(len(str(col)), widths[idx])
66
-
67
- separator = " "
68
-
69
- total_width = 0
70
- for width in widths:
71
- total_width += width
72
- total_width += len(separator) * (len(widths) - 1)
73
-
74
- data = rows[1:] if header else rows
75
- if header and data:
76
- cols = separator.join(
77
- [str.ljust(str(col), width) for col, width in zip(rows[0], widths)]
78
- )
79
- print(cols)
80
- if data:
81
- for row in data:
82
- cols = separator.join(
83
- [str.ljust(str(col), width) for col, width in zip(row, widths)]
84
- )
85
- print(cols)
@@ -1,4 +0,0 @@
1
- class Credentials(object):
2
- def __init__(self, username=None, password=None):
3
- self.username = username
4
- self.password = password
@@ -1,140 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: vswmc-cli
3
- Version: 2.0.9
4
- Summary: VSWMC Command-Line Tools
5
- Home-page: https://spaceweather.hpc.kuleuven.be
6
- Author: Space Applications Services
7
- Author-email: info@spaceapplications.com
8
- License: LGPL
9
- Description: # VSWMC Command-Line Interface
10
-
11
- Install with pip:
12
-
13
- pip install --upgrade vswmc-cli
14
-
15
- This will install a `vswmc` command on your system. The `vswmc` command has a few global options:
16
-
17
- `-u USER`
18
-
19
- &nbsp;&nbsp;&nbsp; SSA Username
20
-
21
- `-p PASSWORD`
22
-
23
- &nbsp;&nbsp;&nbsp; SSA Password
24
-
25
-
26
- ## List available simulations
27
- vswmc simulations list
28
-
29
- This shows the parameters that a run requires.
30
-
31
-
32
- ## Start a run
33
- vswmc run [--param-file PARAM_FILE] [--param PARAM=VALUE ...] -- SIMULATION
34
-
35
- This command returns the ID of the new run via stdout. You can use this ID to fetch the log or fetch result files.
36
-
37
- OPTIONS
38
- <dl>
39
- <dt><tt>--param-file PARAM_FILE</tt></dt>
40
- <dd>Read parameters from a file.</dd>
41
- <dt><tt>--param PARAM=VALUE ...</tt></dt>
42
- <dd>Set parameters.</dd>
43
- </dl>
44
-
45
- Each simulation supports different parameters. To know what parameters you need for a particular simulation, run:
46
-
47
- vswmc simulations describe SIMULATION
48
-
49
-
50
- ## List runs
51
- vswmc ps [--simulation SIMULATION] [-a, --all]
52
-
53
- OPTIONS
54
- <dl>
55
- <dt><tt>--simulation SIMULATION</tt></dt>
56
- <dd>Filter on simulation.</dd>
57
- <dt><tt>-a, --all</tt></dt>
58
- <dd>List all runs (default shows only ongoing)</dd>
59
- </dl>
60
-
61
-
62
- ## Copy a result file to disk
63
- vswmc cp SRC DST
64
-
65
- Downloads a remote result file to local disk. The source should be specified in the format <tt>RUN:FILE</tt>. The <tt>DST</tt> argument can be a local file or directory.
66
-
67
-
68
- ## Fetch the logs of a run
69
- vswmc logs RUN
70
-
71
-
72
- ## List the results of a run
73
- vswmc ls [-l] RUN
74
-
75
- OPTIONS
76
- <dl>
77
- <dt><tt>-l</tt></dt>
78
- <dd>Print long listing</dd>
79
- </dl>
80
-
81
-
82
- ## Save all results of a run
83
- vswmc save RUN
84
-
85
- Saves all result files of a run. The results of each individual task in this run are compressed and saved into a zip archive named after the model for that task.
86
-
87
-
88
- ## Stop one or more runs
89
- vswmc stop RUN ...
90
-
91
-
92
- ## Remove one or more runs
93
- vswmc rm RUN ...
94
-
95
-
96
- ## Create a product
97
- vswmc products create [--metadata-file FILE] [--metadata PARAM=VALUE ...] [--attach FILE ...] -- PRODUCT_TYPE
98
-
99
- OPTIONS
100
- <dl>
101
- <dt><tt>--param-file PARAM_FILE</tt></dt>
102
- <dd>Read parameters from a file.</dd>
103
- <dt><tt>--param PARAM=VALUE ...</tt></dt>
104
- <dd>Set parameters.</dd>
105
- <dt><tt>--attach FILE ...</tt></dt>
106
- <dd>Attach product files</dd>
107
- </dl>
108
-
109
- EXAMPLE
110
- vswmc products create --metadata test=123 --attach ../testdata/solar_wind_boundary.dat -- MHD0.1-1
111
-
112
- Returns the ID of the created product.
113
-
114
-
115
- ## Start a run using a product as input
116
-
117
- vswmc run --param corona=6273ce7678eeb43c60d2eb8f \
118
- --param grid=test_light \
119
- --param cmes=examples/resources/cme_list.dat \
120
- -- euhforia-heliosphere-standalone
121
-
122
- The `corona` parameter expects a product identifier.
123
-
124
- Platform: Posix; MacOS X; Windows
125
- Classifier: Development Status :: 4 - Beta
126
- Classifier: Intended Audience :: Developers
127
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
128
- Classifier: Programming Language :: Python
129
- Classifier: Programming Language :: Python :: 2
130
- Classifier: Programming Language :: Python :: 2.7
131
- Classifier: Programming Language :: Python :: 3
132
- Classifier: Programming Language :: Python :: 3.4
133
- Classifier: Programming Language :: Python :: 3.5
134
- Classifier: Programming Language :: Python :: 3.6
135
- Classifier: Programming Language :: Python :: 3.7
136
- Classifier: Programming Language :: Python :: 3.8
137
- Classifier: Programming Language :: Python :: 3.9
138
- Classifier: Programming Language :: Python :: 3.10
139
- Classifier: Operating System :: OS Independent
140
- Description-Content-Type: text/markdown
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