Skip to content

Commit

Permalink
Add badges to OBO Dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
matentzn committed May 30, 2022
1 parent d9446f9 commit 20d73db
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
23 changes: 21 additions & 2 deletions util/dashboard/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@

from argparse import ArgumentParser, FileType
from py4j.java_gateway import JavaGateway
from lib import round_float, compute_dashboard_score, compute_obo_score, DashboardConfig
from lib import round_float, compute_dashboard_score, compute_obo_score, DashboardConfig, \
create_dashboard_score_badge, create_dashboard_qc_badge


def run():
Expand Down Expand Up @@ -337,18 +338,29 @@ def run():
all_checks[key] = result

# Summary status
badge_message = []
color = ""

if err > 0:
summary = 'ERROR'
color = "red"
summary_comment = '{0} errors'.format(err)
badge_message.append(f"ERROR {err}")
elif warn > 0:
summary = 'WARN'
color = "yellow"
summary_comment = '{0} warnings'.format(warn)
elif info > 0:
summary = 'INFO'
color = 'green'
summary_comment = '{0} info messages'.format(info)
else:
summary = 'PASS'
summary_comment = ''
color = 'green'

if warn > 0:
badge_message.append(f"WARN {warn}")

summary_count = dict()
summary_count['ERROR'] = err
Expand All @@ -364,18 +376,25 @@ def run():
for key in save_data:
data_yml[key] = save_data[key]

data_yml['metrics']['Info: Experimental OBO score']['_dashboard'] = round_float(
obo_dashboard_score = round_float(
float(compute_dashboard_score(data_yml, oboscore_weights, oboscore_maximpacts)) / 100)
data_yml['metrics']['Info: Experimental OBO score']['_dashboard'] = obo_dashboard_score
oboscore = compute_obo_score(data_yml['metrics']['Info: Experimental OBO score']['_impact'],
data_yml['metrics']['Info: Experimental OBO score']['_reuse'],
data_yml['metrics']['Info: Experimental OBO score']['_dashboard'],
data_yml['metrics']['Info: Experimental OBO score']['_impact_external'],
oboscore_weights)

data_yml['metrics']['Info: Experimental OBO score']['oboscore'] = round_float(oboscore['score'])
data_yml['metrics']['Info: Experimental OBO score']['_formula'] = oboscore['formula']



# Save to YAML file
print('Saving results to {0}'.format(dashboard_yml))
create_dashboard_qc_badge(color, ", ".join(badge_message), ontology_dir)
create_dashboard_score_badge("blue", obo_dashboard_score, ontology_dir)

with open(dashboard_yml, 'w+') as f:
yaml.dump(data_yml, f)
except Exception:
Expand Down
34 changes: 33 additions & 1 deletion util/dashboard_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import click
import logging
import urllib.request
import json


from lib import DashboardConfig, runcmd, sha256sum, save_yaml, \
load_yaml, robot_prepare_ontology, get_hours_since, get_base_prefixes, \
compute_percentage_reused_entities, round_float
compute_percentage_reused_entities, round_float, create_dashboard_score_badge, \
create_dashboard_qc_badge

logging.basicConfig(level=logging.INFO)

Expand Down Expand Up @@ -114,6 +116,7 @@ def compute_external_impact(number_uses):
return 0



def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters, config):
ontologies_results = {}

Expand All @@ -140,6 +143,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Corrupted results file for {o}: {ont_results_path}')
ont_results['failure'] = 'corrupted_results_file'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Corrupted results file", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

if config.is_skip_existing():
Expand Down Expand Up @@ -169,6 +174,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Missing download url for {o} in registry..')
ont_results['failure'] = 'missing_url'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Missing URL", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

# Get base namespaces
Expand All @@ -178,6 +185,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Missing base namespaces for {o} in registry..')
ont_results['failure'] = 'missing_base_namespaces'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Missing base namespaces", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

if download:
Expand All @@ -188,6 +197,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Failed to download {o} from {ourl}')
ont_results['failure'] = 'failed_download'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Failed to download", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue
else:
logging.info(f"Downloading {o} skipped.")
Expand Down Expand Up @@ -220,6 +231,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Failed to compute hashcode of {o}.')
ont_results['failure'] = 'failed_sha256_hash'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Failed to compute hashcode", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue


Expand All @@ -231,6 +244,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'No hashcode for {ont_path}, aborting.')
ont_results['failure'] = 'no_sha256_hash'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "No hashcode for file", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

