Source code for thoth.lab.solver
# thoth-lab
# Copyright(C) 2020 Francesco Murdaca
#
# This program is free software: you can redistribute it and / or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Solver results processing and analysis."""
import logging
from pathlib import Path
from .common import aggregate_thoth_results
_LOGGER = logging.getLogger("thoth.lab.solver")
logging.basicConfig(level=logging.INFO)
[docs]def aggregate_solver_results(
limit_results: bool = False, max_ids: int = 5, is_local: bool = True, solver_repo_path: Path = Path("solver")
) -> list:
"""Aggregate solver results from jsons stored in Ceph or locally from `solver` repo.
:param limit_results: reduce the number of solver reports ids considered to `max_ids` to test analysis
:param max_ids: maximum number of solver reports ids considered
:param is_local: flag to retreive the dataset locally or from S3 (credentials are required)
:param solver_repo_path: required if you want to retrieve the solver dataset locally and `is_local` is set to True
"""
solver_reports = aggregate_thoth_results(
limit_results=limit_results,
max_ids=max_ids,
is_local=is_local,
repo_path=solver_repo_path,
store_name="solver",
)
return solver_reports
[docs]def construct_solver_from_metadata(solver_report_metadata: dict) -> str:
"""Construct solver from solver report metadata."""
os_name = solver_report_metadata["os_release"]["name"].lower()
os_version = "".join(
[list_solver for list_solver in solver_report_metadata["os_release"]["version"] if list_solver.isdigit()]
)
python_interpreter = f'{solver_report_metadata["python"]["major"]}{solver_report_metadata["python"]["minor"]}'
solver = f"{os_name}-{os_version}-py{python_interpreter}"
return solver
[docs]def extract_data_from_solver_metadata(solver_report_metadata: dict) -> dict:
"""Extract data from solver report metadata."""
solver = construct_solver_from_metadata(solver_report_metadata)
solver_parts = solver.split("-")
requirements = solver_report_metadata["arguments"]["python"]["requirements"]
extracted_metadata = {
"document_id": solver_report_metadata["document_id"],
"datetime": solver_report_metadata["datetime"],
"requirements": requirements,
"solver": solver,
"os_name": solver_parts[0],
"os_version": solver_parts[1],
"python_interpreter": ".".join(solver_parts[2][2:]),
"analyzer_version": solver_report_metadata["analyzer_version"],
}
return extracted_metadata
[docs]def extract_tree_from_solver_result(solver_report_result: dict) -> list:
"""Extract data from solver report result."""
packages = []
for python_package_info in solver_report_result["tree"]:
package = {
"package_name": python_package_info["package_name"],
"package_version": python_package_info["package_version_requested"],
"index_url": python_package_info["index_url"],
"importlib_metadata": python_package_info["importlib_metadata"]["metadata"],
"dependencies": python_package_info["dependencies"],
}
packages.append(package)
return packages
[docs]def extract_errors_from_solver_result(solver_report_result_errors: list) -> list:
"""Extract all errors from solver report (if any)."""
errors = []
for error in solver_report_result_errors:
errors.append(
{
"package_name": error["package_name"],
"package_version": error["package_version"],
"index_url": error["index_url"],
"type": error["type"],
"command": error["details"]["command"] if "command" in error["details"] else None,
"message": error["details"]["message"] if "message" in error["details"] else None,
"return_code": error["details"]["return_code"] if "return_code" in error["details"] else None,
"stderr": error["details"]["stderr"] if "stderr" in error["details"] else None,
"stdout": error["details"]["stdout"] if "stdout" in error["details"] else None,
"timeout": error["details"]["timeout"] if "timeout" in error["details"] else None,
}
)
return errors