arrow_back Return to Releases...


by The COBRApy Team

In this release we have made major changes to pretty much all corners of cobrapy and we hope that you will enjoy the new features as much as we do, and that any negative impacts on existing workflows will be limited.

The major change is the ongoing move away from cobrapy’s internal solver interfaces to those provided by optlang which provides a single unified interface to glpk, cplex and gurobi enhanced by the ability to deal with symbolic expressions. This means formulating complex constraints no longer implies defining the necessary matrix algebra, but instead simply writing the expression and assigning that as an objective to the model.

We feel that this, and the clarified scope and focus attained by separating the topic of linear programming (optlang) and metabolic flux analysis (cobrapy) to two packages is natural and makes both of these tasks less confusing and more fun. We hope that you after trying, feel the same and that in any case you let us know what you think by raising an issue or talking directly to us on gitter or google groups.

New features

The optlang solver interface

The main change is the addition of model.solver which is the optlang interface to the chosen solver (cplex and glpk are currently well supported, gurobi interface is at the time of writing mostly working but improvements are still expected). The solver interface manages variables, constraints and the objective of the model and the task of turning these into a model formulation to be optimized by the solver. From cobrapy’s point-of-view, this means that all aspects concerning generating problems, configuring solvers are handed over to optlang and consequently the whole cobra.solver has been deprecated, slated for removal in the next major release of cobrapy.

Importantly, configuring the solver by passing **solver_args or solver='solver' is now instead done by assigning solver to model.solver and then configuring via model.solver.configuration.

Creating new algorithms has been greatly facilitated as it no longer requires formulating objectives and constraints by matrix algebra but instead directly by expressions, e.g. see the implementation of cobra.flux_analysis.moma.add_moma and cobra.flux_analysis.loopless.loopless_solution.

Instead of having only reactions as variables and metabolites as constraints, with optlang, cobrapy now supports arbitrary constraints and variables and these can be added/removed by model.add_cons_vars and model.remove_cons_vars which take care of adding these to model.problem which is the optlang’s mathematical model associated with the cobra model.

Reactions are now modeled by two variables, forward and reverse, and these can be seen by accessing reaction.{forward,reverse}_variable and the combined reaction.flux_expression.

Objectives can now easily be made quite advanced by simply crafting the right expression and assigning this as usual to model.objective, see the contraints and objectives notebook.

Temporary changes to a model

Models are large complex objects and copying such objects is inevitably slow. To avoid that, cobrapy has drawn on the experience from the development of cameo to introduce the HistoryManager class and the concept of models as contexts. Now, most changes that can be made to a model such as changing the objective, setting reaction bounds, adding and removing reactions, is reversed upon exit when done inside a context, see the updated getting started notebook.

Improved solution handling

Previously, cobra models lugged around their latest solution to enable providing reaction.{flux,reduced_cost} (formerly reaction.{x,y}). This was problematic because if the model had changed since last optimization, then this would effectively give the wrong result. On top of that, it was not easy to make a change, optimize and get values, and then undo that change to the model without having to copy the whole model object. To solve this, and many similar problem, we have completely refactored cobra.Solution so that model.optimize() now returns a solution and it is the user’s responsibility to manage this object. reaction.flux gets its values directly from the model.problem. To sugar the new solution class, fluxes, reduced costs, and shadow prices are now pandas series!


Cobrapy now has flux sampling supported by cobra.flux_analysis.sampling see the sampling notebook.

Loopless models and solutions

Added implementations of CycleFreeFlux and the loopless model of Schellenberger et al.. See the notebook on loopless and simulating

DataFrames as return values

flux_variability_analysis, single_{gene,reaction}_deletion, cobra.flux_analysis.sampling and cobra.util.create_stoichiometric_matrix now return pandas data frames instead of nested dicts as these are more convenient and fun to work with. Pandas (and numpy) are therefore now hard requirements for cobrapy, which should not be a problem for neither linux, windows or mac users as there are reliable wheels for these packages now.

Model medium

model.medium is now a dict and setter for getting boundary feeding reactions and their bounds


  • Handle multiple IDs in Matlab models #345
  • DictList.query behavior changed so that attribute is None if the search parameter is not a regex or string, to enable reactions.query(lambda x: x.boundary)
  • Set charge from notes if not defined elsewhere #352
  • Warnings are no longer issued on package import if soft requirement scipy, python-libsbml is not available.

Deprecated features

These features are now deprecated and slated for complete removal in the next major cobrapy release.

  • The whole cobra.solver module is now deprecated, see New features.
  • ArrayBasedModel / Model.to_array_based_model are deprecated. This formulation makes little sense when handing over the matrix algebra to optlang, for the stoichiometry matrix (aka S), see cobra.util.array.create_stoichiometric_matrix.
  • Metabolite.y in favor of Metabolite.shadow_price
  • Model.add_reaction in favor of Model.add_reactions
  • Reaction.x in favor of Reaction.flux
  • Reaction.y in favor of Reaction.reduced_cost
  • Solution.{x, y, x_dict, y_dict, f} in favor of Solution.{fluxes, reduced_costs}. The setters are also deprecated.
  • phenotype_phase_plane in favor of production_envelope. The plotting capabilities are deprecated, to be re-implemented somewhere else.
  • convert_to_irreverible, revert_to_irreversible, canonical_form deprecated without replacement.
  • check_reaction_bounds deprecated without replacement.

Backwards incompatible changes

  • optknock was completely removed, users are advised to use cameo for this functionality
  • dual_problem was removed
  • gapfilling algorithms were removed without replacement, to be re-introduced in a different package
  • cobra.topology was removed, possibly to be reintroduced in a different package
  • flux_variability_analysis results must be transformed to have them work as the previous nested dict, i.e. flux_variability_analysis(model).T should give behavior as previously.
  • In a major linting effort we renamed capitalized modules to lower-case, e.g. cobra.core.Model to cobra.core.model. Imports from cobra are unchanged though.
  • objective coefficients of reactions can now only be set once the reaction is attached to a model.
  • Reaction.{x,y}, Metabolite.y are defunct for legacy solvers.