aplos-nca-saas-sdk 0.0.5__tar.gz → 0.0.7__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 (51) hide show
  1. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/.vscode/launch.json +1 -13
  2. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/PKG-INFO +1 -1
  3. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/pyproject.toml +1 -1
  4. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/configs/app_settings.py +37 -9
  5. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/configs/login.py +2 -1
  6. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/integration_test_base.py +20 -2
  7. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/integration_test_factory.py +3 -3
  8. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/integration_test_response.py +2 -0
  9. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/integration_test_suite.py +24 -10
  10. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/main.py +8 -4
  11. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/tests/app_configuration_test.py +7 -1
  12. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/tests/app_login_test.py +5 -0
  13. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/version.py +1 -1
  14. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/.gitignore +0 -0
  15. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/.pypirc +0 -0
  16. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/.vscode/settings.json +0 -0
  17. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/LICENSE +0 -0
  18. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/README.md +0 -0
  19. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/devops/pypi/build.py +0 -0
  20. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/devops/pypi/readme.md +0 -0
  21. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/devops/requirements.txt +0 -0
  22. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/docs/images/API_Configuration_blur.png +0 -0
  23. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/docs/images/aplos-nca-commandline-cropped.png +0 -0
  24. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/docs/images/aplos-nca-commandline.png +0 -0
  25. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/mypy.ini +0 -0
  26. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/mypy_checks.py +0 -0
  27. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/readme.md +0 -0
  28. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/requirements.txt +0 -0
  29. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/run-checks.sh +0 -0
  30. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/__init__.py +0 -0
  31. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/aws_resources/aws_cognito.py +0 -0
  32. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/aws_resources/aws_s3_presigned_payload.py +0 -0
  33. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/aws_resources/aws_s3_presigned_upload.py +0 -0
  34. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/files/analysis_files/single_ev/configuration_single_ev.json +0 -0
  35. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/files/analysis_files/single_ev/meta_data.json +0 -0
  36. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/files/analysis_files/single_ev/single_ev.csv +0 -0
  37. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/configs/_config_base.py +0 -0
  38. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/configs/config_sample.json +0 -0
  39. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/integration_test_configurations.py +0 -0
  40. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/readme.md +0 -0
  41. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/tests/app_execution_test.py +0 -0
  42. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/integration_testing/tests/app_validation_test.py +0 -0
  43. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/nca_resources/nca_app_configuration.py +0 -0
  44. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/nca_resources/nca_endpoints.py +0 -0
  45. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/nca_resources/nca_executions.py +0 -0
  46. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/nca_resources/nca_login.py +0 -0
  47. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/utilities/commandline_args.py +0 -0
  48. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/utilities/environment_services.py +0 -0
  49. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/utilities/environment_vars.py +0 -0
  50. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/src/aplos_nca_saas_sdk/utilities/http_utility.py +0 -0
  51. {aplos_nca_saas_sdk-0.0.5 → aplos_nca_saas_sdk-0.0.7}/tests/__init__.py +0 -0
@@ -25,19 +25,7 @@
25
25
  "console": "integratedTerminal"
26
26
  },
27
27
 
