Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Metadata fbc3 #1237

Open
wants to merge 122 commits into
base: devel
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
782b645
added annotation class
Hemant27031999 Jun 4, 2020
9709974
made some modifications
Hemant27031999 Jun 4, 2020
a7af772
made the complete metadata package
Hemant27031999 Jun 9, 2020
a191413
modified meta_data classes
Hemant27031999 Jun 10, 2020
4ea5b3e
modified classes to look exactly like dictionaries and lists
Hemant27031999 Jun 11, 2020
7795ea6
modified imports and incorporated SBO term in metadata
Hemant27031999 Jun 11, 2020
02345bb
made the classed to inherit from MutableSequence and MutableMapping
Hemant27031999 Jun 13, 2020
4c6c1ca
adding backward compatibility
Hemant27031999 Jun 15, 2020
ff72c55
added instance
Hemant27031999 Jun 15, 2020
989ffe4
work on annotation structure
matthiaskoenig Jun 15, 2020
a4eb840
adding json example
matthiaskoenig Jun 15, 2020
cf38e02
fixed instance2
Hemant27031999 Jun 15, 2020
7d490a4
work on cvterms
matthiaskoenig Jun 15, 2020
024c980
made backward compatible
Hemant27031999 Jun 18, 2020
ff440fb
code review metadata
matthiaskoenig Jun 18, 2020
e4ad484
cleaned the metadata class by putting code in respective classes
Hemant27031999 Jun 21, 2020
2508ac3
new annotation format supported for SBML to cobra model
Hemant27031999 Jun 23, 2020
d5fc54c
added io for json and other formats
Hemant27031999 Jun 24, 2020
c9e904b
added tests for new annotation format
Hemant27031999 Jun 25, 2020
a6e2f8a
updated history
matthiaskoenig Jun 25, 2020
23f9699
fixing broken tests
Hemant27031999 Jun 28, 2020
2f55bbf
commented a few methods
Hemant27031999 Jun 28, 2020
5aae1b0
added equal method inisde metadata classes
Hemant27031999 Jun 29, 2020
d467a14
modified directories paths
Hemant27031999 Jun 30, 2020
e4cc72b
fixed imports and tox tests
Hemant27031999 Jun 30, 2020
32a81da
solved the problem of annotation copy
Hemant27031999 Jul 1, 2020
a07ccaf
new notes format
Hemant27031999 Jul 2, 2020
f69a55c
code refactoring
matthiaskoenig Jul 2, 2020
e4ab40b
modified history, keyvaluepair and notes
Hemant27031999 Jul 4, 2020
8dc96cf
modified tests and imports
Hemant27031999 Jul 5, 2020
a3685d4
modified cvterm class
Hemant27031999 Jul 6, 2020
991123b
small fixes
matthiaskoenig Jul 9, 2020
70b33db
refactored a few names
Hemant27031999 Jul 12, 2020
0e20a91
modified notes documentation
Hemant27031999 Jul 15, 2020
eeee56a
added user defined constraint class
Hemant27031999 Jul 16, 2020
f93723b
example test cases
matthiaskoenig Jul 16, 2020
efcf064
added tests for UserDefinedConstraints
Hemant27031999 Jul 23, 2020
3039344
modified tests
Hemant27031999 Jul 23, 2020
d5dedc9
small modifications
Hemant27031999 Jul 26, 2020
f839755
moved cobra directory to src directory
Hemant27031999 Jul 26, 2020
9704a4b
solved conflicts
Hemant27031999 Jul 26, 2020
211bf48
fixed some tests
Hemant27031999 Jul 26, 2020
1dba21e
fixed conflicts and tests
Hemant27031999 Jul 26, 2020
90c156f
fixed tests
Hemant27031999 Jul 27, 2020
91177cd
added support of group to JSON
Hemant27031999 Jul 27, 2020
1fc7ab2
added support for optional ids in UserDefinedConstraint class
Hemant27031999 Jul 28, 2020
de2398d
added test for json validation function
Hemant27031999 Jul 30, 2020
54809ad
added json schema import requirement
Hemant27031999 Jul 30, 2020
c758bc5
added helper function for UserDefinedConstraint
Hemant27031999 Jul 30, 2020
5c5e2c2
added validate function for json models
Hemant27031999 Jul 30, 2020
0884f4a
added ast tree for parsing constraint expression
Hemant27031999 Aug 5, 2020
0f93cdd
modified json validation function
Hemant27031999 Aug 6, 2020
3da58be
removed python 2 support
Hemant27031999 Aug 6, 2020
8ec5ef2
modified ids in json
Hemant27031999 Aug 6, 2020
d2d8ee9
code refactoring
matthiaskoenig Aug 6, 2020
14a68f5
reformatted code to python 3
Hemant27031999 Aug 9, 2020
80fdcaa
added datetime validation for py3.6
Hemant27031999 Aug 15, 2020
06cb989
modified dict.py
Hemant27031999 Aug 15, 2020
c10f3fa
modified xfail
Hemant27031999 Aug 15, 2020
1747a7b
removed .idea files
Hemant27031999 Aug 15, 2020
14a1415
removed .idea
Hemant27031999 Aug 15, 2020
ba2990c
merged with devel
Hemant27031999 Aug 16, 2020
b04b81a
removed idea
Hemant27031999 Aug 16, 2020
6bae4c0
modified notes string passing
Hemant27031999 Aug 21, 2020
66dd463
modified notes return type
Hemant27031999 Aug 26, 2020
479c2b2
adding dependency for json validation
matthiaskoenig Aug 26, 2020
543d1f8
added .idea files
matthiaskoenig Aug 26, 2020
65e48f1
merged latest devel
matthiaskoenig Aug 26, 2020
564a51a
refactored and cleanup of history
matthiaskoenig Aug 26, 2020
a6aefc5
Intermediate refactoring, breaking changes
matthiaskoenig Aug 26, 2020
42f4838
refactored keyvaluepairs
matthiaskoenig Aug 26, 2020
b3e26cc
cleanup of datetimes
matthiaskoenig Aug 26, 2020
ca9ef48
cleanup metadata
matthiaskoenig Aug 26, 2020
093f799
cleanup dict methods
matthiaskoenig Aug 26, 2020
b5f7516
added to_dict for CVTerm and fixed models
Hemant27031999 Aug 27, 2020
c8b850a
added metadata.ipynb
Hemant27031999 Aug 27, 2020
67d3af1
fixed imports
Hemant27031999 Aug 27, 2020
b951dbd
Merge branch 'devel' into metadata_fbc3_group
Hemant27031999 Aug 27, 2020
e5b3fba
smaller fix to_dict usage
matthiaskoenig Aug 27, 2020
8b2d6dc
modified to_dict for cvterms
Hemant27031999 Aug 28, 2020
010bb44
separated UserDefinedConstraint
Hemant27031999 Aug 28, 2020
fbfb0e8
Merge branch 'devel' into metadata_fbc3_group
May 11, 2022
78ea3d8
fixed most of the merging errors - most tests work
May 11, 2022
841c264
fixed test_annotation_format.py and deleted previous version
May 11, 2022
4fa107a
fixed SBML problems with merge
May 11, 2022
75a2193
fixed field names of creators
May 12, 2022
0237fae
Merge branch 'devel' into metadata_fbc3
Jun 16, 2022
2b021b6
fixed data, e_coli_new_format.json, schema_v2.json and some code chan…
May 12, 2022
f4b6894
consistent schema_v2.json
May 12, 2022
410f758
merged devel into #988 and updated it to current code
May 12, 2022
8c2f992
removed Notes as class
Jun 18, 2022
095654d
renamed constructors as requested
Jun 19, 2022
166dc1b
isort and black
Jun 19, 2022
e2e1bb5
isort error again
Jun 19, 2022
771e43e
sorry, updating salmonella.xml broke test_delete.py
Jun 19, 2022
e9cabd5
fix gitignore
Jun 19, 2022
0d72e42
documentation
Jun 27, 2022
a2a95bb
incorporated changes from fixing mat PR
Jun 28, 2022
03f4230
keyvaluepairs.py is documented
Jun 28, 2022
5313d3a
history.py is documented
Jun 30, 2022
2bc23ae
black on reaction.py
Jul 1, 2022
44c8dc7
removed notes.py and fixed some small bugs
Jul 4, 2022
024795f
creator is NamedTuple and has simpler api
Jul 5, 2022
3058122
replaced HistoryDateTime with standard datetime.datetime class
Jul 5, 2022
e924546
fix HistoryDateTime remaining
Jul 5, 2022
7ad9288
maybe will work better on Python 3.6
Jul 5, 2022
6c54a0d
Merge remote-tracking branch 'upstream/devel' into metadata_fbc3
Jul 6, 2022
c95b8c6
minor bug in history.py
Jul 8, 2022
9d4607f
Revert "minor bug in history.py"
Jul 8, 2022
15b7c5c
trying to fix 3.6 bug
Jul 8, 2022
8248a8d
trying to fix 3.6 bug again
Jul 8, 2022
85bd021
some tidying of sbml.py
Jul 12, 2022
abcafcd
one query for CVTermList as requested
Jul 12, 2022
af5f3fa
better documentation
Jul 14, 2022
dc8d600
almost complete documentation for cvterm.py including CVTerm, CVTermL…
Jul 20, 2022
bc6be3e
some clarification and fixes of cvterm.py
Jul 21, 2022
10dd03c
reorganized metadata.py
Jul 21, 2022
7c79e1c
fixed some changes in tests and example JSON due to changes in code
Jul 21, 2022
8ad6e3d
finished documentation of metadata.py
Jul 24, 2022
f4ffb8f
moved annotation_xml to conftest.py
Jul 25, 2022
0564ffb
fix unification of CVTerms done by sbml
Jul 26, 2022
988148d
simplified custompairs.py
Jul 26, 2022
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
Prev Previous commit
Next Next commit
modified classes to look exactly like dictionaries and lists
  • Loading branch information
