aplos-nca-saas-sdk 0.0.12__py3-none-any.whl → 0.0.14__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.
Files changed (44) hide show
  1. aplos_nca_saas_sdk/integration_testing/configs/_config_base.py +7 -2
  2. aplos_nca_saas_sdk/integration_testing/configs/app_settings_config.py +36 -36
  3. aplos_nca_saas_sdk/integration_testing/configs/config_sample.json +10 -10
  4. aplos_nca_saas_sdk/integration_testing/configs/file_upload_config.py +1 -1
  5. aplos_nca_saas_sdk/integration_testing/configs/login_config.py +15 -14
  6. aplos_nca_saas_sdk/integration_testing/configs/nca_execution_config.py +1 -1
  7. aplos_nca_saas_sdk/integration_testing/integration_test_base.py +2 -2
  8. aplos_nca_saas_sdk/integration_testing/integration_test_configurations.py +9 -5
  9. aplos_nca_saas_sdk/integration_testing/integration_test_factory.py +1 -1
  10. aplos_nca_saas_sdk/integration_testing/integration_test_response.py +1 -1
  11. aplos_nca_saas_sdk/integration_testing/integration_test_suite.py +10 -3
  12. aplos_nca_saas_sdk/integration_testing/main.py +9 -8
  13. aplos_nca_saas_sdk/integration_testing/readme.md +1 -1
  14. aplos_nca_saas_sdk/integration_testing/tests/app_configuration_test.py +4 -4
  15. aplos_nca_saas_sdk/integration_testing/tests/app_login_test.py +3 -3
  16. aplos_nca_saas_sdk/integration_testing/tests/file_upload_test.py +40 -91
  17. aplos_nca_saas_sdk/integration_testing/tests/nca_analysis_test.py +2 -2
  18. aplos_nca_saas_sdk/integration_testing/tests/validation_test.py +1 -1
  19. aplos_nca_saas_sdk/nca_resources/_api_base.py +44 -0
  20. aplos_nca_saas_sdk/{aws_resources → nca_resources}/aws_cognito.py +2 -2
  21. aplos_nca_saas_sdk/{aws_resources → nca_resources}/aws_s3_presigned_payload.py +3 -3
  22. aplos_nca_saas_sdk/{aws_resources → nca_resources}/aws_s3_presigned_upload.py +28 -22
  23. aplos_nca_saas_sdk/nca_resources/nca_analysis.py +23 -167
  24. aplos_nca_saas_sdk/nca_resources/nca_app_configuration.py +4 -4
  25. aplos_nca_saas_sdk/nca_resources/{nca_login.py → nca_authenticator.py} +23 -20
  26. aplos_nca_saas_sdk/nca_resources/nca_endpoints.py +56 -30
  27. aplos_nca_saas_sdk/nca_resources/nca_file_download.py +130 -0
  28. aplos_nca_saas_sdk/nca_resources/nca_file_upload.py +27 -29
  29. aplos_nca_saas_sdk/nca_resources/nca_validations.py +34 -0
  30. aplos_nca_saas_sdk/run_analysis_execution.py +148 -0
  31. aplos_nca_saas_sdk/utilities/commandline_args.py +29 -13
  32. aplos_nca_saas_sdk/utilities/environment_services.py +3 -2
  33. aplos_nca_saas_sdk/utilities/environment_vars.py +10 -4
  34. aplos_nca_saas_sdk/utilities/file_utility.py +1 -1
  35. aplos_nca_saas_sdk/utilities/http_utility.py +1 -26
  36. aplos_nca_saas_sdk/version.py +1 -1
  37. {aplos_nca_saas_sdk-0.0.12.dist-info → aplos_nca_saas_sdk-0.0.14.dist-info}/METADATA +1 -1
  38. aplos_nca_saas_sdk-0.0.14.dist-info/RECORD +51 -0
  39. {aplos_nca_saas_sdk-0.0.12.dist-info → aplos_nca_saas_sdk-0.0.14.dist-info}/licenses/LICENSE +1 -1
  40. aplos_nca_saas_sdk-0.0.12.dist-info/RECORD +0 -47
  41. /aplos_nca_saas_sdk/{files/analysis_files/single_ev/configuration_single_ev.json → sample_files/analysis_files/single_ev/config.json} +0 -0
  42. /aplos_nca_saas_sdk/{files/analysis_files/single_ev/single_ev.csv → sample_files/analysis_files/single_ev/input.csv} +0 -0
  43. /aplos_nca_saas_sdk/{files → sample_files}/analysis_files/single_ev/meta_data.json +0 -0
  44. {aplos_nca_saas_sdk-0.0.12.dist-info → aplos_nca_saas_sdk-0.0.14.dist-info}/WHEEL +0 -0
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -18,8 +18,12 @@ from aplos_nca_saas_sdk.integration_testing.integration_test_response import (
18
18
  IntegrationTestResponse,
19
19
  )