28
- {
29
- "name": "Build & Deploy To Code Artifacts",
30
- "type": "debugpy",
31
- "request": "launch",
32
- "program": "${workspaceFolder}/devops/code_artifacts/main.py",
33
- "console": "integratedTerminal",
34
- "env": {
35
-
36
- "ENVRIONMENT": "dev",
37
- "DEBUG_MODE": "True",
38
- "PYTHONPATH": "${workspaceFolder}:${workspaceFolder}/src:${workspaceFolder}/devops:"
39
- }
40
- },
28
+
41
29
  {
42
30
  "name": "Run Integration Tests - dev",
43
31
  "type": "debugpy",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aplos_nca_saas_sdk
3
- Version: 0.0.5
3
+ Version: 0.0.7
4
4
  Summary: Aplos NCA SaaS SDK
5
5
  Project-URL: Homepage, https://aplosanalytics.com/
6
6
  Project-URL: Documentation, https://docs.aplosanalytics.com/
@@ -26,7 +26,7 @@ keywords = [
26
26
  "Clinical Trials"
27
27
  ]
28
28
 
29
- version = "0.0.5"
29
+ version = "0.0.7"
30
30
  authors = [
31
31
  { name="Eric Wilson", email="eric.wilson@aplosanalytics.com" }
32
32
  ]
@@ -14,9 +14,9 @@ class ApplicationDomain(ConfigBase):
14
14
 
15
15
  """
16
16
 
17
- def __init__(self):
17
+ def __init__(self, domain: str | None = None):
18
18
  super().__init__()
19
- self.__domain: str | None = None
19
+ self.__domain: str | None = domain
20
20
 
21
21
  @property
22
22
  def domain(self) -> str:
@@ -30,25 +30,32 @@ class ApplicationDomain(ConfigBase):
30
30
  self.__domain = value
31
31
 
32
32
 
33
- class ApplicationSettings:
33
+ class ApplicationDomains(ConfigBase):
34
34
  """
35
- Application Settings: Defines the domains that the application settings (configuration endpoint) tests will check against
35
+ Application ApplicationDomain: Defines the Domains that the application configuration tests will check against
36
36
 
37
37
  """
38
38
 
39
39
  def __init__(self):
40
+ super().__init__()
40
41
  self.__domains: List[ApplicationDomain] = []
41
42
 
42
43
  @property
43
- def domains(self) -> List[ApplicationDomain]:
44
+ def list(self) -> List[ApplicationDomain]:
45
+ """List the logins"""
44
46
  return self.__domains
45
47
 
46
- @domains.setter
47
- def domains(self, value: List[ApplicationDomain]):
48
- self.__domains = value
48
+ def add(self, *, domain: str, enabled: bool = True):
49
+ """Add a loging"""
50
+ app_domain = ApplicationDomain()
51
+ app_domain.domain = domain
52
+ app_domain.enabled = enabled
53
+ self.__domains.append(app_domain)
49
54
 
50
55
  def load(self, test_config: Dict[str, Any]):
51
- """Load the domains from the config"""
56
+ """Load the logins from a list of dictionaries"""
57
+ # self.enabled = bool(test_config.get("enabled", True))
58
+ super().load(test_config)
52
59
  domains: List[Dict[str, Any]] = test_config.get("domains", [])
53
60
 
54
61
  domain: Dict[str, Any]
@@ -58,3 +65,24 @@ class ApplicationSettings:
58
65
  app_domain.enabled = bool(domain.get("enabled", True))
59
66
 
60
67
  self.__domains.append(app_domain)
68
+
69
+
70
+ class ApplicationSettings(ConfigBase):
71
+ """
72
+ Application Settings: Defines the domains that the application settings (configuration endpoint) tests will check against
73
+
74
+ """
75
+
76
+ def __init__(self):
77
+ super().__init__()
78
+ self.__domains: ApplicationDomains = ApplicationDomains()
79
+
80
+ @property
81
+ def domains(self) -> ApplicationDomains:
82
+ """List of the domain"""
83
+ return self.__domains
84
+
85
+ def load(self, test_config: Dict[str, Any]):
86
+ """Load the domains from the config"""
87
+ super().load(test_config)
88
+ self.domains.load(test_config)
@@ -95,7 +95,8 @@ class Logins(ConfigBase):
95
95
 
96
96
  def load(self, test_config: Dict[str, Any]):
97
97
  """Load the logins from a list of dictionaries"""
98
- self.enabled = bool(test_config.get("enabled", True))
98
+ # self.enabled = bool(test_config.get("enabled", True))
99
+ super().load(test_config)
99
100
  logins: List[Dict[str, str]] = test_config.get("logins", [])
100
101
  for login in logins:
101
102
  self.add(
@@ -22,7 +22,7 @@ class IntegrationTestBase:
22
22
  def __init__(self, name: str | None = None, index: int = 0):
23
23
  self.name = name
24
24
  self.index = index
25
- self.__config: TestConfiguration | None = None
25
+ self.__config: TestConfiguration = TestConfiguration()
26
26
  self.__results: List[IntegrationTestResponse] = []
27
27
 
28
28
  @property
@@ -55,7 +55,25 @@ class IntegrationTestBase:
55
55
  """
56
56
  Returns True if all tests in the suite were successful
57
57
  """
58
- return all([result.success for result in self.results])
58
+ return all([result.error is None for result in self.results])
59
+
60
+ def skipped_count(self) -> int:
61
+ """
62
+ Gets the number of tests that were skipped
63
+ """
64
+ return len([result for result in self.results if result.skipped])
65
+
66
+ def error_count(self) -> int:
67
+ """
68
+ Gets the number of tests that resulted in an error
69
+ """
70
+ return len([result for result in self.results if result.error is not None])
71
+
72
+ def errors(self) -> List[str]:
73
+ """
74
+ Gets the list of errors that occurred during the test
75
+ """
76
+ return [result.error for result in self.results if result.error is not None]
59
77
 
60
78
  def test(self) -> bool:
61
79
  """
@@ -49,14 +49,14 @@ class IntegrationTestFactory:
49
49
  and obj is not IntegrationTestBase
50
50
  ):
