Skip to content

Commit

Permalink
Merge pull request #9 from MetabolicAtlas/feat/memote-docker
Browse files Browse the repository at this point in the history
feat: use dockerized memote setup
  • Loading branch information
mihai-sysbio authored Mar 14, 2023
2 parents 641e194 + be22f8e commit d8059e3
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 70 deletions.
59 changes: 28 additions & 31 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
jobs:
setup:
runs-on: ubuntu-latest
container:
image: ghcr.io/metabolicatlas/memote-docker:0.13
volumes:
- ${{ github.workspace }}:/project:rw
options: --user root --workdir /project
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
env:
Expand All @@ -19,27 +24,32 @@ jobs:
with:
fetch-depth: 1

- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: "3.x"

- name: Install dependencies
run: pip install -r requirements.txt
- name: Fetch list of repositories
run: |
git config --global --add safe.directory /__w/standard-GEM-validation/standard-GEM-validation
python -c 'import runner; runner.matrix()'
- id: set-matrix
run: echo "matrix=$(python -c 'import runner; runner.matrix()')" >> $GITHUB_OUTPUT

- name: Cache pip directory
uses: actions/cache@v3
id: cache
- name: Commit index of standard-GEMs
uses: stefanzweifel/git-auto-commit-action@v4
with:
path: ~/.cache/pip
key: ${{ github.sha }}
commit_user_name: validation-bot
commit_message: update index of standard-GEMs
file_pattern: index.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Define job matrix from index
id: set-matrix
run: echo "matrix=$(cat index.json)" >> $GITHUB_OUTPUT

validate:
needs: setup
runs-on: ubuntu-latest
container:
image: ghcr.io/metabolicatlas/memote-docker:0.13
volumes:
- ${{ github.workspace }}:/project:rw
options: --user root --workdir /project
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -55,23 +65,10 @@ jobs:
with:
fetch-depth: 1

- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: "3.x"

- name: Restore pip cache directory
uses: actions/cache@v3
id: cache
with:
path: ~/.cache/pip
key: ${{ github.sha }}

- name: Install dependencies
run: pip install -r requirements.txt

- name: Validate repository
run: python -c 'import runner; runner.validate("${{ matrix.gem }}")'
run: |
git config --global --add safe.directory /__w/standard-GEM-validation/standard-GEM-validation
python -c 'import runner; runner.validate("${{ matrix.gem }}")'
- name: Update branch
run: git pull --ff
Expand Down
1 change: 1 addition & 0 deletions index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
["SysBioChalmers/yeast-GEM", "SysBioChalmers/Human-GEM", "SysBioChalmers/Fruitfly-GEM", "SysBioChalmers/Mouse-GEM", "SysBioChalmers/Sco-GEM", "SysBioChalmers/Zebrafish-GEM", "iAMB-RWTH-Aachen/Opol-GSMM", "SysBioChalmers/Worm-GEM", "haowang-bioinfo/Ecoli-GEM", "SysBioChalmers/Rat-GEM", "tibbdc/vna-GEM"]
5 changes: 0 additions & 5 deletions requirements.txt

This file was deleted.

19 changes: 12 additions & 7 deletions runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
API_TOKEN = environ['GH_TOKEN']
MODEL_FILENAME = 'model'
MODEL_FORMATS = ['.yml', '.xml', '.mat', '.json']
RELEASES = 10
RELEASES = 1

header_auth = {'Authorization': 'token %s' % API_TOKEN}
additional_branch_tags = []
Expand Down Expand Up @@ -59,7 +59,8 @@ def releases(nameWithOwner):

def matrix():
m = json.dumps(list(gem_repositories()))
print(m)
with open("index.json", "w") as file:
file.write(m)

def gem_follows_standard(nameWithOwner, release, version):
repo_standard = requests.get('https://raw.githubusercontent.com/{}/{}/.standard-GEM.md'.format(nameWithOwner, release))
Expand All @@ -86,12 +87,16 @@ def validate(nameWithOwner):
if gem_is_standard:
for model_format in MODEL_FORMATS:
my_model = model + model_format
response = requests.get('https://raw.githubusercontent.com/{}/{}/model/{}'.format(nameWithOwner, model_release, my_model))
with open(my_model, 'w') as file:
file.write(response.text)
response = requests.get('https://raw.githubusercontent.com/{}/{}/model/{}'.format(nameWithOwner, model_release, my_model), timeout=10)
if response.ok:
with open(my_model, 'w') as file:
file.write(response.text)
test_results.update(tests.yaml.validate(model))
test_results.update(tests.cobra.load(model))
test_results.update(tests.cobra.validateSBML(model))
test_results.update(tests.cobra.loadYaml(model))
test_results.update(tests.cobra.loadSbml(model))
test_results.update(tests.cobra.loadMatlab(model))
test_results.update(tests.cobra.loadJson(model))
test_results.update(tests.cobra.validateSbml(model))
test_results.update(tests.memote.scoreAnnotationAndConsistency(model))
else:
print('is not following standard')
Expand Down
61 changes: 46 additions & 15 deletions tests/cobra.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
import cobra
import json
from os.path import exists

