query_metrics.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. Provides query functionality for .csv metrics from S3 buckets
  6. This file is in a prototype stage and is expected to change. It has many moving parts and when linking all of them,
  7. some adjustments will have to happen.
  8. """
  9. import argparse
  10. import csv
  11. import os
  12. import boto3
  13. from boto3.session import Session
  14. BUCKET_NAME = "o3de-metrics"
  15. DOWNLOADED_FILES = []
  16. def _get_session(region='us-west-2'):
  17. """
  18. Gets an AWS session via boto3
  19. :param region: desired AWS region for session
  20. """
  21. id_ = os.environ['AWS_ACCESS_KEY_ID']
  22. secret = os.environ['AWS_SECRET_ACCESS_KEY']
  23. token = os.environ['AWS_SESSION_TOKEN']
  24. session = Session(
  25. aws_access_key_id=id_,
  26. aws_secret_access_key=secret,
  27. aws_session_token=token,
  28. region_name=region
  29. )
  30. return session
  31. def _download_csvs(desired_branch, start_week, end_week, download_folder, region, use_env_credentials):
  32. """
  33. Downloads the desired csvs based on branch, start_week, and end_week to the download_folder
  34. :param desired_branch: name of the desired branch
  35. :param start_week: number of the first week to include
  36. :param end_week: number of the last week to include
  37. :param download_folder: destination folder for the .csvs to be stored while they are being parsed
  38. :param region: desired AWS region for session
  39. :param use_env_credentials: use the env credentials instead of the configured boto3 credentials
  40. """
  41. bucket = _get_session(region, ).resource('s3').Bucket(BUCKET_NAME) if use_env_credentials else boto3.client('s3')
  42. prefix = "csv/" + desired_branch
  43. objects = list(bucket.objects.filter(Prefix=prefix))
  44. file_type = ".csv"
  45. for object in objects:
  46. if file_type == os.path.splitext(object.key)[1]:
  47. try:
  48. # Get the key file values
  49. # We are expecting files to be found in buckets/o3de-metrics/csv/branch/Week#/file_name.csv
  50. # If they are not, they won't be checked, and will be caught in the ValueError below
  51. filter_values = object.key.split('/')
  52. found_branch = filter_values[-3]
  53. week_number = int((filter_values[-2])[4:])
  54. file_name = filter_values[-1]
  55. print("found_branch: " + str(found_branch))
  56. print("week_number: " + str(week_number))
  57. print("file_name: " + str(file_name))
  58. # Determine if the file should be downloaded
  59. should_download_file = True
  60. if found_branch != desired_branch:
  61. should_download_file = False
  62. if start_week and week_number < start_week:
  63. should_download_file = False
  64. elif end_week and week_number > end_week:
  65. should_download_file = False
  66. # Download the file
  67. if should_download_file:
  68. print("str(download_folder): " + str(download_folder))
  69. print("str(week_number): " + str(week_number))
  70. week_folder = os.path.join(download_folder, str(week_number))
  71. if not os.path.exists(week_folder):
  72. os.mkdir(week_folder)
  73. download_path = os.path.join(download_folder, str(week_number), file_name)
  74. DOWNLOADED_FILES.append(download_path)
  75. bucket.download_file(object.key, download_path)
  76. # If a .csv is in the wrong location, it'll break the functionality above. We're just going to skip it.
  77. except ValueError as value_error:
  78. print("Found value error. Likely means a csv is in the wrong location. Skipping and continuing. Error "
  79. "{0} ".format(str(value_error)))
  80. def query_csvs(test_case_ids=None, test_case_metrics=None):
  81. """
  82. Queries the desired information from the downloaded csvs
  83. :param test_case_ids: the desired test case ids
  84. :param test_case_metrics: the desired test case metrics
  85. """
  86. query_results = []
  87. for downloaded_csv in DOWNLOADED_FILES:
  88. with open(downloaded_csv, 'r') as csv_file:
  89. reader = csv.reader(csv_file)
  90. parsed_header_row = False
  91. desired_columns = []
  92. for row in reader:
  93. # Get desired columns if test_case_metrics were passed
  94. if not parsed_header_row:
  95. if test_case_metrics is not None:
  96. for column_index, column_header in enumerate(row):
  97. if column_header in test_case_metrics:
  98. desired_columns.append(column_index)
  99. parsed_header_row = True
  100. # Actually get the data
  101. if test_case_ids is not None and row[0] in test_case_ids:
  102. query_results.append(_parse_row(test_case_metrics, row, desired_columns))
  103. elif test_case_ids is None:
  104. query_results.append(_parse_row(test_case_metrics, row, desired_columns))
  105. print("row " + str(row))
  106. csv_file.close()
  107. return query_results
  108. def _parse_row(test_case_metrics, row, desired_columns):
  109. """
  110. Queries the desired information from the downloaded csvs
  111. :param test_case_metrics: the desired test case metrics
  112. :param row: the row being parsed
  113. :param desired_columns: the columns to include
  114. """
  115. row_to_add = []
  116. if test_case_metrics is not None:
  117. for column_number in desired_columns:
  118. row_to_add.append(row[int(column_number)])
  119. pass
  120. else:
  121. row_to_add = row
  122. return row_to_add
  123. if __name__ == '__main__':
  124. # This functionality is in a prototype stage, and expected to change
  125. # parse parameters
  126. parser = argparse.ArgumentParser(prog='MetricsQueryTool', description='Queries the metrics.')
  127. parser.add_argument('-b', '--branch', required=True)
  128. parser.add_argument('-sw', '--startweek', required=False)
  129. parser.add_argument('-ew', '--endweek', required=False, help='Max of 52.')
  130. parser.add_argument('-df', '--downloadfolder', required=True)
  131. parser.add_argument('-tcids', '--testcaseids', nargs='+', required=False)
  132. parser.add_argument('-tcms', '--testcasemetrics', nargs='+', required=False)
  133. parser.add_argument('-r', '--region', required=False)
  134. parser.add_argument('-env', '--envcredentials', required=False, help="Override the configured credentials to "
  135. "instead use environment variables.")
  136. args = parser.parse_args()
  137. start_week = int(args.startweek) if args.startweek else None
  138. end_week = int(args.endweek) if args.endweek else None
  139. # download csvs
  140. _download_csvs(args.branch, start_week, end_week, args.downloadfolder, args.region, args.envcredentials)
  141. # query csvs for data
  142. query_csvs(args.testcaseids, args.testcasemetrics)