Skip to content

Commit

Permalink
moving collecting of Git repo metadata to utils and io so that wc_kb …
Browse files Browse the repository at this point in the history
…can be used without Git and from any directory
  • Loading branch information
jonrkarr committed Apr 23, 2018
1 parent 359e447 commit 30da423
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 42 deletions.
3 changes: 2 additions & 1 deletion tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def test_ComplexSpeciesType(self):
species2 = core.Species(species_type=prot2, compartment=comp1)
species_coeff1 = core.SpeciesCoefficient(species=species1, coefficient=2)
species_coeff2 = core.SpeciesCoefficient(species=species2, coefficient=3)
reaction1 = core.Reaction(participants=[species_coeff1,species_coeff2])
reaction1 = core.Reaction(participants=[species_coeff1, species_coeff2])
complex1.formation_reaction = reaction1

self.assertEqual(complex1.get_subunits(), [prot1, prot1, prot2, prot2, prot2])
Expand All @@ -579,5 +579,6 @@ def test_ComplexSpeciesType(self):
# test get_empirical_formula
self.assertEqual(complex1.get_empirical_formula(), chem.EmpiricalFormula('C273H408N76O82S2'))


class ReactionParticipantAttributeTestCase(unittest.TestCase):
def test_ReactionParticipantAttribute(self): pass
14 changes: 7 additions & 7 deletions tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ def test_write_read(self):
seq_path = os.path.join(self.dir, 'seq.fna')

writer = io.Writer()
writer.run(self.kb, core_path, seq_path)
writer.run(self.kb, core_path, seq_path, set_repo_metadata_from_path=False)

reader = io.Reader()
kb = reader.run(core_path, seq_path)

core_path = os.path.join(self.dir, 'core2.xlsx')
seq_path = os.path.join(self.dir, 'seq2.fna')
writer.run(kb, core_path, seq_path)
writer.run(kb, core_path, seq_path, set_repo_metadata_from_path=False)

self.assertTrue(self.kb.is_equal(kb))

Expand All @@ -79,14 +79,14 @@ def test_write_without_cell_relationships(self):

writer = io.Writer()
with self.assertRaisesRegexp(ValueError, 'must be set to the instance of `Cell`'):
writer.run(self.kb, core_path, seq_path)
writer.run(self.kb, core_path, seq_path, set_repo_metadata_from_path=False)

def test_write_read_sloppy(self):
core_path = os.path.join(self.dir, 'core.xlsx')
seq_path = os.path.join(self.dir, 'seq.fna')

writer = io.Writer()
writer.run(self.kb, core_path, seq_path)
writer.run(self.kb, core_path, seq_path, set_repo_metadata_from_path=False)

wb = wc_utils.workbook.io.read(core_path)
row = wb['Knowledge base'].pop(0)
Expand Down Expand Up @@ -166,7 +166,7 @@ def test_convert(self):
path_seq_2 = os.path.join(self.dir, 'seq_2.fna')
path_seq_3 = os.path.join(self.dir, 'seq_3.fna')

io.Writer().run(self.kb, path_core_1, path_seq_1)
io.Writer().run(self.kb, path_core_1, path_seq_1, set_repo_metadata_from_path=False)

io.convert(path_core_1, path_seq_1, path_core_2, path_seq_2)
kb = io.Reader().run(path_core_2, path_seq_2)
Expand All @@ -184,7 +184,7 @@ def test_convert_sloppy(self):
path_seq_2 = os.path.join(self.dir, 'seq_2.fna')
path_seq_3 = os.path.join(self.dir, 'seq_3.fna')

io.Writer().run(self.kb, path_core_1, path_seq_1)
io.Writer().run(self.kb, path_core_1, path_seq_1, set_repo_metadata_from_path=False)

wb = wc_utils.workbook.io.read(path_core_1)
row = wb['Knowledge base'].pop(0)
Expand All @@ -204,7 +204,7 @@ def test_convert_sloppy(self):
def test_create_template(self):
path_core = os.path.join(self.dir, 'core.xlsx')
path_seq = os.path.join(self.dir, 'seq.fna')
io.create_template(path_core, path_seq)
io.create_template(path_core, path_seq, set_repo_metadata_from_path=False)
kb = io.Reader().run(path_core, path_seq)

def test_validate_implicit_relationships(self):
Expand Down
22 changes: 11 additions & 11 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_validate(self):
self.assertEqual(Validator().run(kb, get_related=True), None)
filename_core = path.join(self.tempdir, 'core.xlsx')
filename_seq = path.join(self.tempdir, 'seq.fna')
io.Writer().run(kb, filename_core, filename_seq)
io.Writer().run(kb, filename_core, filename_seq, set_repo_metadata_from_path=False)