20
20
  from aplos_nca_saas_sdk.nca_resources.nca_file_upload import NCAFileUpload
21
- from aplos_nca_saas_sdk.nca_resources.nca_login import NCALogin
21
+ from aplos_nca_saas_sdk.nca_resources.nca_file_download import NCAFileDownload
22
+ from aplos_nca_saas_sdk.nca_resources.nca_authenticator import NCAAuthenticator
22
23
  from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities
24
+ from aplos_nca_saas_sdk.integration_testing.configs.file_upload_config import (
25
+ FileUploadConfig,
26
+ )
23
27
 
24
28
  logger = Logger()
25
29
 
@@ -35,31 +39,30 @@ class FileUploadTest(IntegrationTestBase):
35
39
 
36
40
  self.results.clear()
37
41
 
42
+ file_upload: FileUploadConfig
38
43
  for file_upload in self.config.file_uploads.list:
39
44
  test_response: IntegrationTestResponse = IntegrationTestResponse()
40
45
  test_response.name = self.name
41
46
  try:
42
47
  # Confirm Login
43
48
  nca_login = self.__login(file_upload.login)
44
- if not nca_login.jwt:
45
- test_response.error = "Failed to authenticate"
49
+ # if not nca_login.cognito.jwt:
50
+ # test_response.error = "Failed to authenticate"
51
+ # else:
52
+ # Confirm Upload
53
+ upload_response: Dict[str, Any] = self.__upload(
54
+ nca_login, file_upload.file_path
55
+ )
56
+ if upload_response is None:
57
+ test_response.error = "Failed to upload"
46
58
  else:
47
- # Confirm Upload
48
- upload_response: Dict[str, Any] = self.__upload(
49
- nca_login, file_upload.file_path
50
- )
51
- if upload_response is None:
52
- test_response.error = "Failed to upload"
53
- else:
54
- # Confirm conversion and download
55
- # Allow time buffer so file data is available
56
- file_id: str = upload_response.get("file_id", "")
57
- if not file_id:
58
- raise RuntimeError(
59
- "Failed to get a file_id from the upload"
60
- )
61
- time.sleep(3)
62
- self.__download(nca_login, file_id, test_response)
59
+ # Confirm conversion and download
60
+ # Allow time buffer so file data is available
61
+ file_id: str = upload_response.get("file_id", "")
62
+ if not file_id:
63
+ raise RuntimeError("Failed to get a file_id from the upload")
64
+ time.sleep(3)
65
+ self.__download(nca_login, file_id, test_response)
63
66
 
64
67
  except Exception as e: # pylint: disable=w0718
65
68
  test_response.error = str(e)
@@ -68,91 +71,37 @@ class FileUploadTest(IntegrationTestBase):
68
71
 
69
72
  return self.success()
70
73
 
71
- def __login(self, login: LoginConfig) -> NCALogin:
72
- nca_login = NCALogin(aplos_saas_domain=login.domain)
74
+ def __login(self, login: LoginConfig) -> NCAAuthenticator:
75
+ nca_login = NCAAuthenticator(host=login.host)
73
76
  nca_login.authenticate(username=login.username, password=login.password)
74
77
  return nca_login
75
78
 
76
- def __upload(self, nca_login: NCALogin, upload_file_path: str) -> Dict[str, Any]:
79
+ def __upload(self, auth: NCAAuthenticator, upload_file_path: str) -> Dict[str, Any]:
77
80
  logger.info({"message": "Uploading file", "file_path": upload_file_path})
78
81
 
79
- nca_file_upload = NCAFileUpload(nca_login)
82
+ nca_file_upload = NCAFileUpload(auth.host)
83
+ nca_file_upload.authenticator = auth
80
84
  upload_response: Dict[str, Any] = nca_file_upload.upload(upload_file_path)
81
85
  return upload_response
82
86
 