51
51
  # Instantiate the class and store it
52
- self.register_test_class(obj())
52
+ self.register_test_instance(obj())
53
53
 
54
54
  @property
55
- def test_classes(self) -> List[IntegrationTestBase]:
55
+ def test_instances(self) -> List[IntegrationTestBase]:
56
56
  """Get the test classes"""
57
57
  self.__test_classes.sort(key=lambda x: x.index)
58
58
  return self.__test_classes
59
59
 
60
- def register_test_class(self, test_class: IntegrationTestBase):
60
+ def register_test_instance(self, test_class: IntegrationTestBase):
61
61
  """Register a test class"""
62
62
  self.__test_classes.append(test_class)
@@ -16,6 +16,7 @@ class IntegrationTestResponse:
16
16
  self.response: Dict[str, Any] = {}
17
17
  self.error: Optional[str] = None
18
18
  self.success: bool = False
19
+ self.skipped: bool = False
19
20
 
20
21
  def to_dict(self) -> Dict[str, Any]:
21
22
  """JSON Dictionary Object"""
@@ -25,4 +26,5 @@ class IntegrationTestResponse:
25
26
  "response": self.response,
26
27
  "error": self.error,
27
28
  "success": self.success,
29
+ "skipped": self.skipped,
28
30
  }
@@ -38,24 +38,35 @@ class IntegrationTestSuite:
38
38
  start_time: datetime = datetime.now(UTC)
39
39
  factory: IntegrationTestFactory = IntegrationTestFactory()
40
40
  test: IntegrationTestBase | None = None
41
- for test in factory.test_classes:
41
+ for test in factory.test_instances:
42
42
  test.config = test_config
43
43
  test_result: Dict[str, Any] = {
44
44
  "test_name": test.name,
45
- "success": True,
46
- "error": None,
47
- "start_time_utc": datetime.now(UTC),
45
+ "success": 0,
46
+ "errors": [],
47
+ "skipped_count": 0,
48
+ "error_count": 0,
49
+ "start_time_utc": None,
48
50
  "end_time_utc": None,
49
51
  }
50
52
 
51
53
  logger.info(f"Running test class {test.name}")
52
54
  try:
55
+ test_result["start_time_utc"] = datetime.now(UTC)
53
56
  success = test.test()
54
57
  test_result["success"] = success
55
58
  test_result["results"] = test.results
59
+ test_result["skipped_count"] = test.skipped_count()
60
+ test_result["error_count"] = test.error_count()
61
+ test_result["errors"] = test.errors()
62
+ if not success:
63
+ if self.fail_fast:
64
+ # just break and let the failure routine handle it
65
+ break
66
+
56
67
  except Exception as e: # pylint: disable=broad-except
57
68
  test_result["success"] = False
58
- test_result["error"] = str(e)
69
+ test_result["errors"] = [str(e)]
59
70
  if self.fail_fast:
60
71
  # just break and let the failure routine handle it
61
72
  break
@@ -69,7 +80,7 @@ class IntegrationTestSuite:
69
80
  else:
70
81
  logger.error(test_result)
71
82
  # find the failures
72
- failures = [test for test in self.test_results if not test["success"]]
83
+ failures = [test for test in self.test_results if len(test["errors"]) > 0]
73
84
  self.__print_results(start_time, failures)
74
85
 
75
86
  # print the results
@@ -83,16 +94,19 @@ class IntegrationTestSuite:
83
94
 