Hemant27031999 committed Jun 11, 2020
commit 4ea5b3ee9ed05913ff2116a2d1e8dec951667d96
8 changes: 6 additions & 2 deletions cobra/core/meta_data/cvTerm.py
Original file line number Diff line number Diff line change
@@ -177,8 +177,12 @@ def __setitem__(self, key, value):
raise TypeError("Resources must be put in a list")
dict.__setitem__(self, key, value)
elif key == 'nested_data':
if not isinstance(value, CVTerm):
raise TypeError("The value passed must be of type CVTerm.")
if isinstance(value, CVTerm):
dict.__setitem__(self, key, value)
elif isinstance(value, dict):
dict.__setitem__(self, key, CVTerm(value))
else:
raise TypeError("The value passed has invalid format.")
dict.__setitem__(self, key, value)

def __delitem__(self, key):
86 changes: 55 additions & 31 deletions cobra/core/meta_data/history.py
Original file line number Diff line number Diff line change
@@ -18,10 +18,11 @@ def validateDate(date_text):
return True


class History:
class History(dict):
"""
Class representation of history of a given component i.e. creator,
created date and modification dates
created date and modification dates. It is basically an extended
dictionary with some restrictions

Parameters
----------
@@ -33,7 +34,7 @@ class History:
modified : list
A list of dates about the component modification

Attributes
Allowed Keys
----------
creator : dict
A dictionary containong details of creator's name, email and
@@ -45,49 +46,72 @@ class History:

"""