def load(model_filename):
print(' load model with cobrapy')
is_valid_cobrapy = False
def loadYaml(model_name):
print('load yaml')
is_valid = False
errors = ''
try:
cobra.io.load_yaml_model(model_filename + '.yml')
cobra.io.read_sbml_model(model_filename + '.xml')
if exists(model_filename + '.mat'):
cobra.io.load_matlab_model(model_filename + '.mat')
if exists(model_filename + '.json'):
cobra.io.load_json_model(model_filename + '.json')
is_valid_cobrapy = True
cobra.io.load_yaml_model(model_name + '.yml')
is_valid = True
except Exception as e:
errors = json.dumps(str(e))
print(e)
return {'cobrapy-load': { cobra.__version__ : is_valid_cobrapy, 'errors': errors } }
return {'cobrapy-load-yaml': { cobra.__version__ : is_valid, 'errors': errors } }

def validateSBML(model_filename):
print(' validate sbml with cobrapy')
def loadSbml(model_name):
print('load sbml')
is_valid = False
errors = ''
try:
cobra.io.read_sbml_model(model_name + '.xml')
is_valid = True
except Exception as e:
errors = json.dumps(str(e))
print(e)
return {'cobrapy-load-sbml': { cobra.__version__ : is_valid, 'errors': errors } }

def loadMatlab(model_name):
print('load matlab')
is_valid = False
errors = ''
try:
cobra.io.load_matlab_model(model_name + '.mat')
is_valid = True
except Exception as e:
errors = json.dumps(str(e))
print(e)
return {'cobrapy-load-matlab': { cobra.__version__ : is_valid, 'errors': errors } }

def loadJson(model_name):
print('load json')
is_valid = False
errors = ''
try:
cobra.io.load_json_model(model_name + '.json')
is_valid = True
except Exception as e:
errors = json.dumps(str(e))
print(e)
return {'cobrapy-load-json': { cobra.__version__ : is_valid, 'errors': errors } }


def validateSbml(model_name):
print('validate sbml with cobrapy')
is_valid_sbml = False
try:
_, result = cobra.io.sbml.validate_sbml_model(model_filename + '.xml')
_, result = cobra.io.sbml.validate_sbml_model(model_name + '.xml')
if result != {}:
raise Exception(result)
except Exception as e:
Expand Down
13 changes: 7 additions & 6 deletions tests/memote.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
import json
import memote

def scoreAnnotationAndConsistency(model_filename):
print(' memote scoring')
memote_score = 'Scoring failed'
def scoreAnnotationAndConsistency(model_name):
print('memote scoring')
memote_score = False
errors = ''
try:
model = cobra.io.read_sbml_model(model_filename + '.xml')
_, results = memote.suite.api.test_model(model, None, True, None, {"basic", "annotation", "consistency"})
processed_results = memote.suite.api.snapshot_report(results, None, False)
model = cobra.io.read_sbml_model(model_name + '.xml')
_, results = memote.suite.api.test_model(model=model, results=True, exclusive=['test_stoichiometric_consistency', 'test_reaction_mass_balance', 'test_reaction_charge_balance', 'test_find_disconnected', 'test_find_reactions_unbounded_flux_default_condition', 'test_metabolite_annotation_presence', 'test_metabolite_annotation_overview', 'test_metabolite_annotation_wrong_ids', 'test_metabolite_id_namespace_consistency', 'test_reaction_annotation_presence', 'test_reaction_annotation_overview', 'test_reaction_annotation_wrong_ids', 'test_reaction_id_namespace_consistency', 'test_gene_product_annotation_presence', 'test_gene_product_annotation_overview', 'test_gene_product_annotation_wrong_ids', 'test_model_id_presence', 'test_metabolites_presence', 'test_reactions_presence', 'test_genes_presence', 'test_compartments_presence', 'test_metabolic_coverage', 'test_unconserved_metabolites', 'test_inconsistent_min_stoichiometry', 'test_find_unique_metabolites', 'test_find_duplicate_metabolites_in_compartments', 'test_metabolites_charge_presence', 'test_metabolites_formula_presence', 'test_find_medium_metabolites', 'test_find_pure_metabolic_reactions', 'test_find_constrained_pure_metabolic_reactions', 'test_find_transport_reactions', 'test_find_constrained_transport_reactions', 'test_find_candidate_irreversible_reactions', 'test_find_reactions_with_partially_identical_annotations', 'test_find_duplicate_reactions', 'test_find_reactions_with_identical_genes'])
processed_results = memote.suite.api.snapshot_report(results, config=None, html=False)
results_json = json.loads(processed_results)
print(results_json['score'])
memote_score = results_json['score']['total_score']
except Exception as e:
errors = json.dumps(str(e))
Expand Down
13 changes: 7 additions & 6 deletions tests/yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
from yamllint.config import YamlLintConfig
import json

def validate(model_filename):
print(' validate YAML with yamllint')
is_valid_yaml = False
def validate(model_name):
print('validate YAML with yamllint')
is_valid = False
errors = ''
try:
conf = YamlLintConfig('{extends: default, rules: {line-length: disable}}')
with open(model_filename + '.yml', 'r') as file:
with open(model_name + '.yml', 'r') as file:
errors = list(map(str, yamllint.linter.run(file, conf)))
if len(errors) == 0:
is_valid_yaml = True
is_valid = True
else:
errors = json.dumps(errors)
except Exception as e:
errors = json.dumps(str(e))
print(e)
return {'yamllint': { yamllint.__version__ : str(is_valid_yaml), 'errors': errors } }
return {'yamllint': { yamllint.__version__ : is_valid, 'errors': errors } }

0 comments on commit d8059e3

Please sign in to comment.