ont_results['base_generated'] = make_base
Expand All @@ -253,6 +268,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.error(f'Failed to verify {o} as downloaded from {ourl}')
ont_results['failure'] = 'not_an_ontology'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Not an ontology", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

logging.info(f"Creating basefile for {o}...")
Expand All @@ -263,6 +280,8 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Failed to compute base file for {o}.')
ont_results['failure'] = 'failed_robot_base'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Failed to compute base", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue


Expand Down Expand Up @@ -308,10 +327,14 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
logging.exception(f'Broken metrics file for {o}: {ont_metrics_path}')
ont_results['failure'] = 'broken_metrics_file'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Failed metrics", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue
else:
logging.exception(f'Missing metrics file for {o}: {ont_metrics_path}')
ont_results['failure'] = 'missing_metrics_file'
create_dashboard_qc_badge("red", "Missing metrics", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
save_yaml(ont_results, ont_results_path)
continue

Expand All @@ -320,18 +343,24 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
if ont_results['metrics']['Axioms: Number of axioms'] < 1:
logging.exception(f'Ontology has lass than one axiom: {o}')
ont_results['failure'] = 'empty_ontology'
create_dashboard_qc_badge("red", "Empty ontology", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
save_yaml(ont_results, ont_results_path)
continue

if not ont_results['metrics']['Info: Logical consistency']:
logging.exception(f'Ontology is inconsistent: {o}')
ont_results['failure'] = 'inconsistent_ontology'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Inconsistent ontology", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue
except Exception:
logging.exception(f'Metrics based checks failed for {o}: {ont_metrics_path}')
ont_results['failure'] = 'metrics_check_failed'
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Processing error: failed metrics", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue

logging.info(f"{o}: preprocessing successful.")
Expand Down Expand Up @@ -425,11 +454,14 @@ def prepare_ontologies(ontologies, ontology_dir, dashboard_dir, make_parameters,
save_yaml(ont_results, ont_results_path)
runcmd(f"make {make_parameters} {dashboard_html}", config.get_dashboard_report_timeout_seconds())
ont_results.pop('last_ontology_dashboard_run_failed', None)

except Exception:
logging.exception(f'Failed to build dashboard pages for {o}.')
ont_results['failure'] = 'failed_ontology_dashboard'
ont_results['last_ontology_dashboard_run_failed'] = True
save_yaml(ont_results, ont_results_path)
create_dashboard_qc_badge("red", "Processing error: build dashboard", ont_dashboard_dir)
create_dashboard_score_badge("lightgrey", "NA", ont_dashboard_dir)
continue
else:
logging.info(f"Not running dashboard for {o} because it has not changed ({ont_results['changed']}) "
Expand Down
22 changes: 22 additions & 0 deletions util/lib.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3

import yaml
import json
import logging
import subprocess
import threading
Expand Down Expand Up @@ -492,3 +493,24 @@ def compute_percentage_reused_entities(entity_use_map, internal_ns):
reuse_score = 100*(external_entities/(external_entities+internal_entities))
score_string = "%.2f" % round(reuse_score, 2)
return float(score_string)

def create_dashboard_qc_badge(color: str, message: str, outdir: str):
create_badge(color, message, "OBO Dashboard QC", f"{outdir}/dashboard-qc-badge.json")


def create_dashboard_score_badge(color: str, message: str, outdir: str):
create_badge(color, message, "OBO Dashboard Score", f"{outdir}/dashboard-score-badge.json")


def create_badge(color: str, message: str, label:str, filepath: str):
odk_svg='<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 135.54 133.3"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#231f20;}</style></defs><path class="cls-1" d="M85.31,20.58l-4-16.64s0,0,0,0c-1.11-.14-2.21-.26-3.33-.35s-2.24-.15-3.36-.18-2.26,0-3.4,0c-.82,0-1.66.06-2.49.11L63.21,19.66c-.22,0-.43.11-.65.15l0,.11c-1.58.3-3.13.68-4.65,1.12s-3,1-4.45,1.53L40.52,11.64c-.58.32-1.17.63-1.74,1-1,.56-1.91,1.14-2.83,1.74s-1.84,1.23-2.73,1.88-1.77,1.31-2.63,2l-.73.6L34.72,35c-.15.16-.28.33-.42.48v0c-1.12,1.18-2.17,2.42-3.17,3.7s-1.95,2.59-2.84,4h-.06v0l-16.83-1c-.31.62-.62,1.23-.91,1.85-.46,1-.88,2-1.29,3.07-.28.69-.53,1.39-.79,2.09-.12.35-.26.7-.38,1.05-.36,1-.69,2.1-1,3.17-.1.33-.17.68-.26,1l13.4,10.13a54.29,54.29,0,0,0-.56,10.73L5.25,84.54c.09.52.16,1,.26,1.55.21,1.08.44,2.16.7,3.23s.54,2.14.85,3.2.65,2.12,1,3.16c.14.42.31.82.46,1.24h0L25.22,97l0,0h.13a51.6,51.6,0,0,0,5.88,9L24.87,122c.61.59,1.21,1.18,1.83,1.74.85.76,1.71,1.49,2.59,2.2S31.06,127.35,32,128s1.62,1.14,2.45,1.69l13.68-9.92c.14.07.3.12.43.19l.1-.07c1.22.59,2.47,1.11,3.73,1.59a19.94,19.94,0,0,1,9.28-28.87A22.89,22.89,0,0,1,72.29,49.46a23.11,23.11,0,0,1,6,.82,19.92,19.92,0,0,1,11.53-27.8l.16-.42A47.65,47.65,0,0,0,85.31,20.58Z"/><path class="cls-2" d="M43.71,37.89V34.77c0-2.89,1.57-4,4.09-4s4.09,1.07,4.09,4v3.12c0,3-1.2,4.17-4.09,4.17S43.71,40.86,43.71,37.89Zm6.4,0V34.77c0-2-.84-2.37-2.31-2.37s-2.32.39-2.32,2.37v3.12c0,2,.73,2.62,2.32,2.62S50.11,39.87,50.11,37.89Z"/><path class="cls-2" d="M60.46,41.87l-.22-1.44a2.71,2.71,0,0,1-2.71,1.5c-2.19,0-3.7-1-3.7-3.94V35.11c0-3,1.4-4.24,3.7-4.24a3,3,0,0,1,2.63.95V27.27H62v14.6Zm-2.54-9.28c-1.59,0-2.31.63-2.31,2.56V38c0,1.79.72,2.26,2.18,2.26s2.37-.71,2.37-2.86V35.05C60.16,33.19,59.51,32.59,57.92,32.59Z"/><path class="cls-2" d="M67,37h-.8v4.85H64.42V27.45H66.2v7.88h.71L70.29,31h2.17l-4,5.13,4.37,5.79H70.7Z"/><path class="cls-1" d="M126.8,64.76a4.35,4.35,0,0,0-3.28,1.52l-6.24-3A8.16,8.16,0,0,0,115.15,55l3.73-5.15a2.7,2.7,0,0,0,.63.07A2.93,2.93,0,1,0,116.58,47a2.87,2.87,0,0,0,.42,1.48l-3.74,5.15a8.21,8.21,0,0,0-12,7.27,7.59,7.59,0,0,0,.11,1.27L84.84,67.27a13.6,13.6,0,0,0-3.38-4.87l10.7-13.85a8.12,8.12,0,0,0,4,1.07,8.24,8.24,0,1,0-5.89-2.5L79.61,61a13.54,13.54,0,1,0-9.5,24.75l-1.3,17.14a8.21,8.21,0,0,0,.55,16.4l.49,0,1.38,6.7a2.3,2.3,0,1,0,2.29-.46l-1.38-6.7a8.21,8.21,0,0,0-1-15.74l1.3-17.13a13.5,13.5,0,0,0,6.26-1.6l8.18,12.51A8.2,8.2,0,0,0,90.48,111L90,116.62a4.39,4.39,0,1,0,2.33.2l.47-5.66A8.21,8.21,0,0,0,99.49,107l7.1,2.71a2.32,2.32,0,1,0,.84-2.18l-7.11-2.71a8.2,8.2,0,0,0-11.48-9.24L80.65,83a13.74,13.74,0,0,0,3.81-4.71L99.14,84a8,8,0,0,0-.22,1.84,8.22,8.22,0,1,0,1-4L85.3,76.12a13.36,13.36,0,0,0,.23-6.62L102,64.42a8.21,8.21,0,0,0,14.27,1l6.24,3a4.41,4.41,0,0,0-.08.73,4.36,4.36,0,1,0,4.36-4.36Z"/></svg>'
json_data = {
"schemaVersion": 1,
"label": f"{label}",
"message": f"{message}",
"color": f"{color}",
"logoSvg": odk_svg
}
json_string = json.dumps(json_data)
with open(filepath, "w") as text_file:
print(json_string, file=text_file)

0 comments on commit 20d73db

Please sign in to comment.