with CaptureOutput() as capturer:
with __main__.App(argv=['validate', filename_core, filename_seq]) as app:
Expand All @@ -53,7 +53,7 @@ def test_validate_exception(self):
self.assertNotEqual(Validator().run(kb, get_related=True), None)
filename_core = path.join(self.tempdir, 'core.xlsx')
filename_seq = path.join(self.tempdir, 'seq.fna')
io.Writer().run(kb, filename_core, filename_seq)
io.Writer().run(kb, filename_core, filename_seq, set_repo_metadata_from_path=False)

with self.assertRaisesRegexp(ValueError, '^Knowledge base is invalid: '):
with __main__.App(argv=['validate', filename_core, filename_seq]) as app:
Expand All @@ -63,17 +63,17 @@ def test_difference(self):
kb1 = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.0')
filename_core_1 = path.join(self.tempdir, 'core1.xlsx')
filename_seq_1 = path.join(self.tempdir, 'seq1.fna')
io.Writer().run(kb1, filename_core_1, filename_seq_1)
io.Writer().run(kb1, filename_core_1, filename_seq_1, set_repo_metadata_from_path=False)

kb2 = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.0')
filename_core_2 = path.join(self.tempdir, 'core2.xlsx')
filename_seq_2 = path.join(self.tempdir, 'seq2.fna')
io.Writer().run(kb2, filename_core_2, filename_seq_2)
io.Writer().run(kb2, filename_core_2, filename_seq_2, set_repo_metadata_from_path=False)

kb3 = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.1')
filename_core_3 = path.join(self.tempdir, 'core3.xlsx')
filename_seq_3 = path.join(self.tempdir, 'seq3.fna')
io.Writer().run(kb3, filename_core_3, filename_seq_3)
io.Writer().run(kb3, filename_core_3, filename_seq_3, set_repo_metadata_from_path=False)

