forked from cehbrecht/duck
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
148 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
from .wps_clintai import ClintAI | ||
from .wps_dashboard import Dashboard | ||
|
||
processes = [ | ||
ClintAI(), | ||
Dashboard(), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
from pathlib import Path | ||
|
||
from pywps import Process, ComplexOutput, Format | ||
|
||
from duck import query | ||
|
||
class Dashboard(Process): | ||
def __init__(self): | ||
# inputs = [ | ||
# ComplexInput('input_csv', 'CSV File', supported_formats=[Format('text/csv')]), | ||
# ] | ||
outputs = [ | ||
ComplexOutput( | ||
'report', | ||
'Generated HTML Report', | ||
as_reference=True, | ||
supported_formats=[Format('text/html')] | ||
), | ||
] | ||
|
||
super(Dashboard, self).__init__( | ||
self._handler, | ||
identifier='dashboard', | ||
title='Generate HTML Report', | ||
version='1.0', | ||
abstract='Generate an HTML report from a provenance database.', | ||
# inputs=inputs, | ||
outputs=outputs, | ||
) | ||
|
||
def _handler(self, request, response): | ||
workdir = Path(self.workdir) | ||
# input_csv = request.inputs['input_csv'][0].file | ||
|
||
# Query the provenance database ... result is a Pandas DataFrame | ||
df = query.query() | ||
|
||
# Generate an HTML report from the DataFrame | ||
html_report = self.write_html(df, workdir) | ||
|
||
response.outputs['report'].file = html_report | ||
response.outputs['report'].output_format = Format('text/html') | ||
|
||
return response | ||
|
||
def write_html(self, df, workdir): | ||
# Convert the DataFrame to an HTML table | ||
html_table = df.to_html(index=False) | ||
|
||
# Define the HTML template | ||
html_template = f""" | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Provenance Report</title> | ||
<style> | ||
table {{ | ||
border-collapse: collapse; | ||
width: 100%; | ||
border: 1px solid #ddd; | ||
}} | ||
th, td {{ | ||
text-align: left; | ||
padding: 8px; | ||
}} | ||
th {{ | ||
background-color: #f2f2f2; | ||
}} | ||
tr:nth-child(even) {{ | ||
background-color: #f2f2f2; | ||
}} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Provenance Report</h1> | ||
{html_table} | ||
</body> | ||
</html> | ||
""" | ||
|
||
# Write the HTML template to a file | ||
outfile = workdir / "provenance_report.html" | ||
with outfile.open(mode='w') as file: | ||
file.write(html_template) | ||
|
||
return outfile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from duck.db import GraphDB | ||
import pandas as pd | ||
|
||
|
||
def query(): | ||
query_str = """ | ||
SELECT ?process ?dataset ?variable ?startTime ?endTime ?input ?output ?min ?max ?stddev | ||
WHERE { | ||
?exec rdf:type provone:Execution ; | ||
rdfs:label ?process ; | ||
clint:dataset_name ?dataset ; | ||
clint:variable_name ?variable ; | ||
prov:startedAtTime ?startTime ; | ||
prov:endedAtTime ?endTime ; | ||
clint:min ?min ; | ||
clint:max ?max ; | ||
clint:stddev ?stddev . | ||
?input rdf:type prov:Entity . | ||
?output rdf:type prov:Entity ; | ||
prov:qualifiedDerivation [ prov:entity ?input; prov:hadActivity ?exec ] . | ||
} | ||
""" | ||
graph_db = GraphDB() | ||
results = graph_db.query(query_str) | ||
|
||
data = [] | ||
for row in results: | ||
# print(row) | ||
process = row.process.split("/")[-1] | ||
dataset = row.dataset.value | ||
variable = row.variable.value | ||
start_time = row.startTime.value | ||
end_time = row.endTime.value | ||
input = row.input.split("/")[-1] | ||
input = input.split("urn:clint:")[-1] | ||
output = row.output.split("/")[-1] | ||
output = output.split("urn:clint:")[-1] | ||
min = row.min.value | ||
max = row.max.value | ||
stddev = row.stddev.value | ||
data.append({ | ||
"Process": process, | ||
"Dataset": dataset, | ||
"Variable": variable, | ||
"Start Time": start_time, | ||
"End Time": end_time, | ||
"Input": input, | ||
"Output": output, | ||
"Min": min, | ||
"Max": max, | ||
"StdDev": stddev, | ||
}) | ||
df = pd.DataFrame(data) | ||
return df |