VALID_KEYS = ["creators", "created", "modified"]

def __init__(self, creators=[], created=None, modified=[]):
if creators is None:
creators = []
self._creators = self.ListOfCreators(creators)
dict.__setitem__(self, "creators", self.ListOfCreators(creators))
if isinstance(created, str):
validateDate(created)
self._created = created
dict.__setitem__(self, "created", created)
elif created is None:
self._created = None
dict.__setitem__(self, "created", None)
else:
raise TypeError('Only None and string types are possible for '
'"created" date attribute')
if modified is None:
modified = []
self._modified = self.ModifiedHistory(modified)

@property
def creators(self):
return self._creators

@creators.setter
def creators(self, creators_list):
self._creators = self.ListOfCreators(creators_list)
dict.__setitem__(self, "modified", self.ModifiedHistory(modified))

def __getitem__(self, key):
if key not in self.VALID_KEYS:
raise ValueError("Key %s is not allowed. Only allowed "
"keys are : 'creators', 'created', 'modified'"
% key)
return dict.__getitem__(self, key)

def __setitem__(self, key, value):
"""Restricting the keys and values that can be set.
Only allowed keys are : 'id', 'name', 'key', 'value', 'uri''
"""
if key not in self.VALID_KEYS:
raise ValueError("Key %s is not allowed. Only allowed"
" keys are : 'id', 'name', 'key',"
" 'value', 'uri'" % key)
if key == "creators":
if isinstance(value, self.ListOfCreators):
dict.__setitem__(self, key, value)
elif isinstance(value, list):
dict.__setitem__(self, key, self.ListOfCreators(value))
else:
raise TypeError("The passed format for creators is invalid")
elif key == "created":
if not isinstance(value, str):
raise TypeError("The date passed must be a string")
else:
validateDate(value)
dict.__setitem__(self, key, value)
elif key == "modified":
if isinstance(value, self.ModifiedHistory):
dict.__setitem__(self, key, value)
elif isinstance(value, list):
dict.__setitem__(self, key, self.ModifiedHistory(value))
else:
raise TypeError("The passed format for modification"
" history is invalid")

