Skip to content

Commit

Permalink
generate index.html automatically based on the jsonld
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenifer Tabita Ciuciu-Kiss committed Jun 13, 2024
1 parent d2efbdf commit 5fd47ec
Show file tree
Hide file tree
Showing 7 changed files with 986 additions and 497 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__/
*.py[cod]
928 changes: 431 additions & 497 deletions index.html

Large diffs are not rendered by default.

144 changes: 144 additions & 0 deletions src/generate_doc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import requests
import json
from jinja2 import Environment, FileSystemLoader
from static import namespace_descriptions, codemeta_properties_data
from static import group_leaders, team_members
from static import context_desciption

# Get schema.orh jsonld
schemaorg_url = "https://raw.githubusercontent.com/schemaorg/schemaorg/main/data/releases/26.0/schemaorg-all-http.jsonld"
schemaorg_response = requests.get(schemaorg_url)

# Get codemeta jsonld
headers = {
"Accept": "application/ld+json"
}
codemeta_url = "https://w3id.org/codemeta"
#codemeta_url = "https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld"
codemeta_response = requests.get(codemeta_url, headers=headers)


if schemaorg_response.status_code == 200 and codemeta_response.status_code == 200:
schemaorg_data = schemaorg_response.json()
codemeta_data = codemeta_response.json()


with open('development/context.jsonld', 'r') as f:
data = json.load(f)


def get_item_by_id(graph, item_id):
"""Retrieve an item from the graph by its @id."""
for item in graph:
if item.get('@id') == item_id:
return item
return None


def get_expected_types_and_urls(item):
range_includes = item.get('schema:rangeIncludes', [])
if not isinstance(range_includes, list):
range_includes = [range_includes]
expected_types = [rtype.get('@id', '') for rtype in range_includes if isinstance(rtype, dict)]
expected_types_url = []
for type in expected_types:
if 'schema' in type:
expected_types_url.append('http://schema.org/' + type.split(':')[-1])
else:
expected_types_url.append('')
return expected_types, expected_types_url


def get_description(item, schemaorg_data, codemeta_data):
if 'schema:' in item.get('@id', ''):
return next((x['rdfs:comment'] for x in schemaorg_data['@graph'] if x['@id'] == item.get('@id', '')), '')
elif 'codemeta:' in item.get('@id', ''):
return next((x['rdfs:comment'] for x in codemeta_data['@context'] if x['@id'] == item.get('@id', '')), '')
return item.get('rdfs:comment', '')


def format_property(item, schemaorg_data, codemeta_data):
property_name = item.get('@id', '')
if property_name.split(':')[-1].isupper():
return
property_url = ''
if 'schema:' in item.get('@id', ''):
property_url = 'http://schema.org/' + property_name.split(':')[-1]

description = get_description(item, schemaorg_data, codemeta_data)

expected_types, expected_types_url = get_expected_types_and_urls(item)
return {
'property': property_name,
'property_url': property_url,
'expected_type_and_urls': list(zip(expected_types, expected_types_url)),
'description': description
}

# Extract FAIR4ML properties
fair4ml_properties = [format_property(item, schemaorg_data, codemeta_data) for item in data.get('@graph', []) if item.get('@id', '').startswith('fair4ml:')]

# Extract schema.org profiles
schema_profiles = []
for key, value in data['@context'].items():
if type({}) == type(value):
item_id = value.get('@id')
item = get_item_by_id(schemaorg_data['@graph'], item_id)
else:
continue
if item_id.split(':')[-1][0].isupper():
expected_types, expected_types_url = get_expected_types_and_urls(item)
profile = {
'profile': item_id,
'profile_url': 'http://schema.org/' + item_id.split(':')[-1],
'description': item.get('rdfs:comment', '')
}
schema_profiles.append(profile)