83
87
  def __download(
84
88
  self,
85
- nca_login: NCALogin,
89
+ nca_login: NCAAuthenticator,
86
90
  file_id: str,
87
91
  test_response: IntegrationTestResponse,
88
92
  ):
89
93
  logger.info({"message": "Downloading file", "file_id": file_id})
90
- file_data_endpoint = nca_login.config.endpoints.file_data(
91
- nca_login.cognito.tenant_id,
92
- nca_login.cognito.user_id,
93
- file_id,
94
- )
95
- file_info_endpoint = nca_login.config.endpoints.file(
96
- nca_login.cognito.tenant_id,
97
- nca_login.cognito.user_id,
98
- file_id,
99
- )
100
-
101
- max_wait_in_minutes: int = 3
102
- headers = HttpUtilities.get_headers(nca_login.jwt)
103
- current_time = datetime.now()
104
-
105
- # Create a timedelta object representing 3 minutes
106
- time_delta = timedelta(minutes=max_wait_in_minutes)
107
- # Add the timedelta to the current time
108
- max_time = current_time + time_delta
109
-
110
- complete = False
111
- while not complete:
112
- response = requests.get(file_info_endpoint, headers=headers, timeout=60)
113
- json_response: dict = response.json()
114
- errors: List[Dict[str, Any]] = []
115
- errors.extend(json_response.get("errors") or [])
116
- status = json_response.get("workable_state")
117
- complete = status == "ready"
118
-
119
- if status == "invalid" or len(errors) > 0:
120
- test_response.success = False
121
- test_response.error = (
122
- "File conversion failed."
123
- if len(errors) < 0
124
- else f"File conversion failed with errors ${errors}."
125
- )
126
- break
127
- if complete:
128
- break
129
- if not complete:
130
- time.sleep(5)
131
- if datetime.now() > max_time:
132
- test_response.success = False
133
- test_response.error = (
134
- "Timeout attempting to get conversion file status. "
135
- f"The current timeout limit is {max_wait_in_minutes} minutes. "
136
- "You may need to up the timeout period, or check for errors. "
137
- )
138
- break
139
-
140
- if test_response.error is not None:
141
- return
94
+ downloader: NCAFileDownload = NCAFileDownload(nca_login.host)
95
+ downloader.authenticator = nca_login
96
+ response = downloader.download(file_id)
142
97
 
143
- file_response = requests.get(file_data_endpoint, headers=headers, timeout=30)
144
-
145
- json_file_response: dict = file_response.json()
146
- data = json_file_response.get("data", None)
147
- error = json_file_response.get("error", None)
148
-
149
- if data is None:
98
+ status = response.get("workable_state")
99
+ if status != "ready":
150
100
  test_response.success = False
151
- test_response.error = "File download missing expected data. "
152
- if error is not None:
153
- test_response.success = False
154
- test_response.error = (
155
- test_response.error or ""
156
- ) + f"File download contained error ${error}"
101
+ test_response.error = f"File conversion failed. Status: {status}"
102
+ else:
103
+ test_response.success = True
104
+
105
+ test_response.response = response
157
106
 
158
- test_response.success = True
107
+ return response
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -48,7 +48,7 @@ class NCAAnalysisTest(IntegrationTestBase):
48
48
  try:
49
49
  # Create new NCA Execution
50
50
  nca_execution: NCAAnalysis = NCAAnalysis(
51
- nca_execution_config.login.domain
51
+ nca_execution_config.login.host
52
52
  )
53
53
 
