-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor some core funtionality to ease the extension of cobrapy by third parties #1087
Comments
This is exactly the kind of thing that I'd like to address when tackling #967. I don't know how much time you have for achieving your task but it probably does not make sense to start a separate package yet. What extra information do you need to parse? |
More or less, I don't need to make extra libSBML calls, but I am heavily relying on |
I think the composition in Model is fine for that. You don't need to store the type of the derived class just use |
Groups work, but I add functionality based on the groups at the moment of parsing. In fact, everything is working for me after rewriting What I am trying to highlight is that having to duplicate As I said, I understand that adding arguments for inherited types everywhere is not the best possible pattern, but these are my afterthoughts after writing a package that inherits from |
Could you expand on what you are trying to achieve a little more? I agree that the hierarchical structure can make it harder to derive classes, but the type injection would probably create too much overhead and overwriting just the relevant methods seems a bit more clear to me. That said there aren't that many methods you have to overwrite. For Model it's add_boundary and only if you want to support it. For Metabolite you only need to rewrite the Reaction constructor if you don't add the metabolites to the model first. I think this is already much more modular than other packages. For instance, substituting Series with a custom class in pandas would be much harder. Making the parser more modular is a separate issue and I can see use cases for that. It would also fit well with the design of lisbml where you get a doc and then extract info from part of it. And I could imagine use cases where one only wants to get the metabolites and their annotations from a model for instance. |
Since the refactoring of IO is more straightforward, that should be prioritized. It is true that there aren't many methods to overwrite and that this is common in python packages, so we can leave the discussion there. Again, I was just highlighting the pain points I have found of extending cobrapy as a third party package, hoping that can initiate a discussion to ease those points. Once you know what to overwrite, it is fine, the problem comes when, for instance, someone naively implements a |
I see, make sense. Thanks for the additional info. |
Checklist
Related to the discussion on #967, in the sense that it is about libraries building upon
cobrapy
.Is your feature related to a problem? Please describe it.
One of the pains of extending cobrapy is the composition pattern of
cobra.Model
. For instance, if a package wants to merely extendcobra.Reaction
, the library can implement the following:However, even though the new package doesn't add new functionality to the
cobra.Model
class, it has to rewrite all of the methods ofcobra.Model
that involve acobra.Reaction
(well, in this case, justadd_boundary
). Not only that, but it has to rewrite the I/O monolithic functions, replacingcobra.Reaction
withCustomReaction
. In the same fashion, extendingcobra.Metabolite
requires reimplementing some methods insidecobra.Reaction
.Describe the solution you would like.
This is not a problem of cobrapy itself, but a common problem when extending python libraries in general that leads to avoiding inheritance through shallow inheritance and code duplication. Nonetheless, I'd like to propose some changes that could facilitate the extension of cobrapy:
_sbml_to_model
into smaller functions (e.g.,parse_annotation
,parse_metabolites
,parse_reactions
,parse_groups
) would lead to less code duplication (this is directly related to Extracting core functionality into a separate package #967, although I don't think that a core sbml module is needed for this).Reaction
.Describe alternatives you considered
Shallow inheritance, straight up rewriting the relevant functions and classes, etc.
Additional context
I am writing a package that inherits from cobrapy and involves additional parsing of the SBML document.
The text was updated successfully, but these errors were encountered: