aplos-nca-saas-sdk 1.0.0__py3-none-any.whl
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.
- aplos_nca_saas_sdk/__init__.py +0 -0
- aplos_nca_saas_sdk/aws_resources/aws_cognito.py +188 -0
- aplos_nca_saas_sdk/aws_resources/aws_s3_presigned_payload.py +49 -0
- aplos_nca_saas_sdk/aws_resources/aws_s3_presigned_upload.py +116 -0
- aplos_nca_saas_sdk/files/analysis_files/single_ev/configuration_single_ev.json +51 -0
- aplos_nca_saas_sdk/files/analysis_files/single_ev/meta_data.json +17 -0
- aplos_nca_saas_sdk/files/analysis_files/single_ev/single_ev.csv +121 -0
- aplos_nca_saas_sdk/integration_testing/integration_test_base.py +34 -0
- aplos_nca_saas_sdk/integration_testing/integration_test_factory.py +62 -0
- aplos_nca_saas_sdk/integration_testing/integration_test_suite.py +84 -0
- aplos_nca_saas_sdk/integration_testing/main.py +28 -0
- aplos_nca_saas_sdk/integration_testing/readme.md +18 -0
- aplos_nca_saas_sdk/integration_testing/tests/app_configuration_test.py +30 -0
- aplos_nca_saas_sdk/integration_testing/tests/app_execution_test.py +5 -0
- aplos_nca_saas_sdk/integration_testing/tests/app_login_test.py +32 -0
- aplos_nca_saas_sdk/integration_testing/tests/app_validation_test.py +5 -0
- aplos_nca_saas_sdk/nca_resources/nca_app_configuration.py +69 -0
- aplos_nca_saas_sdk/nca_resources/nca_endpoints.py +54 -0
- aplos_nca_saas_sdk/nca_resources/nca_executions.py +378 -0
- aplos_nca_saas_sdk/nca_resources/nca_login.py +104 -0
- aplos_nca_saas_sdk/utilities/commandline_args.py +332 -0
- aplos_nca_saas_sdk/utilities/environment_services.py +81 -0
- aplos_nca_saas_sdk/utilities/environment_vars.py +23 -0
- aplos_nca_saas_sdk/utilities/http_utility.py +30 -0
- aplos_nca_saas_sdk/version.py +4 -0
- aplos_nca_saas_sdk-1.0.0.dist-info/METADATA +195 -0
- aplos_nca_saas_sdk-1.0.0.dist-info/RECORD +28 -0
- aplos_nca_saas_sdk-1.0.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,332 @@
|
|
1
|
+
import os
|
2
|
+
import argparse
|
3
|
+
import getpass
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import List
|
6
|
+
from aplos_nca_saas_sdk.utilities.environment_vars import EnvironmentVars
|
7
|
+
from dotenv import load_dotenv
|
8
|
+
|
9
|
+
# load the environment (.env) file if any
|
10
|
+
# this may or may not be the desired results
|
11
|
+
load_dotenv(override=True)
|
12
|
+
|
13
|
+
|
14
|
+
class CommandlineArgs:
|
15
|
+
def __init__(self) -> None:
|
16
|
+
# command line args
|
17
|
+
self.parser = argparse.ArgumentParser(
|
18
|
+
description="Example script to demonstrate command line argument parsing."
|
19
|
+
)
|
20
|
+
|
21
|
+
# Add the arguments
|
22
|
+
self.parser.add_argument(
|
23
|
+
"-u", "--username", required=False, help="The username"
|
24
|
+
)
|
25
|
+
self.parser.add_argument(
|
26
|
+
"-p", "--password", required=False, help="The password"
|
27
|
+
)
|
28
|
+
self.parser.add_argument(
|
29
|
+
"-c", "--config-file", required=False, help="Path to the configuration file"
|
30
|
+
)
|
31
|
+
self.parser.add_argument(
|
32
|
+
"-f", "--analyis-file", required=False, help="Path to the analysis file"
|
33
|
+
)
|
34
|
+
self.parser.add_argument(
|
35
|
+
"-m", "--metadata-file", required=False, help="Path to the metadata file"
|
36
|
+
)
|
37
|
+
|
38
|
+
self.parser.add_argument("-a", "--api-url", required=False, help="The api url")
|
39
|
+
self.parser.add_argument(
|
40
|
+
"-i", "--client-id", required=False, help="The client id to cognito"
|
41
|
+
)
|
42
|
+
|
43
|
+
self.parser.add_argument(
|
44
|
+
"-v", "--verbose", required=False, help="Detailed logging information"
|
45
|
+
)
|
46
|
+
|
47
|
+
self.parser.add_argument(
|
48
|
+
"-r", "--region", required=False, help="AWS Region. For Cognito Login"
|
49
|
+
)
|
50
|
+
|
51
|
+
self.parser.add_argument(
|
52
|
+
"-s",
|
53
|
+
"--skip",
|
54
|
+
required=False,
|
55
|
+
action="store_true",
|
56
|
+
help="Skip prompts if required values have defaults",
|
57
|
+
)
|
58
|
+
self.parser.add_argument(
|
59
|
+
"-o",
|
60
|
+
"--output-directory",
|
61
|
+
required=False,
|
62
|
+
help="The full path to an output directory",
|
63
|
+
)
|
64
|
+
|
65
|
+
self.parser.add_argument(
|
66
|
+
"-e",
|
67
|
+
"--environment-file",
|
68
|
+
required=False,
|
69
|
+
help="The full path to an environment file (.env file).",
|
70
|
+
)
|
71
|
+
|
72
|
+
self.username: str | None = None
|
73
|
+
self.password: str | None = None
|
74
|
+
self.api_domain: str | None = None
|
75
|
+
self.cognito_client_id: str | None = None
|
76
|
+
self.aws_region: str | None = None
|
77
|
+
|
78
|
+
self.config_file: str | None = None
|
79
|
+
self.config_file_default: str | None = None
|
80
|
+
self.analysis_file: str | None = None
|
81
|
+
self.analysis_file_default: str | None = None
|
82
|
+
self.metadata_file: str | None = None
|
83
|
+
self.metadata_file_default: str | None = None
|
84
|
+
self.skip: bool = False
|
85
|
+
self.output_directory: str | None = None
|
86
|
+
self.output_directory_default: str = ".output"
|
87
|
+
self.environment_file: str | None = None
|
88
|
+
|
89
|
+
self.display_directions: bool = True
|
90
|
+
|
91
|
+
def is_valid(self) -> bool:
|
92
|
+
"""
|
93
|
+
Validates and Prompts the user if needed
|
94
|
+
Returns:
|
95
|
+
bool: True if they are all valid
|
96
|
+
"""
|
97
|
+
# see if we have any aruments
|
98
|
+
args = self.parser.parse_args()
|
99
|
+
|
100
|
+
self.username = args.username
|
101
|
+
self.password = args.password
|
102
|
+
self.config_file = args.config_file
|
103
|
+
# anything with a dash (in the args) is accessed with an underscore
|
104
|
+
self.analysis_file = args.analyis_file
|
105
|
+
self.api_domain = args.api_domain
|
106
|
+
self.cognito_client_id = args.client_id
|
107
|
+
self.aws_region = args.region
|
108
|
+
self.metadata_file = args.metadata_file
|
109
|
+
self.skip = args.skip
|
110
|
+
self.output_directory = args.output_directory
|
111
|
+
self.environment_file = args.environment_file
|
112
|
+
# no args check to see if they have them in the environmet
|
113
|
+
|
114
|
+
# if we have an environment file we'll want to load it before checking any defaults
|
115
|
+
self.check_for_environment_config()
|
116
|
+
|
117
|
+
env = EnvironmentVars()
|
118
|
+
|
119
|
+
if not self.username:
|
120
|
+
if self.skip and env.username:
|
121
|
+
self.username = env.username
|
122
|
+
else:
|
123
|
+
self.username = self.prompt_for_input("username", env.username)
|
124
|
+
if not self.password:
|
125
|
+
if self.skip and env.password:
|
126
|
+
self.password = env.password
|
127
|
+
else:
|
128
|
+
self.password = self.prompt_for_input(
|
129
|
+
"password", env.password, is_sensitive=True
|
130
|
+
)
|
131
|
+
if not self.aws_region:
|
132
|
+
if self.skip and env.aws_region:
|
133
|
+
self.aws_region = env.aws_region
|
134
|
+
else:
|
135
|
+
self.aws_region = self.prompt_for_input("AWS Region", env.aws_region)
|
136
|
+
if not self.api_domain:
|
137
|
+
if self.skip and env.api_domain:
|
138
|
+
self.api_domain = env.api_domain
|
139
|
+
else:
|
140
|
+
self.api_domain = self.prompt_for_input("Api Domain", env.api_domain)
|
141
|
+
|
142
|
+
if not self.cognito_client_id:
|
143
|
+
if self.skip and env.client_id:
|
144
|
+
self.cognito_client_id = env.client_id
|
145
|
+
else:
|
146
|
+
self.cognito_client_id = self.prompt_for_input(
|
147
|
+
"Cognito Client Id", env.client_id
|
148
|
+
)
|
149
|
+
|
150
|
+
if not self.analysis_file:
|
151
|
+
if self.skip and self.analysis_file_default or env.analysis_file:
|
152
|
+
self.analysis_file = self.analysis_file_default or env.analysis_file
|
153
|
+
else:
|
154
|
+
self.analysis_file = self.prompt_for_input(
|
155
|
+
"Analysis File", self.analysis_file_default or env.analysis_file
|
156
|
+
)
|
157
|
+
|
158
|
+
if not self.config_file:
|
159
|
+
if self.skip and self.config_file_default or env.config_file:
|
160
|
+
self.config_file = self.config_file_default or env.config_file
|
161
|
+
else:
|
162
|
+
self.config_file = self.prompt_for_input(
|
163
|
+
"Configuration File", self.config_file_default or env.config_file
|
164
|
+
)
|
165
|
+
|
166
|
+
if not self.metadata_file:
|
167
|
+
if self.skip and self.metadata_file_default or env.metadata_file:
|
168
|
+
self.metadata_file = self.metadata_file_default or env.metadata_file
|
169
|
+
else:
|
170
|
+
self.metadata_file = self.prompt_for_input(
|
171
|
+
"MetaData File",
|
172
|
+
self.metadata_file_default or env.metadata_file,
|
173
|
+
required=False,
|
174
|
+
)
|
175
|
+
if not self.output_directory:
|
176
|
+
if self.skip:
|
177
|
+
self.output_directory = self.output_directory_default
|
178
|
+
else:
|
179
|
+
self.output_directory = self.prompt_for_input(
|
180
|
+
"Output directory (the full path)",
|
181
|
+
self.output_directory_default,
|
182
|
+
required=False,
|
183
|
+
)
|
184
|
+
|
185
|
+
# do we have everything we need?
|
186
|
+
|
187
|
+
return self.__check_all_required()
|
188
|
+
|
189
|
+
def __check_all_required(self) -> bool:
|
190
|
+
"""
|
191
|
+
Check to see if all the fields are required
|
192
|
+
Returns:
|
193
|
+
bool: True if all required fields are populated, otherwise false
|
194
|
+
"""
|
195
|
+
# basically everything except metadata
|
196
|
+
required_fields = [
|
197
|
+
self.username,
|
198
|
+
self.password,
|
199
|
+
self.aws_region,
|
200
|
+
self.cognito_client_id,
|
201
|
+
self.analysis_file,
|
202
|
+
self.config_file,
|
203
|
+
self.api_domain,
|
204
|
+
]
|
205
|
+
for field in required_fields:
|
206
|
+
if not field:
|
207
|
+
return False
|
208
|
+
|
209
|
+
return True
|
210
|
+
|
211
|
+
def prompt_for_input(
|
212
|
+
self,
|
213
|
+
prompt: str,
|
214
|
+
default: str | None = None,
|
215
|
+
is_sensitive: bool = False,
|
216
|
+
required: bool = True,
|
217
|
+
) -> str | None:
|
218
|
+
"""
|
219
|
+
Create a prompt to display
|
220
|
+
Args:
|
221
|
+
prompt (str): The Prompt
|
222
|
+
default (str | None, optional): Default Value. Defaults to None.
|
223
|
+
is_sensitive (bool, optional): If the data is sensitive it won't be displayed on the screen. Defaults to False.
|
224
|
+
required (bool, optional): If the field is required. Defaults to True.
|
225
|
+
|
226
|
+
Returns:
|
227
|
+
str | None: The result of the prompt
|
228
|
+
"""
|
229
|
+
# Construct the prompt message to include the default option if provided
|
230
|
+
if self.display_directions:
|
231
|
+
self.display_directions = False
|
232
|
+
print("Hit enter if you wish to accept a default value (if available)")
|
233
|
+
print("")
|
234
|
+
default_display = default if not is_sensitive else "************"
|
235
|
+
required_display = " - Required" if required else " - Optional"
|
236
|
+
|
237
|
+
display = (
|
238
|
+
f" [{default_display}]: "
|
239
|
+
if default
|
240
|
+
else f" [No Default{required_display}]: "
|
241
|
+
)
|
242
|
+
user_input: str | None = None
|
243
|
+
if is_sensitive:
|
244
|
+
user_input = getpass.getpass(f"{prompt}{display}")
|
245
|
+
else:
|
246
|
+
prompt_message = f"{prompt}{display}"
|
247
|
+
|
248
|
+
# Get user input
|
249
|
+
user_input = input(prompt_message)
|
250
|
+
|
251
|
+
# Return the user input if not empty, otherwise return the default value
|
252
|
+
user_input = user_input if user_input else default
|
253
|
+
|
254
|
+
if not user_input and required:
|
255
|
+
return self.prompt_for_input(
|
256
|
+
prompt=prompt,
|
257
|
+
default=default,
|
258
|
+
is_sensitive=is_sensitive,
|
259
|
+
required=required,
|
260
|
+
)
|
261
|
+
|
262
|
+
return user_input
|
263
|
+
|
264
|
+
def find_file(
|
265
|
+
self, starting_path: str, file_name: str, raise_error_if_not_found: bool = True
|
266
|
+
) -> str | None:
|
267
|
+
"""Searches the project directory structor for a file"""
|
268
|
+
parents = 10
|
269
|
+
starting_path = starting_path or __file__
|
270
|
+
|
271
|
+
paths: List[str] = []
|
272
|
+
for parent in range(parents):
|
273
|
+
path = Path(starting_path).parents[parent].absolute()
|
274
|
+
|
275
|
+
tmp = os.path.join(path, file_name)
|
276
|
+
paths.append(tmp)
|
277
|
+
if os.path.exists(tmp):
|
278
|
+
return tmp
|
279
|
+
|
280
|
+
if raise_error_if_not_found:
|
281
|
+
searched_paths = "\n".join(paths)
|
282
|
+
raise RuntimeError(
|
283
|
+
f"Failed to locate environment file: {file_name} in: \n {searched_paths}"
|
284
|
+
)
|
285
|
+
|
286
|
+
return None
|
287
|
+
|
288
|
+
def check_for_environment_config(self):
|
289
|
+
"""Attempts to load an environment file"""
|
290
|
+
if not self.environment_file:
|
291
|
+
return # Exit early if no environment file is provided
|
292
|
+
|
293
|
+
env_file_path = Path(self.environment_file)
|
294
|
+
|
295
|
+
if not env_file_path.exists():
|
296
|
+
# Try to find the file
|
297
|
+
file = self.find_file(__file__, env_file_path.name)
|
298
|
+
file_path = Path(str(file))
|
299
|
+
|
300
|
+
if not file_path.exists():
|
301
|
+
print("\n\nAn environment file was provided but it doesn't exist.")
|
302
|
+
print(f"\tFile provided: {self.environment_file}")
|
303
|
+
exit()
|
304
|
+
else:
|
305
|
+
self.environment_file = str(file_path)
|
306
|
+
|
307
|
+
load_dotenv(dotenv_path=self.environment_file, override=True)
|
308
|
+
|
309
|
+
|
310
|
+
def main():
|
311
|
+
args = CommandlineArgs()
|
312
|
+
|
313
|
+
if args.is_valid():
|
314
|
+
pwd = "************" if args.password else "empty"
|
315
|
+
print(f"username = {args.username}")
|
316
|
+
print(f"password = {pwd}")
|
317
|
+
print(f"aws_region = {args.aws_region}")
|
318
|
+
print(f"api_domain = {args.api_domain}")
|
319
|
+
print(f"cognito_client_id = {args.cognito_client_id}")
|
320
|
+
print(f"config_file = {args.config_file}")
|
321
|
+
print(f"metadata_file = {args.metadata_file}")
|
322
|
+
print(f"analysis_file = {args.analysis_file}")
|
323
|
+
print(f"output_directory = {args.output_directory}")
|
324
|
+
|
325
|
+
print("were good to go")
|
326
|
+
|
327
|
+
else:
|
328
|
+
print("Missing some required fields.")
|
329
|
+
|
330
|
+
|
331
|
+
if __name__ == "__main__":
|
332
|
+
main()
|
@@ -0,0 +1,81 @@
|
|
1
|
+
"""
|
2
|
+
Aplos Analytics
|
3
|
+
|
4
|
+
"""
|
5
|
+
|
6
|
+
import os
|
7
|
+
import json
|
8
|
+
from typing import Dict, List, Any
|
9
|
+
from pathlib import Path
|
10
|
+
from dotenv import load_dotenv
|
11
|
+
|
12
|
+
|
13
|
+
class EnvironmentServices:
|
14
|
+
"""Environment Services"""
|
15
|
+
|
16
|
+
def load_environment(
|
17
|
+
self,
|
18
|
+
*,
|
19
|
+
starting_path: str | None = None,
|
20
|
+
file_name: str = ".env.dev",
|
21
|
+
override_vars: bool = True,
|
22
|
+
raise_error_if_not_found: bool = True,
|
23
|
+
):
|
24
|
+
"""Loads the local environment"""
|
25
|
+
|
26
|
+
if not starting_path:
|
27
|
+
starting_path = __file__
|
28
|
+
|
29
|
+
environment_file: str | None = self.find_file(
|
30
|
+
starting_path=starting_path,
|
31
|
+
file_name=file_name,
|
32
|
+
raise_error_if_not_found=raise_error_if_not_found,
|
33
|
+
)
|
34
|
+
|
35
|
+
if environment_file:
|
36
|
+
load_dotenv(dotenv_path=environment_file, override=override_vars)
|
37
|
+
|
38
|
+
def load_event_file(self, full_path: str) -> Dict[str, Any]:
|
39
|
+
"""Loads an event file"""
|
40
|
+
if not os.path.exists(full_path):
|
41
|
+
raise RuntimeError(f"Failed to locate event file: {full_path}")
|
42
|
+
|
43
|
+
event: Dict = {}
|
44
|
+
with open(full_path, mode="r", encoding="utf-8") as json_file:
|
45
|
+
event = json.load(json_file)
|
46
|
+
|
47
|
+
if "message" in event:
|
48
|
+
tmp = event.get("message")
|
49
|
+
if isinstance(tmp, Dict):
|
50
|
+
event = tmp
|
51
|
+
|
52
|
+
if "event" in event:
|
53
|
+
tmp = event.get("event")
|
54
|
+
if isinstance(tmp, Dict):
|
55
|
+
event = tmp
|
56
|
+
|
57
|
+
return event
|
58
|
+
|
59
|
+
def find_file(
|
60
|
+
self, starting_path: str, file_name: str, raise_error_if_not_found: bool = True
|
61
|
+
) -> str | None:
|
62
|
+
"""Searches the project directory structor for a file"""
|
63
|
+
parents = 10
|
64
|
+
starting_path = starting_path or __file__
|
65
|
+
|
66
|
+
paths: List[str] = []
|
67
|
+
for parent in range(parents):
|
68
|
+
path = Path(starting_path).parents[parent].absolute()
|
69
|
+
|
70
|
+
tmp = os.path.join(path, file_name)
|
71
|
+
paths.append(tmp)
|
72
|
+
if os.path.exists(tmp):
|
73
|
+
return tmp
|
74
|
+
|
75
|
+
if raise_error_if_not_found:
|
76
|
+
searched_paths = "\n".join(paths)
|
77
|
+
raise RuntimeError(
|
78
|
+
f"Failed to locate environment file: {file_name} in: \n {searched_paths}"
|
79
|
+
)
|
80
|
+
|
81
|
+
return None
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
|
4
|
+
class EnvironmentVars:
|
5
|
+
"""Loading Environment Vars or replace them with runtime values"""
|
6
|
+
|
7
|
+
def __init__(self) -> None:
|
8
|
+
# load defaults
|
9
|
+
self.api_domain = os.getenv("APLOS_API_DOMAIN")
|
10
|
+
|
11
|
+
self.aws_region = os.getenv("COGNITO_REGION")
|
12
|
+
self.client_id = os.getenv("COGNITO_CLIENT_ID")
|
13
|
+
self.username = os.getenv("COGNITO_USER_NAME")
|
14
|
+
self.password = os.getenv("COGNITO_PASSWORD")
|
15
|
+
|
16
|
+
self.config_file = os.getenv("CONFIG_FILE")
|
17
|
+
self.metadata_file = os.getenv("METADATA_FILE")
|
18
|
+
self.analysis_file = os.getenv("ANALYSIS_FILE")
|
19
|
+
|
20
|
+
if "https://" in self.api_domain:
|
21
|
+
self.api_domain = self.api_domain.replace("https://", "")
|
22
|
+
|
23
|
+
self.aplos_api_url = f"https://{self.api_domain}"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Routes:
|
2
|
+
"""NCA Saas Routes"""
|
3
|
+
|
4
|
+
NCA_EXECUTIONS = "nca/executions"
|
5
|
+
NCA_GENERATE_UPLOAD = "nca/files"
|
6
|
+
|
7
|
+
|
8
|
+
class HttpUtilities:
|
9
|
+
"""Http Utilties"""
|
10
|
+
|
11
|
+
@staticmethod
|
12
|
+
def build_url(domain_name: str) -> str:
|
13
|
+
"""Build the url"""
|
14
|
+
domain_name = domain_name.strip()
|
15
|
+
if domain_name.startswith("http"):
|
16
|
+
return domain_name
|
17
|
+
else:
|
18
|
+
return f"https://{domain_name}"
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def get_headers(jwt: str) -> dict:
|
22
|
+
"""Get the Http Headers"""
|
23
|
+
headers = {
|
24
|
+
"Content-Type": "application/json",
|
25
|
+
}
|
26
|
+
|
27
|
+
if jwt:
|
28
|
+
headers["Authorization"] = f"Bearer {jwt}"
|
29
|
+
|
30
|
+
return headers
|
@@ -0,0 +1,195 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: aplos_nca_saas_sdk
|
3
|
+
Version: 1.0.0
|
4
|
+
Summary: Aplos NCA SaaS SDK
|
5
|
+
Author-email: Eric Wilson <eric.wilson@aplosanalytics.com>
|
6
|
+
Classifier: License :: Other/Proprietary License
|
7
|
+
Classifier: Operating System :: OS Independent
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Requires-Python: >=3.10
|
10
|
+
Requires-Dist: aws-lambda-powertools==2.38.1
|
11
|
+
Requires-Dist: boto3==1.34.110
|
12
|
+
Requires-Dist: pyjwt==2.9.0
|
13
|
+
Requires-Dist: python-dotenv==1.0.1
|
14
|
+
Requires-Dist: requests==2.31.0
|
15
|
+
Description-Content-Type: text/markdown
|
16
|
+
|
17
|
+
# Aplos NCA SaaS SDK for python
|
18
|
+
|
19
|
+
You can use 🐍 python to perform analysis with Aplos NCA using API calls via secure HTTPS requests. We have prepared sample scripts to illustrate how this analysis can be performed using python.
|
20
|
+
|
21
|
+
This was created as a reusable library which was wrapped with commandline parsing. You can use command line switches or simply run it and get prompted for the required input.
|
22
|
+
|
23
|
+
All the source code can be downloaded from our [docs repo](https://github.com/AplosAnalytics/docs.aplosanalytics.com/tree/main/docs/samples/python/aplos_nca).
|
24
|
+
|
25
|
+
>[!TIP] We use this for our demos
|
26
|
+
> We'll keep this maintained as we use it for our customer demos. So keep coming back for new features.
|
27
|
+
|
28
|
+
|
29
|
+
## API Settings
|
30
|
+
|
31
|
+
> [!WARNING] A valid Aplos NCA Account is required.
|
32
|
+
> In order to run the executions and connect to our system, you will need a valid account with an active subscription.
|
33
|
+
>
|
34
|
+
> You'll need your username (email address and a password) a Cognito Client Id
|
35
|
+
> which allows the USER_PASSWORD_AUTH flow, and your API URL.
|
36
|
+
>
|
37
|
+
> The Client Id (aka Cognito Client Key) and API URL can be found in your user account.
|
38
|
+
> Your username is your email address and your password would have been provided to you during your
|
39
|
+
> onboarding or with a "forgot password" request and reset.
|
40
|
+
|
41
|
+
### Access your settings from the UI
|
42
|
+

|
43
|
+
|
44
|
+
|
45
|
+
## Python Environment
|
46
|
+
While it's not required, we suggest setting up a virtual environment with your favorite tool.
|
47
|
+
|
48
|
+
Example. From the project root issue the following command (in mac, linux or windows shell subsystem)
|
49
|
+
```shell
|
50
|
+
python -m venv .venv
|
51
|
+
source ./.venv/bin/activate
|
52
|
+
```
|
53
|
+
|
54
|
+
Install the required packages
|
55
|
+
```shell
|
56
|
+
# (from the project root)
|
57
|
+
pip install -r ./docs/samples/python/aplos_nca/requirements.txt
|
58
|
+
|
59
|
+
# or if you are in the aplos_nca directory
|
60
|
+
pip install -r ./requirements.txt
|
61
|
+
```
|
62
|
+
|
63
|
+
|
64
|
+
## Required Files for execution (analysis submission)
|
65
|
+
To submit something for an analysis, you will need 2 required files and one optional file.
|
66
|
+
- Input File (analysis file)
|
67
|
+
- Configuration File (configurations on how to run the analysis)
|
68
|
+
- Meta Data (optional)
|
69
|
+
|
70
|
+
Technically only the analysis file is submitted as a file.
|
71
|
+
|
72
|
+
The other two (configuration and metadata) are submitted as JSON/dictionary objects. However to make things easier for this demo they are stored as files, then read in at runtime and submitted in their normal dictionary form.
|
73
|
+
|
74
|
+
The files are located `./files` directory of this demo project (`./samples/python/aplos_nca`).
|
75
|
+
|
76
|
+
|
77
|
+
## Outputs
|
78
|
+
Currently, we are outputting the files in a hidden directory (`.output`) which is also excluded from the git commits. This can easily be overridden to your choosing.
|
79
|
+
|
80
|
+
Located in `./.output`
|
81
|
+
|
82
|
+
|
83
|
+
## Run the Execution
|
84
|
+
|
85
|
+
In order to run the execution you need to either:
|
86
|
+
- Add environment variables for the required parameter see [Environment Vars](/docs/samples/python-overview.html#environment-vars) later in this document
|
87
|
+
- Use the command switch arguments
|
88
|
+
- Or simply input the values as you are prompted.
|
89
|
+
|
90
|
+
> [!TIP] Tip! Use environment vars and override when needed.
|
91
|
+
> You can set the environment variables, but still override them during the prompts
|
92
|
+
|
93
|
+
From the project you you can
|
94
|
+
`python .<project-path>/main.py`
|
95
|
+
|
96
|
+
or navigate to the folder
|
97
|
+
`python ./main.py`
|
98
|
+
|
99
|
+
## Arguments
|
100
|
+
|
101
|
+
|short|long|description|
|
102
|
+
|---|---|---|
|
103
|
+
|-s|--skip|Skip prompts if required values have defaults|
|
104
|
+
|-u|--username|Your login username|
|
105
|
+
|-p|--password|Your login password|
|
106
|
+
|-f|--analyis-file|Path to the analysis file|
|
107
|
+
|-c|--config-file|Path to the configuration file|
|
108
|
+
|-m|--metadata-file|Path to the metadata file|
|
109
|
+
|-a|--api-url|The api url|
|
110
|
+
|-i|--client-id|The client id to cognito|
|
111
|
+
|-o|-output-directory|The full path to an output directory. If one isn't provided it will default to a local (.aplos-nca-output) directory one level up from the execution directory. |
|
112
|
+
|-e|--environment-file|The full path to an environment file (.env file).|
|
113
|
+
|
114
|
+
### The `-s` argument (skipping prompts when defaults are available)
|
115
|
+
If you have default values specified in code or a `.env` file, specify the `-s` will skip prompting for any parameters that are required but have an associated matching default value.
|
116
|
+
|
117
|
+
|
118
|
+
### Scripting
|
119
|
+
You can create scripts to launch several analyses by providing the runtime arguments. WARNING: you should be careful when exposing your username and password to others.
|
120
|
+
For automation, it's best to store them as a secret and retrieve the secret at runtime.
|
121
|
+
|
122
|
+
|
123
|
+
## Examples:
|
124
|
+
Let's assume you have your username, password, and API settings in environment vars. You can use the `-s` to skip those prompts and supply the config, meta, and analysis for different runs.
|
125
|
+
|
126
|
+
> [!TIP]
|
127
|
+
> If you have certain values present the command line tool will prompt to see if you want to use the defaults or override them.
|
128
|
+
> If you want to skip the prompt, use `-s` as an argument. This will skip the prompt for any value already set.
|
129
|
+
|
130
|
+
### Sample execution
|
131
|
+
|
132
|
+
If your username, password, client key and API URL are already set, then the only thing you need to do on each run is supply the configuration and the analysis file. The meta-data file is optional. Issuing the `-s` will skip all the extra prompts.
|
133
|
+
|
134
|
+
```shell
|
135
|
+
# single line execution example
|
136
|
+
|
137
|
+
python main.py -s -c <config-file> -f <analysis-file> -m <meta-file>
|
138
|
+
|
139
|
+
```
|
140
|
+
|
141
|
+
### Same example, on multiple lines and with example files
|
142
|
+
|
143
|
+
```shell
|
144
|
+
|
145
|
+
# break into multiple lines for easier readability
|
146
|
+
# NOTE: a copy paste of this from code samples doesn't always work right
|
147
|
+
|
148
|
+
python ./main.py \
|
149
|
+
-s \
|
150
|
+
-f ./files/single_ev.csv \
|
151
|
+
-c ./files/configuration_single_ev.json \
|
152
|
+
-m ./files/meta_data.json
|
153
|
+
|
154
|
+
```
|
155
|
+
|
156
|
+
## Environment Vars
|
157
|
+
|
158
|
+
To save time and typing you can use environment variables to "pre-load" your execution and then any "unknown" value will be asked by the command line utility.
|
159
|
+
|
160
|
+
The following environment variables are required for execution. We're using environment vars so that nothing gets accidentally saved into git.
|
161
|
+
|
162
|
+
If executing the functions via the command line, you need to create the environment variables so that they are available at runtime, like the following.
|
163
|
+
|
164
|
+
Mac & Linux
|
165
|
+
```shell
|
166
|
+
export APLOS_API_DOMAIN="<api-gateway-url>"
|
167
|
+
export COGNITO_CLIENT_ID="<client-id>"
|
168
|
+
export COGNITO_USER_NAME="<email-address>"
|
169
|
+
export COGNITO_PASSWORD="<password>"
|
170
|
+
export COGNITO_REGION="<region>"
|
171
|
+
```
|
172
|
+
Windows
|
173
|
+
```shell
|
174
|
+
SET APLOS_API_DOMAIN="<api-gateway-url>"
|
175
|
+
SET COGNITO_CLIENT_ID="<client-id>"
|
176
|
+
SET COGNITO_USER_NAME="<email-address>"
|
177
|
+
SET COGNITO_PASSWORD="<password>"
|
178
|
+
SET COGNITO_REGION="<region>"
|
179
|
+
```
|
180
|
+
|
181
|
+
> [!TIP]
|
182
|
+
> You can also create a `.env` file locally and enter the environment vars there.
|
183
|
+
|
184
|
+
```shell
|
185
|
+
APLOS_API_DOMAIN="<api-gateway-url>"
|
186
|
+
COGNITO_CLIENT_ID="<client-id>"
|
187
|
+
COGNITO_USER_NAME="<email-address>"
|
188
|
+
COGNITO_PASSWORD="<password>"
|
189
|
+
COGNITO_REGION="<region>"
|
190
|
+
```
|
191
|
+
|
192
|
+
## The Command Line in Action
|
193
|
+
In this example, I have all my settings preloaded in environment vars and I just hit enter several times to accept the defaults.
|
194
|
+
|
195
|
+

|