54
54
  # Initialize Configuration Data
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -0,0 +1,44 @@
1
+ """
2
+ Copyright 2024-2025 Aplos Analytics
3
+ All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
+ Property of Aplos Analytics, Utah, USA
5
+ """
6
+
7
+ from typing import Any
8
+
9
+
10
+ from aplos_nca_saas_sdk.nca_resources.nca_authenticator import NCAAuthenticator
11
+ from aplos_nca_saas_sdk.nca_resources.nca_endpoints import NCAEndpoints
12
+
13
+
14
+ class NCAApiBaseClass:
15
+ """NCA Api Base Class"""
16
+
17
+ def __init__(self, host: str) -> None:
18
+ self.host = host
19
+ self.__authenticator: NCAAuthenticator = NCAAuthenticator(host=host)
20
+ self.__endpoints: NCAEndpoints = NCAEndpoints(host=host)
21
+ if not host:
22
+ raise ValueError("Missing Aplos Api Domain")
23
+
24
+ @property
25
+ def authenticator(self) -> NCAAuthenticator:
26
+ """Gets the authenticator"""
27
+
28
+ return self.__authenticator
29
+
30
+ @authenticator.setter
31
+ def authenticator(self, value: Any) -> None:
32
+ """Sets the authenticator"""
33
+
34
+ self.__authenticator = value
35
+
36
+ @property
37
+ def endpoints(self) -> NCAEndpoints:
38
+ """Gets the endpoints"""
39
+
40
+ if self.authenticator.cognito.jwt:
41
+ self.__endpoints.tenant_id = self.authenticator.cognito.tenant_id
42
+ self.__endpoints.user_id = self.authenticator.cognito.user_id
43
+
44
+ return self.__endpoints
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -79,7 +79,7 @@ class CognitoAuthentication:
79
79
  - or the Aplos Domain (which can get the clientId and region)
80
80
  """
81
81
  if self.__client_id is None and self.__aplos_domain is not None:
82
- self.__config = NCAAppConfiguration(aplos_saas_domain=self.__aplos_domain)
82
+ self.__config = NCAAppConfiguration(host=self.__aplos_domain)
83
83
  self.__client_id = self.__config.cognito_client_id
84
84
  self.__region = self.__config.cognito_region
85
85
 
@@ -1,12 +1,12 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
6
6
 
7
7
 
8
- class S3PresignedPayload:
9
- """S3PresignedPayload"""
8
+ class S3PresignedUrlPayload:
9
+ """S3 Presigned Url Payload"""
10
10
 
11
11
  def __init__(self, payload: dict | None = None) -> None:
12
12
  self.url: str | None = None
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -9,20 +9,23 @@ import os
9
9
  from typing import Any, Dict
10
10
 
11
11
  import requests
12
- from aplos_nca_saas_sdk.aws_resources.aws_s3_presigned_payload import (
13
- S3PresignedPayload,
12
+ from aplos_nca_saas_sdk.nca_resources.aws_s3_presigned_payload import (
13
+ S3PresignedUrlPayload,
14
14
  )
15
- from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities, Routes
15
+ from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities
16
+ from aplos_nca_saas_sdk.nca_resources._api_base import NCAApiBaseClass
16
17
 
17
18
 
18
- class S3PresignedUpload:
19
- """S3PresignedUpload"""
19
+ class S3PresignedUrlUpload(NCAApiBaseClass):
20
+ """S3PresignedUrlUpload"""
20
21
 
21
- def __init__(self, jwt: str, api_url: str) -> None:
22
- self.api_url = api_url
23
- self.jwt = jwt
22
+ def __init__(self, host: str) -> None:
23
+ super().__init__(host)
24
24
 
25
- def upload_file(self, input_file: str) -> Dict[str, Any]:
25
+ def upload_file(
26
+ self,
27
+ input_file: str,
28
+ ) -> Dict[str, Any]:
26
29
  """
27
30
  Uploads a file to your Aplos Cloud Account in AWS
28
31
 
@@ -34,15 +37,17 @@ class S3PresignedUpload:
34
37
  """
35
38
 
36
39
  # get the presigned url for uploading
37
- paylod: S3PresignedPayload = self.__get_presigned_upload_info(
38
- input_file=input_file
40
+ paylod: S3PresignedUrlPayload = self.__get_presigned_upload_info(
41
+ input_file=input_file, jwt=self.authenticator.cognito.jwt
39
42
  )
40
43
  # upload the files
41
44
  upload_response = self.__upload_file_to_s3(paylod, input_file=input_file)
42
45
 
43
46
  return upload_response
44
47
 
45
- def __get_presigned_upload_info(self, input_file: str) -> S3PresignedPayload:
48
+ def __get_presigned_upload_info(
49
+ self, input_file: str, jwt: str
50
+ ) -> S3PresignedUrlPayload:
46
51
  """
47
52
  Performs all the necessary steps for creating a presigned url to upload a file to S3.
48
53
  We're using AWS S3 presigned urls for security as well as allowing for very large files if required.
@@ -50,11 +55,11 @@ class S3PresignedUpload:
50
55
  input_file (str): the path to the input (analysis) file
51
56
 
52
57
  Returns:
53
- S3PresignedPayload: instance of S3PresignedPayload
58
+ S3PresignedUrlPayload: instance of S3PresignedUrlPayload
54
59
  """
55
60
 
56
- url = f"{self.api_url}/{Routes.NCA_GENERATE_UPLOAD}"
57
- headers = HttpUtilities.get_headers(self.jwt)
61
+ url = self.endpoints.files
62
+ headers = HttpUtilities.get_headers(jwt)
58
63
 
59
64
  body = {"file_name": input_file, "method_type": "post"}
60
65
  response = requests.post(
@@ -64,29 +69,29 @@ class S3PresignedUpload:
64
69
  if response.status_code == 403:
65
70
  raise PermissionError(
66
71
  "Failed to get a presigned url. "
67
- f"Status Code: {response.status_code }"
72
+ f"Status Code: {response.status_code}"
68
73
  f"Reason: {response.reason} "
69
74
  f"403 Errors can also occur if you have an invalid path."
70
75
  )
71
76
  elif response.status_code != 200:
72
77
  raise RuntimeError(
73
78
  "Failed to get a presigned url. "
74
- f"Status Code: {response.status_code }"
79
+ f"Status Code: {response.status_code}"
75
80
  f"Reason: {response.reason}"
76
81
  )
77
82
  result = response.json()
78
83
 
79
- payload: S3PresignedPayload = S3PresignedPayload(result)
84
+ payload: S3PresignedUrlPayload = S3PresignedUrlPayload(result)
80
85
 
81
86
  return payload
82
87
 
83
88
  def __upload_file_to_s3(
84
- self, payload: S3PresignedPayload, input_file: str
89
+ self, payload: S3PresignedUrlPayload, input_file: str
85
90
  ) -> Dict[str, Any]:
86
91
  """
87
92
  Peforms the actual uploading via a presigned url for S3 bucket storage
88
93
  Args:
89
- payload (S3PresignedPayload): instance of S3PresignedPayload with all the data needed
94
+ payload (S3PresignedUrlPayload): instance of S3PresignedUrlPayload with all the data needed
90
95
  input_file (str): the path to a file being uploaded
91
96
 
92
97
  Raises:
@@ -104,8 +109,9 @@ class S3PresignedUpload:
104
109
  with open(input_file, "rb") as file:
105
110
  files = {"file": (input_file, file)}
106
111
  # upload to s3 with the presigned url
112
+ # authentication is built into the url
107
113
  upload_response = requests.post(
108
- str(payload.url), data=payload.form_data, files=files, timeout=30
114
+ str(payload.url), data=payload.form_data, files=files, timeout=60
109
115
  )
110
116
 
111
117
  # Check the response: 204 is a success in this case
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -11,61 +11,27 @@ import zipfile
11
11
  from datetime import datetime, timedelta
12
12
  from pathlib import Path
13
13
  from typing import Any, Dict
14
- from aws_lambda_powertools import Logger
14
+
15
15
  import requests
16
+ from aws_lambda_powertools import Logger
16
17
 