84
95
  def __print_results(self, start_time: datetime, failures: List[Dict[str, Any]]):
85
96
  print("Test Results:")
97
+ skipped = sum([test["skipped_count"] for test in self.test_results])
98
+
86
99
  for test_result in self.test_results:
87
100
  duration = test_result["end_time_utc"] - test_result["start_time_utc"]
88
101
  print(
89
102
  f" {test_result['test_name']} {'succeeded' if test_result['success'] else 'failed'} duration: {duration}"
90
103
  )
91
104
  if not test_result["success"]:
92
- print(f" Error: {test_result['error']}")
105
+ print(f" Error: {test_result['errors']}")
93
106
 
94
107
  print(f"Test Suite completed in {datetime.now(UTC) - start_time}")
95
108
 
96
- print(f"Total Tests: {len(self.test_results)}")
97
- print(f"Successful Tests: {len(self.test_results) - len(failures)}")
98
- print(f"Failed Tests: {len(failures)}")
109
+ print(f" Total Tests: {len(self.test_results)}")
110
+ print(f" Successful: {len(self.test_results) - len(failures) - skipped}")
111
+ print(f" Skipped: {skipped}")
112
+ print(f" Failed: {len(failures)}")
@@ -29,12 +29,16 @@ def main():
29
29
 
30
30
  # normally we'd pull a test configuration file from Secrets Manager, Parameter Store, or some other secure location
31
31
  # here we're going to pull the sample file and then override some it's values.
32
- config_file = os.path.join(Path(__file__).parent, "configs", "config_sample.json")
32
+ config_file = os.path.join(
33
+ Path(__file__).parent,
34
+ "configs",
35
+ os.getenv("TEST_CONFIG_FILE") or "config_sample.json",
36
+ )
33
37
  # load it so we can see what it looks like
34
38
  config.load(file_path=config_file)
35
39
 
36
40
  # override the configuration
37
- override_config(config)
41
+ # override_config(config)
38
42
 
39
43
  its.test(test_config=config)
40
44
 
@@ -53,8 +57,8 @@ def override_config(config: TestConfiguration):
53
57
  config.logins.list.clear()
54
58
  config.logins.add(username=username, password=password, domain=domain)
55
59
 
56
- config.app_config.domains.clear()
57
- config.app_config.domains.append(domain)
60
+ config.app_config.domains.list.clear()
61
+ config.app_config.domains.add(domain=domain)
58
62
 
59
63
 
60
64
  if __name__ == "__main__":
@@ -26,11 +26,17 @@ class TestAppConfiguration(IntegrationTestBase):
26
26
  """Test loading the application configuration"""
27
27
 
28
28
  self.results.clear()
29
- for domain_config in self.config.app_config.domains:
29
+ for domain_config in self.config.app_config.domains.list:
30
30
  config: NCAAppConfiguration = NCAAppConfiguration(domain_config.domain)
31
31
 
32
32
  test_response: IntegrationTestResponse = IntegrationTestResponse()
33
33
  test_response.meta = {"domain": domain_config}
34
+
35
+ if not domain_config.enabled or not self.config.app_config.enabled:
36
+ test_response.skipped = True
37
+ self.results.append(test_response)
38
+ continue
39
+
34
40
  try:
35
41
  response = config.get()
36
42
  test_response.response = response
@@ -29,6 +29,11 @@ class TestAppLogin(IntegrationTestBase):
29
29
  for login in self.config.logins.list:
30
30
  test_response: IntegrationTestResponse = IntegrationTestResponse()
31
31
  test_response.name = self.name
32
+ if not login.enabled or not self.config.logins.enabled:
33
+ test_response.skipped = True
34
+ test_response.success = True
35
+ self.results.append(test_response)
36
+ continue
32
37
  try:
33
38
  nca_login = NCALogin(aplos_saas_domain=login.domain)
34
39
  token = nca_login.authenticate(
@@ -1,4 +1,4 @@
1
1
  # Aplos NCA SaaS SDK Version File
2
2
  # This is automatically generated during the build process.
3
3
  # DO NOT UPDATE IT DIRECTLY. IT WILL BE OVERWRITTEN.
4
- __version__ = '0.0.5'
4
+ __version__ = '0.0.7'