with CaptureOutput() as capturer:
with __main__.App(argv=['difference',
Expand Down Expand Up @@ -117,7 +117,7 @@ def test_normalize(self):
filename_seq_2 = path.join(self.tempdir, 'seq-2.fna')

kb = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.0')
io.Writer().run(kb, filename_core_1, filename_seq_1)
io.Writer().run(kb, filename_core_1, filename_seq_1, set_repo_metadata_from_path=False)

# with same dest
with __main__.App(argv=['normalize', filename_core_1, filename_seq_1]) as app:
Expand All @@ -141,7 +141,7 @@ def test_convert(self):
filename_out_seq = path.join(self.tempdir, 'out.seq.fna')

kb = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.0')
io.Writer().run(kb, filename_in_core, filename_in_seq)
io.Writer().run(kb, filename_in_core, filename_in_seq, set_repo_metadata_from_path=False)

with __main__.App(argv=['convert',
filename_in_core, filename_in_seq,
Expand All @@ -155,21 +155,21 @@ def test_create_template(self):
filename_core = path.join(self.tempdir, 'core.xlsx')
filename_seq = path.join(self.tempdir, 'seq.fna')

with __main__.App(argv=['create-template', filename_core, filename_seq]) as app:
with __main__.App(argv=['create-template', filename_core, filename_seq, '--ignore-repo-metadata']) as app:
app.run()

self.assertTrue(path.isfile(filename_core))
self.assertTrue(path.isfile(filename_seq))

def test_update_wc_kb_version(self):
def test_update_version_metadata(self):
filename_core = path.join(self.tempdir, 'core.xlsx')
filename_seq = path.join(self.tempdir, 'seq.fna')

kb = wc_kb.KnowledgeBase(id='kb', name='KB', version='0.0.1a', wc_kb_version='0.0.0')
self.assertNotEqual(kb.wc_kb_version, wc_kb.__version__)
io.Writer().run(kb, filename_core, filename_seq)
io.Writer().run(kb, filename_core, filename_seq, set_repo_metadata_from_path=False)

with __main__.App(argv=['update-wc-kb-version', filename_core, filename_seq]) as app:
with __main__.App(argv=['update-version-metadata', filename_core, filename_seq, '--ignore-repo-metadata']) as app:
app.run()

kb = io.Reader().run(filename_core, filename_seq)
Expand Down
25 changes: 25 additions & 0 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from wc_kb import core
from wc_kb import util
import shutil
import tempfile
import unittest


Expand All @@ -20,3 +22,26 @@ def test_get_models(self):

self.assertIn(core.KnowledgeBase, util.get_models(inline=False))
self.assertIn(core.Cell, util.get_models(inline=False))

def test_set_git_repo_metadata_from_path(self):
kb = core.KnowledgeBase()
self.assertEqual(kb.url, '')

util.set_git_repo_metadata_from_path(kb, path='.')
self.assertIn(kb.url, [
'https://github.com/KarrLab/wc_kb.git',
'ssh://git@github.com/KarrLab/wc_kb.git',
'git@github.com:KarrLab/wc_kb.git',
])

def test_set_git_repo_metadata_from_path_error(self):
tempdir = tempfile.mkdtemp()

kb = core.KnowledgeBase()
self.assertEqual(kb.url, '')

with self.assertRaisesRegexp(ValueError, 'is not a Git repository'):
util.set_git_repo_metadata_from_path(kb, path=tempdir)
self.assertEqual(kb.url, '')

shutil.rmtree(tempdir)
28 changes: 17 additions & 11 deletions wc_kb/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ def default(self):
args = self.app.pargs
kb = io.Reader().run(args.source_core, args.source_seq, strict=args.strict)
if args.dest_core or args.dest_seq:
io.Writer().run(kb, args.dest_core, args.dest_seq)
io.Writer().run(kb, args.dest_core, args.dest_seq, set_repo_metadata_from_path=False)
else:
io.Writer().run(kb, args.source_core, args.source_seq)
io.Writer().run(kb, args.source_core, args.source_seq, set_repo_metadata_from_path=False)


class ConvertController(CementBaseController):
Expand Down Expand Up @@ -159,27 +159,33 @@ class Meta:
stacked_on = 'base'
stacked_type = 'nested'
arguments = [
(['path_core'], dict(type=str, help='Path to save a template of the core of a knowledge base')),
(['path_seq'], dict(type=str, help='Path to save a template of the genome sequence of a knowledge base')),
(['path_core'], dict(metavar='path-core', type=str, help='Path to save a template of the core of a knowledge base')),
(['path_seq'], dict(metavar='path-seq', type=str, help='Path to save a template of the genome sequence of a knowledge base')),
(['--ignore-repo-metadata'], dict(dest='set_repo_metadata_from_path', default=True, action='store_false',
help=('If set, do not set the Git repository metadata for the knowledge base from '
'the parent directory of `path-core`'))),
]

@expose(hide=True)
def default(self):
args = self.app.pargs
io.create_template(args.path_core, args.path_seq)
io.create_template(args.path_core, args.path_seq, set_repo_metadata_from_path=args.set_repo_metadata_from_path)


class UpdateWcKbVersionController(CementBaseController):
""" Update wc_kb_version of a knowledge base """
class UpdateVersionMetadataController(CementBaseController):
""" Update version metadata of a knowledge base (URL, branch, revision, wc_kb version) """

class Meta:
label = 'update-wc-kb-version'
description = 'Update wc_kb_version of a knowledge base'
label = 'update-version-metadata'
description = 'Update version metadata of a knowledge base (URL, branch, revision, wc_kb version)'
stacked_on = 'base'
stacked_type = 'nested'
arguments = [
(['path_core'], dict(type=str, help='Path to the core of the knowledge base')),
(['path_seq'], dict(type=str, help='Path to the FASTA-formatted genome sequence of a knowledge base')),
(['--ignore-repo-metadata'], dict(dest='set_repo_metadata_from_path', default=True, action='store_false',
help=('If set, do not set the Git repository metadata for the knowledge base from '
'the parent directory of `path-core`'))),
(['--sloppy'], dict(dest='strict', default=True, action='store_false',
help='If set, do not validate the format of the knowledge base file(s)')),
]
Expand All @@ -189,7 +195,7 @@ def default(self):
args = self.app.pargs
kb = io.Reader().run(args.path_core, args.path_seq, strict=args.strict)
kb.wc_kb_version = wc_kb.__version__
io.Writer().run(kb, args.path_core, args.path_seq)
io.Writer().run(kb, args.path_core, args.path_seq, set_repo_metadata_from_path=args.set_repo_metadata_from_path)


class App(CementApp):
Expand All @@ -204,7 +210,7 @@ class Meta:
NormalizeController,
ConvertController,
CreateTemplateController,
UpdateWcKbVersionController,
UpdateVersionMetadataController,
]


Expand Down
5 changes: 0 additions & 5 deletions wc_kb/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"""

from wc_utils.util import chem
import wc_utils.util.git as git
import abc
import Bio.Seq
import Bio.SeqUtils
Expand Down Expand Up @@ -125,10 +124,6 @@ class Meta(obj_model.core.Model.Meta):
tabular_orientation = obj_model.core.TabularOrientation.column

def __init__(self, **kwargs):
md = git.get_repo_metadata()
self.url = md.url
self.branch = md.branch
self.revision = md.revision
super(KnowledgeBase, self).__init__(**kwargs)


Expand Down
23 changes: 16 additions & 7 deletions wc_kb/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"""

from . import core
from . import util
from wc_utils.util.string import indent_forest
import Bio.SeqIO
import Bio.SeqRecord
Expand Down Expand Up @@ -41,13 +42,15 @@ class Writer(object):
core.Reaction,
)

def run(self, knowledge_base, core_path, seq_path):
def run(self, knowledge_base, core_path, seq_path, set_repo_metadata_from_path=True):
""" Write knowledge base to file(s)
Args:
knowledge_base (:obj:`core.KnowledgeBase`): knowledge base
core_path (:obj:`str`): path to save core knowledge base
seq_path (:obj:`str`): path to save genome sequence
set_repo_metadata_from_path (:obj:`bool`, optional): if :obj:`True`, set the Git repository metadata (URL,
branch, revision) for the knowledge base from the parent directory of :obj:`core_path`
Raises:
:obj:`ValueError`: if any of the relationships with knowledge bases and cells are not set
Expand All @@ -66,6 +69,10 @@ def run(self, knowledge_base, core_path, seq_path):
if val is None or val != cell:
raise ValueError('{}.{} must be set to the instance of `Cell`'.format(obj.__class__.__name__, attr.name))

# set Git repository metadata from the parent directories of :obj:`core_path`
if set_repo_metadata_from_path:
util.set_git_repo_metadata_from_path(knowledge_base, core_path)

# gather DNA sequences
dna_seqs = []
if cell:
Expand Down Expand Up @@ -135,8 +142,8 @@ def run(self, core_path, seq_path, strict=True):
Args:
core_path (:obj:`str`): path to core knowledge base
seq_path (:obj:`str`): path to genome sequence
strict (:obj:`str`, optional): if :obj:`True`, validate that the the model file(s) strictly follow the
seq_path (:obj:`str`): path to genome sequence
strict (:obj:`bool`, optional): if :obj:`True`, validate that the the model file(s) strictly follow the
:obj:`obj_model` serialization format:
* The worksheets are in the expected order
Expand Down Expand Up @@ -241,7 +248,7 @@ def convert(source_core, source_seq, dest_core, dest_seq, strict=True):
source_seq (:obj:`str`): path to the genome sequence of the source knowledge base
dest_core (:obj:`str`): path to save the converted core of the knowledge base
dest_seq (:obj:`str`): path to save the converted genome sequence of the knowledge base
strict (:obj:`str`, optional): if :obj:`True`, validate that the the model file(s) strictly follow the
strict (:obj:`bool`, optional): if :obj:`True`, validate that the the model file(s) strictly follow the
:obj:`obj_model` serialization format:
* The worksheets are in the expected order
Expand All @@ -252,15 +259,17 @@ def convert(source_core, source_seq, dest_core, dest_seq, strict=True):
* There are no extra columns
"""
kb = Reader().run(source_core, source_seq, strict=strict)
Writer().run(kb, dest_core, dest_seq)
Writer().run(kb, dest_core, dest_seq, set_repo_metadata_from_path=False)


def create_template(core_path, seq_path):
def create_template(core_path, seq_path, set_repo_metadata_from_path=True):
""" Create file with knowledge base template, including row and column headings
Args:
core_path (:obj:`str`): path to save temploate of core knowledge base
seq_path (:obj:`str`): path to save genome sequence
set_repo_metadata_from_path (:obj:`bool`, optional): if :obj:`True`, set the Git repository metadata (URL,
branch, revision) for the knowledge base from the parent directory of :obj:`core_path`
"""
kb = core.KnowledgeBase(id='template', name='Template', version=wc_kb.__version__)
Writer().run(kb, core_path, seq_path)
Writer().run(kb, core_path, seq_path, set_repo_metadata_from_path=set_repo_metadata_from_path)
15 changes: 15 additions & 0 deletions wc_kb/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
"""

from . import core
from wc_utils.util import git
import obj_model.core


def get_models(inline=True):
""" Get list of models
Expand All @@ -20,3 +22,16 @@ def get_models(inline=True):
"""

return obj_model.core.get_models(module=core, inline=inline)


def set_git_repo_metadata_from_path(kb, path='.'):
""" Use Git to set the Git repository URL, branch, and revision metadata for a knowledge base
Args:
kb (:obj:`core.KnowledgeBase`): knowledge base
path (:obj:`str`, optional): path to the Git repository for the knowledge base
"""
md = git.get_repo_metadata(dirname=path)
kb.url = md.url
kb.branch = md.branch
kb.revision = md.revision

0 comments on commit 30da423

Please sign in to comment.