17
- from aplos_nca_saas_sdk.aws_resources.aws_cognito import CognitoAuthentication
18
- from aplos_nca_saas_sdk.aws_resources.aws_s3_presigned_upload import (
19
- S3PresignedUpload,
18
+ from aplos_nca_saas_sdk.nca_resources._api_base import NCAApiBaseClass
19
+ from aplos_nca_saas_sdk.nca_resources.aws_s3_presigned_upload import (
20
+ S3PresignedUrlUpload,
20
21
  )
21
- from aplos_nca_saas_sdk.utilities.commandline_args import CommandlineArgs
22
- from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities, Routes
23
22
  from aplos_nca_saas_sdk.utilities.environment_vars import EnvironmentVars
23
+ from aplos_nca_saas_sdk.utilities.http_utility import HttpUtilities
24
24
 
25
25
  logger = Logger()
26
26
 
27
27
 
28
- class NCAAnalysis:
29
- """NCA Analysis API Access"""
28
+ class NCAAnalysis(NCAApiBaseClass):
29
+ """NCA Analysis API"""
30
30
 
31
- def __init__(self, api_domain: str) -> None:
32
- self.__jwt: str
31
+ def __init__(self, host: str) -> None:
32
+ super().__init__(host)
33
33
 
34
- if not api_domain:
35
- raise ValueError("Missing Aplos Api Domain")
36
-
37
- self.__api_domain: str = api_domain
38
34
  self.verbose: bool = False
39
- self.__cognito: CognitoAuthentication | None = None
40
-
41
- @property
42
- def cognito(self) -> CognitoAuthentication:
43
- """Gets the cognito authentication object"""
44
-
45
- if not self.__api_domain:
46
- raise RuntimeError(
47
- "Missing Aplos Api Domain. Set the internal property of __api_domain first."
48
- "This is required to make an authentication connection"
49
- )
50
-
51
- if self.__cognito is None:
52
- self.__cognito = CognitoAuthentication(
53
- client_id=None, region=None, aplos_domain=self.__api_domain
54
- )
55
-
56
- return self.__cognito
57
-
58
- @property
59
- def api_root(self) -> str:
60
- """Gets the base url"""
61
- if self.__api_domain is None:
62
- raise RuntimeError("Missing Aplos Api Domain")
63
-
64
- url = HttpUtilities.build_url(
65
- self.__api_domain, self.cognito.tenant_id, self.cognito.user_id
66
- )
67
-
68
- return url
69
35
 
70
36
  def execute(
71
37
  self,
@@ -100,17 +66,13 @@ class NCAAnalysis:
100
66
  Dict[str, Any]: The execution response. If you wait for the completion
101
67
  """
102
68
 
103
- self.log(f"\tLogging into {self.__api_domain}.")
69
+ self.log(f"\tLogging into {self.host}.")
104
70
 
105
- if not username:
106
- raise ValueError("Missing username. Please provide a valid username.")
107
- if not password:
108
- raise ValueError("Missing password. Please provide a valid password.")
109
-
110
- self.__jwt = self.cognito.login(username=username, password=password)
71
+ self.authenticator.authenticate(username=username, password=password)
111
72
 
112
73
  self.log("\tUploading the analysis file.")
113
- uploader: S3PresignedUpload = S3PresignedUpload(self.__jwt, str(self.api_root))
74
+ uploader: S3PresignedUrlUpload = S3PresignedUrlUpload(str(self.host))
75
+ uploader.authenticator = self.authenticator
114
76
  upload_response: Dict[str, Any] = uploader.upload_file(input_file_path)
115
77
 
116
78
  file_id: str = upload_response.get("file_id", "")
@@ -188,7 +150,7 @@ class NCAAnalysis:
188
150
  raise ValueError(
189
151
  "Missing config_data. Please provide a valid config_data."
190
152
  )
191
- headers = HttpUtilities.get_headers(self.__jwt)
153
+ headers = HttpUtilities.get_headers(self.authenticator.cognito.jwt)
192
154
  # to start a new execution we need the location of the file (s3 bucket and object key)
193
155
  # you basic configuration
194
156
  # optional meta data
@@ -198,9 +160,12 @@ class NCAAnalysis:
198
160
  "configuration": config_data,
199
161
  "meta_data": meta_data,
200
162
  }
201
- url = f"{str(self.api_root)}/{Routes.NCA_EXECUTIONS}"
163
+
202
164
  response: requests.Response = requests.post(
203
- url, headers=headers, data=json.dumps(submission), timeout=30
165
+ self.endpoints.executions,
166
+ headers=headers,
167
+ data=json.dumps(submission),
168
+ timeout=30,
204
169
  )
205
170
  json_response: dict = response.json()
206
171
 
@@ -234,9 +199,9 @@ class NCAAnalysis:
234
199
  str | None: on success: a url for download, on failure: None
235
200
  """
236
201
 
237
- url = f"{self.api_root}/{Routes.NCA_EXECUTIONS}/{execution_id}"
202
+ url = f"{self.endpoints.execution(execution_id)}"
238
203
 
239
- headers = HttpUtilities.get_headers(self.__jwt)
204
+ headers = HttpUtilities.get_headers(self.authenticator.cognito.jwt)
240
205
  current_time = datetime.now()
241
206
  # Create a timedelta object representing 15 minutes
242
207
  time_delta = timedelta(seconds=max_wait_in_seconds)
@@ -337,112 +302,3 @@ class NCAAnalysis:
337
302
 
338
303
  if self.verbose:
339
304
  print(message)
340
-
341
-
342
- def main():
343
- try:
344
- print("Welcome to the NCA Engine Upload & Execution Demo")
345
- args = CommandlineArgs()
346
- files_path = os.path.join(Path(__file__).parent, "files")
347
-
348
- args.analysis_file_default = os.path.join(files_path, "single_ev.csv")
349
- args.config_file_default = os.path.join(
350
- files_path, "configuration_single_ev.json"
351
- )
352
- args.metadata_file_default = os.path.join(files_path, "meta_data.json")
353
- if not args.is_valid():
354
- print("\n\n")
355
- print("Missing some arguments.")
356
- exit()
357
-
358
- engine = NCAAnalysis(
359
- api_domain=str(args.api_domain),
360
- )
361
-
362
- print("\tLoading analysis configurations")
363
- print(f"\t\t{args.config_file}")
364
- config_data: dict = read_json_file(str(args.config_file))
365
-
366
- print("\tLoading analysis meta data")
367
- print(f"\t\t{args.metadata_file}")
368
- meta_data = optional_json_loads(read_text_file(str(args.metadata_file)))
369
-
370
- engine.execute(
371
- username=str(args.username),
372
- password=str(args.password),
373
- input_file_path=str(args.analysis_file),
374
- config_data=config_data,
375
- meta_data=meta_data,
376
- output_directory=str(args.output_directory),
377
- )
378
- print("Thank you for using the NCA Engine Upload and Execution Demo")
379
- except Exception as e: # pylint: disable=w0718
380
- print("An error occured ... exiting with an error")
381
- print(str(e))
382
-
383
-
384
- def optional_json_loads(data: str | dict) -> str | dict:
385
- """
386
- Attempts to load the data as json, fails gracefull and retuns the data is if it fails
387
- Args:
388
- data (str): data as string
389
-
390
- Returns:
391
- str | dict: either the data as is or a converted dictionary/json object
392
- """
393
- if isinstance(data, dict):
394
- return data
395
-
396
- try:
397
- data = json.loads(str(data))
398
- finally:
399
- pass
400
- return data
401
-
402
-
403
- def read_json_file(file_path: str) -> dict:
404
- """
405
- Reads a file and returns the json
406
- Args:
407
- file_path (str): _description_
408
-
409
- Raises:
410
- FileNotFoundError: _description_
411
-
412
- Returns:
413
- dict: _description_
414
- """
415
- if not os.path.exists(file_path):
416
- raise FileNotFoundError(f"File Not Found: {file_path}")
417
-
418
- data = None
419
- with open(file_path, mode="r", encoding="utf8") as file:
420
- data = json.load(file)
421
-
422
- return data
423
-
424
-
425
- def read_text_file(file_path: str) -> str:
426
- """
427
- Read files contents
428
- Args:
429
- file_path (str): path to the file
430
-
431
- Raises:
432
- FileNotFoundError: if the file is not found
433
-
434
- Returns:
435
- str: the files data
436
- """
437
- if not os.path.exists(file_path):
438
- raise FileNotFoundError(f"File Not Found: {file_path}")
439
-
440
- data = None
441
- with open(file_path, mode="r", encoding="utf8") as file:
442
- data = file.read()
443
-
444
- return data
445
-
446
-
447
- if __name__ == "__main__":
448
- main()
@@ -1,5 +1,5 @@
1
1
  """
2
- Copyright 2024 Aplos Analytics
2
+ Copyright 2024-2025 Aplos Analytics
3
3
  All Rights Reserved. www.aplosanalytics.com LICENSED MATERIALS
4
4
  Property of Aplos Analytics, Utah, USA
5
5
  """
@@ -30,8 +30,8 @@ class NCAAppConfiguration:
30
30
 
31
31
  """
32
32
 
33
- def __init__(self, aplos_saas_domain: str):
34
- self.endpoints: NCAEndpoints = NCAEndpoints(aplos_saas_domain=aplos_saas_domain)
33
+ def __init__(self, host: str):
34
+ self.__endpoints: NCAEndpoints = NCAEndpoints(host=host)
35
35
  self.__response: requests.Response | None = None
36
36
 
37
37
  def get(self) -> requests.Response:
@@ -40,7 +40,7 @@ class NCAAppConfiguration:
40
40
  if self.__response is not None:
41
41
  return self.__response
42
42
 
43
- url = self.endpoints.app_configuration()
43
+ url = self.__endpoints.app_configuration
44
44
  self.__response = requests.get(url, timeout=30)
45
45
  if self.__response.status_code != 200:
46
46
  raise RuntimeError("App configuration url is not working.")