Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ src/work/*
sbol-validator/*
*.bat
src/DEPLOY_SECRET
.DS_Store
.DS_Store
.venv
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# SBOL Validator
[![Build Status](https://travis-ci.org/SynBioDex/SBOL-Validator.svg?branch=master)](https://travis-ci.org/SynBioDex/SBOL-Validator)
A web-based validator for SBOL files backed by libSBOLj's validation runtimes. This validator offers support for SBOL2, SBOL1.1, and GenBank.
A web-based validator for SBOL files backed by the [SBOL-Converter](https://github.com/SynBioDex/SBOL-Converter), which bundles libSBOLj (SBOL2) and libSBOLj3 (SBOL3). This validator offers support for SBOL3, SBOL2, SBOL1.1, GenBank, FASTA, and GFF3, including conversion between them.
Furthermore, it is accessible through a web GUI or a RESTful API.

The validator can be found [here](https://validator.sbolstandard.org) with an API endpoint found at `https://validator.sbolstandard.org/validate`.

### Validation engine
The backend shells out to `src/sbol-converter.jar`, the `jar-with-dependencies` build of the [SBOL-Converter](https://github.com/SynBioDex/SBOL-Converter) (which bundles libSBOLj and libSBOLj3). To update it, download the latest `sbol-converter-*-jar-with-dependencies.jar` asset from the [SBOL-Converter releases](https://github.com/SynBioDex/SBOL-Converter/releases) and replace `src/sbol-converter.jar`. A Java 21+ runtime is required.

### Installation
First, bit about the way the application is structured.
There are two main parts:
Expand Down
2 changes: 1 addition & 1 deletion docker/converter.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3.9-alpine

RUN apk add nginx openjdk17-jre python3-dev build-base linux-headers pcre-dev bash
RUN apk add nginx openjdk21-jre python3-dev build-base linux-headers pcre-dev bash

WORKDIR /opt/SBOL-Validator

Expand Down
2 changes: 1 addition & 1 deletion docker/validator.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3.9-alpine

RUN apk add nginx openjdk17-jre python3-dev build-base linux-headers pcre-dev bash
RUN apk add nginx openjdk21-jre python3-dev build-base linux-headers pcre-dev bash

WORKDIR /opt/SBOL-Validator

Expand Down
7 changes: 2 additions & 5 deletions src/conversion-form/html/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,13 @@ <h3 class="panel-title">
</h3>
</div>
<div class="panel-body">
<div
class="form-group" id="fileOptions">
<!--
<div class="form-group" id="fileOptions">
<div class="radio">
<label>
<input type="radio" name="output" value="SBOL3" id="sbol32" /> Output SBOL 3
<br />
</label>
</div>
-->
</div>
<div class="radio">
<label>
<input type="radio" name="output" value="SBOL2" id="sbol20" checked="checked" /> Output SBOL 2
Expand Down
Binary file removed src/libSBOLj.jar
Binary file not shown.
Binary file added src/sbol-converter.jar
Binary file not shown.
3 changes: 1 addition & 2 deletions src/validation-form/html/form.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,12 @@ <h3 class="panel-title">
</div>
<div class="panel-body">
<div class="form-group" id="fileOptions">
<!-- <div class="radio">
<div class="radio">
<label>
<input type="radio" name="output" value="SBOL3" id="sbol32" /> Output SBOL 3
<br />
</label>
</div>
-->
<div class="radio">
<label>
<input type="radio" name="output" value="SBOL2" id="sbol20" checked="checked" /> Output SBOL 2
Expand Down
43 changes: 31 additions & 12 deletions src/validator/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@
logger = logging.getLogger(__name__)

class ValidationResult:
# Status lines the SBOL-Converter prints that are not validation errors and should
# not surface to the user (e.g. among a comparison's differences).
STATUS_LINES = frozenset([
"Validation successful, no errors.",
"Either Validate or Convert to/from SBOL2",
])

def __init__(self, output_file, equality):
self.check_equality = equality
self.output_file = output_file
self.valid = False
self.errors = []

def digest_errors(self, output):
self.errors = output.strip().split('\n')
self.errors = [
line for line in output.strip().split('\n')
if line.strip() and line.strip() not in self.STATUS_LINES
]

def decipher(self, output, options):
if self.check_equality:
Expand All @@ -33,16 +43,24 @@ def decipher(self, output, options):
else:
self.equal = True

if "Validation successful, no errors." not in output:
self.valid = False
succeeded = "Validation successful, no errors." in output

# The SBOL-Converter is silent on a successful conversion (e.g. SBOL2<->SBOL3)
# and exits non-zero on any error, so reaching this point with a written
# output file signals success even without the validation message.
if not succeeded and options.return_file:
succeeded = os.path.exists(options.output_file) and os.path.getsize(options.output_file) > 0

if succeeded:
self.digest_errors(output)
else:
self.digest_errors(output.strip(u"Validation successful, no errors."))
self.valid = True

if options.return_file:
if options.return_file and os.path.exists(options.output_file):
with open(options.output_file, 'r') as file:
self.result = file.read()
else:
self.valid = False
self.digest_errors(output)

def broken_validation_request(self, command):
self.valid = False
Expand All @@ -62,14 +80,15 @@ def execute(self):

# Attempt to run command
try:
command = self.options.command("libSBOLj.jar", self.validation_file, self.diff_file)
command = self.options.command("sbol-converter.jar", self.validation_file, self.diff_file)
logger.info("Running command: %s", " ".join(command))
output = subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT)
try:
output = subprocess.check_output(command, universal_newlines=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exception:
# The SBOL-Converter exits non-zero both for an invalid document and when a
# comparison finds differences; decipher classifies each from the output.
output = exception.output
result.decipher(output, self.options)
except subprocess.CalledProcessError as exception:
#If the command fails, the file is not valid.
result.valid = False
result.errors += [exception.output, ]
except ValueError as ve:
print(traceback.print_tb(ve.__traceback__))
result.broken_validation_request(command)
Expand Down