@property
def created(self):
return self._created
def __delitem__(self, key):
dict.__delitem__(self, key)

@created.setter
def created(self, value):
if not isinstance(value, str):
raise TypeError("The date passed must be a string")
else:
validateDate(value)
self._created = value
def __iter__(self):
return dict.__iter__(self)

@property
def modified(self):
return self._modified
def __len__(self):
return dict.__len__(self)

@modified.setter
def modified(self, value):
self._modified = self.ModifiedHistory(value)
def __contains__(self, x):
return dict.__contains__(self, x)

class ListOfCreators(list):
"""A list extension to store each creator's info
2 changes: 0 additions & 2 deletions cobra/core/meta_data/keyValuePair.py
Original file line number Diff line number Diff line change
@@ -2,8 +2,6 @@

from __future__ import absolute_import

from cobra.core.object import Object


class ListOfKeyValue(list):
"""A list extension to store key-value pairs
128 changes: 68 additions & 60 deletions cobra/core/meta_data/metaData.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
from cobra.core.meta_data.keyValuePair import ListOfKeyValue


class MetaData:
class MetaData(dict):
"""Class representation of the meta-data of the component.
It is a combination of three classes i.e CVTerm, History
and KeyValuePair class.
@@ -25,92 +25,100 @@ class MetaData:

"""

VALID_KEYS = ["sbo", "cvTerms", "history", "listofKeyValue"]

def __init__(self, cvterm=None, history=None, listofKeyValue=None):
# setting the cvterm
if cvterm is None:
self._cvTerms = CVTerm()
dict.__setitem__(self, "cvTerms", CVTerm())
elif isinstance(cvterm, CVTerm):
self._cvTerms = cvterm
dict.__setitem__(self, "cvTerms", cvterm)
elif isinstance(cvterm, dict):
self._cvTerms = CVTerm(cvterm)
dict.__setitem__(self, "cvTerms", CVTerm(cvterm))
else:
raise TypeError("Invalid format passed for cvterm")
# setting the history of the component
if history is None:
self._history = History()
dict.__setitem__(self, "history", History())
elif isinstance(history, History):
self._history = history
dict.__setitem__(self, "history", history)
elif isinstance(history, dict):
if "creator" not in history:
history["creator"] = []
if "creators" not in history:
history["creators"] = []
if "created" not in history:
history["created"] = None
if "modified" not in history:
history["modified"] = []
self._history = History(history["creator"],
history["created"], history["modified"])
dict.__setitem__(self, "history", History(history["creators"],
history["created"],
history["modified"]))
else:
raise TypeError("Invalid format passed for history")
# setting the list of key-value pair
if listofKeyValue is not None:
if isinstance(listofKeyValue, ListOfKeyValue):
self._listofKeyValue = listofKeyValue
dict.__setitem__(self, "listofKeyValue", listofKeyValue)
elif isinstance(listofKeyValue, list):
self._listofKeyValue = ListOfKeyValue(listofKeyValue)
dict.__setitem__(self, "listofKeyValue",
ListOfKeyValue(listofKeyValue))
else:
raise TypeError("Key value pairs must be passed in a list")
else:
self._listofKeyValue = ListOfKeyValue()
dict.__setitem__(self, "listofKeyValue", ListOfKeyValue())