# Extract schema.org and codemeta properties
schema_properties = []
codemeta_properties = []
for property, val in data['@context'].items():
if not isinstance(val, str):
property_name = val['@id'].split(':')[-1]
if property_name[0].islower():
if 'schema' in val['@id'].split(':')[0]:
item = get_item_by_id(schemaorg_data['@graph'], val['@id'])
schema_properties.append(format_property(item, schemaorg_data, codemeta_data))
else:
codemeta_property_info = codemeta_properties_data[property_name]
property_json = {
'property': property_name,
'property_url': "https://w3id.org/codemeta/"+property_name,
'expected_type_and_urls': list(zip([codemeta_property_info['type']], "http://schema.org/"+codemeta_property_info['type'])),
'description': codemeta_property_info["desc"]
}
codemeta_properties.append(property_json)

# Extract namespaces
namespaces = []
for prefix, url in data.get('@context', {}).items():
if isinstance(url, str):
namespaces.append({'prefix': prefix, 'url': url, "description": namespace_descriptions[prefix]})

context = {
'description': context_desciption,
'fair4ml_properties': fair4ml_properties,
'schema_properties': schema_properties,
'codemeta_properties': codemeta_properties,
'schema_profiles': schema_profiles,
'namespaces': namespaces,
'group_leaders': group_leaders,
'team_members': team_members
}

env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('src/template.html')

html_output = template.render(context)

# Save index.html
with open('index.html', 'w') as f:
f.write(html_output)

#print("HTML file has been generated successfully.")
2 changes: 2 additions & 0 deletions src/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json
jinja
37 changes: 37 additions & 0 deletions src/static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
group_leaders = ['Daniel Garijo', 'Leyla Jael Castro']
team_members = ['Jenifer Tabita Ciuciu-Kiss', 'Dhwani Solanki', 'Dietrich Rebholz-Schuhmann']

context_desciption = "'In this document we propose a simple way for MLModel to self-describe their genetic variant cardinality service for better integration.'"

namespace_descriptions = {
"rdf": "This is the RDF Schema for the RDF vocabulary terms in the RDF Namespace, defined in RDF 1.1 Concepts.",
"rdfs": "The RDF Schema vocabulary (RDFS).",
"owl": "This ontology partially describes the built-in classes and properties that together form the basis of the RDF/XML syntax of OWL 2.",
"schema": "Schema.org is a collaborative, community activity with a mission to create, maintain, and promote schemas for structured data on the Internet, on web pages, in email messages, and beyond.",
"codemeta": "Codemeta is a minimal metadata schema for science software and code, in JSON and XML.",
"fair4ml": "FAIR4ML metadata schema for machine learning models.",
"cr": "Datasets are the basis of machine learning (ML). However, a lack of standardization in the description and semantics of ML datasets has made it increasingly difficult for researchers and practitioners to explore, understand, and use all but a small fraction of popular datasets."
}

codemeta_properties_data = {
"buildInstructions": {
"type": "schema:URL",
"desc": "Link to installation instructions/documentation."
},
"developmentStatus": {
"type": "schema:Text",
"desc": "Description of development status, e.g. Active, inactive, suspended. See repostatus.org ."
},
"issueTracker": {
"type": "schema:URL",
"desc": "Link to software bug reporting or issue tracking system."
},
"readme": {
"type": "schema:URL",
"desc": "Link to software Readme file."
},
"referencePublication": {
"type": "schema:ScholarlyArticle",
"desc": "An academic publication related to the software."
}
}
185 changes: 185 additions & 0 deletions src/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="en">
<html>

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<title>
FAIR4ML

</title>
<meta name="description" content="">
<!-- Styling -->
<link href='https://fonts.googleapis.com/css?family=Noto+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<!-- JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>

<body>
<div class="container min-vh-100">
<main id="main" class="my-5">
<h1>FAIR4ML <u></u> Profile</h1>

<h3><strong>Version:</strong> 0.0.1 (2024.06.04.)</h3>
<h2>A convention for FAIR4ML to self-describe. </h2>
<br />
<p>If you spot any errors or omissions with this type, please file an issue in our <a
href="https://github.com/RDA-FAIR4ML/FAIR4ML-schema" target="_blank">GitHub</a>.</p>
<div class="tab-content py-3 mb-3 border-bottom" id="nav-tabContent">