@property
def cvTerms(self):
return getattr(self, "_cvTerms", None)
def __getitem__(self, key):
if key not in self.VALID_KEYS:
raise ValueError("Key %s is not allowed. Only allowed "
"keys are : 'sbo', 'cvTerms', 'history', "
"'listofKeyValue'" % key)
return dict.__getitem__(self, key)

@cvTerms.setter
def cvTerms(self, value):
if value == self._cvTerms:
pass
elif isinstance(value, CVTerm):
self._cvTerms = value
elif isinstance(value, dict):
self._cvTerms = CVTerm(cvterm)
else:
raise TypeError("This passed format for cvterm is invalid")
def __setitem__(self, key, value):
"""Restricting the keys and values that can be set.
Only allowed keys are : 'sbo', 'cvTerms', 'history',
'listofKeyValue'
"""
if key not in self.VALID_KEYS:
raise ValueError("Key %s is not allowed. Only allowed "
"keys are : 'sbo', 'cvTerms', 'history', "
"'listofKeyValue'" % key)
if key == "cvTerms":
if isinstance(value, CVTerm):
dict.__setitem__(self, "cvTerms", value)
elif isinstance(value, dict):
dict.__setitem__(self, "cvTerms", CVTerm(value))
else:
raise TypeError("This passed format for cvterm is invalid")
elif key == "history":
if isinstance(history, History):
dict.__setitem__(self, "history", history)
elif isinstance(history, dict):
if "creators" not in history:
history["creators"] = []
if "created" not in history:
history["created"] = None
if "modified" not in history:
history["modified"] = []
dict.__setitem__(self, "history", History(history["creators"],
history["created"],
history["modified"]))
elif key == "listofKeyValue":
if isinstance(listofKeyValue, ListOfKeyValue):
dict.__setitem__(self, "listofKeyValue", listofKeyValue)
elif isinstance(listofKeyValue, list):
dict.__setitem__(self, "listofKeyValue",
ListOfKeyValue(listofKeyValue))
else:
raise TypeError("Key value pairs must be passed in a list")

@property
def history(self):
return getattr(self, "_history", None)
def __delitem__(self, key):
dict.__delitem__(self, key)

@history.setter
def history(self, value):
if value == self._history:
pass
elif isinstance(value, History):
self._history = value
elif isinstance(value, dict):
if "creator" not in history:
history["creator"] = []
if "created" not in history:
history["created"] = None
if "modified" not in history:
history["modified"] = []
self._history = History(value["creator"],
value["created"], value["modified"])
else:
raise TypeError("This passed format for history is invalid")
def __iter__(self):
return dict.__iter__(self)

@property
def listofKeyValue(self):
return getattr(self, "_listofKeyValue", [])
def __len__(self):
return dict.__len__(self)

@listofKeyValue.setter
def listofKeyValue(self, value):
if value == self._listofKeyValue:
pass
elif isinstance(value, ListOfKeyValue):
self._listofKeyValue = value
elif isinstance(value, list):
self._listofKeyValue = ListOfKeyValue(value)
else:
raise TypeError("This passed format for listofKeyValue is "
"invalid")
def __contains__(self, x):
return dict.__contains__(self, x)
15 changes: 2 additions & 13 deletions cobra/core/object.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
from __future__ import absolute_import

from six import string_types

from cobra.core.meta_data import MetaData

class Object(object):
"""Defines common behavior of object in cobra.core"""
@@ -20,7 +20,7 @@ def __init__(self, id=None, name=""):
self.name = name

self.notes = {}
self._annotation = {}
self.annotation = MetaData()

@property
def id(self):
@@ -40,17 +40,6 @@ def id(self, value):
def _set_id_with_model(self, value):
self._id = value

@property
def annotation(self):
return self._annotation

@annotation.setter
def annotation(self, annotation):
if not isinstance(annotation, dict):
raise TypeError("Annotation must be a dict")
else:
self._annotation = annotation

def __getstate__(self):
"""To prevent excessive replication during deepcopy."""
state = self.__dict__.copy()