<div class="tab-pane fade show active" id="nav-description" role="tabpanel" aria-labelledby="nav-description-tab">
<h3>Description</h3>
<p>{{ description }}</p>
<h3>Schema.org hierarchy</h3>
This Profile fits into the schema.org hierarchy as follows:
<br />
<br />
<hr />
<a href="http://schema.org/Thing">Thing</a>
&gt;
<a href="http://schema.org/CreativeWork">CreativeWork</a>
&gt;
<a href="https://github.com/RDA-FAIR4ML/FAIR4ML-schema">MLModel</a>
<hr />
</div>

<div class="table-responsive shadow rounded mt-4 mb-5">
<table class="table table-hover table-borderless mb-0 spec-prof-table">
<thead>
<tr>
<th>Property</th>
<th>Expected Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for property in fair4ml_properties %}
<tr>
<td class="property-column"><a href="{{ property.property_url }}">{{ property.property }}</a></td>
<td>
{% for type, url in property.expected_type_and_urls %}
<a href="{{ url }}">{{ type }}</a><br/>
{% endfor %}
</td>
<td class="description-column">{{ property.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<h3>Schema.org Profiles</h3>
<div class="table-responsive shadow rounded mt-4 mb-5">
<table class="table table-hover table-borderless mb-0 spec-prof-table">
<thead>
<tr>
<th>Profiles</th>
<th>Expected Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for profile in schema_profiles %}
<tr>
<td class="property-column"><a href="{{ profile.profile_url }}">{{ profile.profile }}</a></td>
<td class="property-column"><a href="{{ profile.profile_url }}">{{ profile.profile }}</a></td>
<td class="description-column">{{ profile.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<h3>Schema.org Properties</h3>
<div class="table-responsive shadow rounded mt-4 mb-5">
<table class="table table-hover table-borderless mb-0 spec-prof-table">
<thead>
<tr>
<th>Property</th>
<th>Expected Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for property in schema_properties %}
<tr>
<td class="property-column"><a href="{{ property.property_url }}">{{ property.property }}</a></td>
<td>
{% for type, url in property.expected_type_and_urls %}
<a href="{{ url }}">{{ type }}</a><br/>
{% endfor %}
</td>
<td class="description-column">{{ property.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<h3>Codemeta Properties</h3>
<div class="table-responsive shadow rounded mt-4 mb-5">
<table class="table table-hover table-borderless mb-0 spec-prof-table">
<thead>
<tr>
<th>Property</th>
<th>Expected Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for property in codemeta_properties %}
<tr>
<td class="property-column"><a href="{{ property.property_url }}">{{ property.property }}</a></td>
<td>
{% for type, url in property.expected_type_and_urls %}
<a href="{{ url }}">{{ type }}</a><br/>
{% endfor %}
</td>
<td class="description-column">{{ property.description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>

<h3>Namespaces</h3>
<p>Below are the namespaces used in this document:</p>
<ul>
{% for namespace in namespaces %}
<li><a href="{{ namespace.url }}" target="_blank" class="external" rel="noopener">{{ namespace.prefix }}</a>: {{ namespace.description }}</li>
{% endfor %}
</ul>

<hr/>

<div>
<h3>Contributors</h3>
<p>The following people have been involved in the creation of this specification document.</p>

<h5 class="my-4">Group Leader(s)</h5>
{% for leader in group_leaders %}
<div class="col mt-2">{{ leader }}</div>
{% endfor %}

<h5 class="my-4">Other team members</h5>
{% for member in team_members %}
<div class="col mt-2">{{ member }}</div>
{% endfor %}
</div>


</div>
</main>
</div>

<script src="/assets/js/clipboard.min.js"></script>
<script src="/assets/js/scripts.js"></script>
</body>

</html>
Loading

0 comments on commit 5fd47ec

Please sign in to comment.