AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
COBRApy is a Python library for constraint-based reconstruction and analysis of metabolic networks. It enables researchers to perform steady-state flux analysis, simulate gene knockouts, design growth media, and explore feasible flux spaces. The tool supports standard formats like SBML and integrates with various solvers to facilitate metabolic engineering and systems biology research.
What it does
- Perform Flux Balance Analysis (FBA) and parsimonious FBA (pFBA).
- Conduct Flux Variability Analysis (FVA) to determine flux ranges.
- Simulate single and double gene deletions for knockout screening.
- Calculate minimal growth media and production envelopes.
- Validate and manipulate metabolic models using SBML, JSON, or YAML formats.
- Sample the feasible flux space of metabolic networks.
When to use it
- When building or loading metabolic network models for steady-state analysis.
- To predict the effects of genetic modifications on metabolic flux.
- When identifying minimal nutrient requirements for specific growth targets.
- To analyze the metabolic potential and production capabilities of a biological system.
Advantages
- Standardized interface for constraint-based modeling in Python.
- Supports diverse analysis methods including sampling and gap-filling.
- Compatible with multiple optimization solvers for flexibility.
- Facilitates reproducible research through structured model I/O and configuration.
Usage examples
- “Load the textbook E. coli model and perform a standard FBA to find the growth rate.”
- The agent loads the model, sets the solver, optimizes the objective, and returns the growth rate and flux values.
- “Run a single gene deletion screen on the current model to identify essential genes.”
- The agent executes the deletion analysis and provides a report of growth impacts for each gene knockout.
- “Calculate the minimal medium required to achieve 50% of the baseline growth rate.”
- The agent computes the minimal nutrient set and validates that the model achieves the target growth rate with this medium.
- “Perform flux variability analysis on the PFK reaction with a 90% optimality fraction.”
- The agent returns the minimum and maximum flux bounds for the PFK reaction under the specified constraints.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/k-dense-ai/cobrapy/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip cobrapy.zip -d .agents/skills
Documentation by K-Dense Inc.
COBRApy - Constraint-Based Reconstruction and Analysis
When to use
Use for loading/building metabolic networks, optimizing their steady-state fluxes, knockout screens, medium design, feasible-space sampling, and gap-filling hypotheses. FBA is a constraint-based prediction; it does not infer kinetic rates or establish experimental growth, thermodynamic feasibility, or flux identifiability.
Setup and reproducibility
Targets cobra 0.32.1 (import cobra), checked against its released source and
current documentation.
uv pip install "cobra==0.32.1"
# Optional SciPy support for MATLAB I/O and array operations:
uv pip install "cobra[array]==0.32.1"Plotting examples additionally require matplotlib, pandas, and seaborn. The
cobra[chrr] extra supplies hopsy for the new CHRR sampler; that optional backend
was documentation-reviewed, not executed in this refresh. In 0.32.1, sample()
defaults to method="auto" (CHRR when hopsy is installed, otherwise OptGP).
Choose the method explicitly to avoid environment-dependent changes.
Record model source/version/checksum, cobra and solver versions, objective,
medium, bounds, tolerances, and any random seed with each analysis. GLPK handles
the examples below; inspect cobra.util.solver.solvers before choosing an
optional solver. Use "hybrid" for its HiGHS/OSQP interface when installed;
the legacy "osqp" alias is deprecated. QP methods require a suitable backend.
Start with processes=1; scripts using multiprocessing need a guarded entry point.
Workflow
1. Load, inspect, and validate a model
from cobra.io import load_model
# These names are bundled: textbook, iJO1366, salmonella.
model = load_model("textbook") # model.id is e_coli_core; 95 reactions
model.solver = "glpk"
print(model.id, len(model.reactions), len(model.metabolites), len(model.genes))
print(model.reactions.get_by_id("PFK").reaction)
print(model.reactions.PFK.gene_reaction_rule)
print(model.medium)
solution = model.optimize(raise_error=True)
assert solution.status == "optimal"
print(solution.objective_value, solution.fluxes["PFK"])
# error_value=None raises on a failed solve; the default instead returns NaN.
baseline = model.slim_optimize(error_value=None)
assert baseline > 0e_coli_core is a remote BiGG identifier, not a bundled alias for textbook.
The released remote adapters encounter redirects on current BiGG/BioModels URLs;
see model I/O for verified download routes
and local SBML loading. Do not assume load_model caches: its 0.32.1 implementation
accepts cache but does not use it. Save source files for reproducibility.
Check chemical formulas/charges and boundary annotations separately from solver feasibility. Review excluded biomass/pseudo reactions and missing chemistry; an empty imbalance dictionary alone cannot establish a chemically valid model. The validation workflow distinguishes those cases.
2. Compare FBA, pFBA, and FVA under stated constraints
from cobra.flux_analysis import pfba, geometric_fba, flux_variability_analysis
biomass_id = "Biomass_Ecoli_core" # inspect IDs/objective for each new model
parsimonious = pfba(model)
print(parsimonious.fluxes[biomass_id])
# parsimonious.objective_value is the minimized total flux, not biomass growth.
centered = geometric_fba(model, processes=1)
fva = flux_variability_analysis(
model, reaction_list=["PFK", "FBA", "PGI"],
fraction_of_optimum=0.9, processes=1,
)
loopless_fva = flux_variability_analysis(
model, reaction_list=["PFK", "FBA", "PGI"],
fraction_of_optimum=0.9, loopless="fastSNP", processes=1,
)
print(fva) # index: reaction ID; columns: minimum, maximumFVA extrema are optimized separately and need not be jointly achievable.
loopless="fastSNP" computes loopless bounds; "cycleFreeFlux" is an alternative
that need not find the optimal bounds. Boolean loopless arguments are deprecated.
Loop removal does not impose measured Gibbs energies or metabolite concentrations.
Fractional objective thresholds here assume a positive biomass maximization
objective; use an explicit constraint for other objective signs/directions.
3. Knockouts and media
from cobra.flux_analysis import single_gene_deletion
from cobra.medium import minimal_medium
results = single_gene_deletion(model, processes=1)
valid = results[results.status.eq("optimal") & results.growth.notna()]
low_growth = valid[valid.growth < 0.01 * baseline] # declared 1% criterion
unresolved = results[~results.index.isin(valid.index)]
print(low_growth[["ids", "growth"]], unresolved[["ids", "status"]])
with model:
medium = model.medium
medium["EX_o2_e"] = 0.0
model.medium = medium # editing the returned dict alone does not change model
anaerobic = model.optimize()
print(anaerobic.status, anaerobic.objective_value)
min_medium = minimal_medium(model, 0.5 * baseline, minimize_components=True)
if min_medium is None:
raise RuntimeError("No medium found at the requested growth target")
with model:
model.medium = min_medium.to_dict()
assert model.slim_optimize(error_value=None) >= 0.5 * baseline - 1e-6Deletion results contain ids sets, growth, and status; the index is not a
pair MultiIndex. Double-deletion results also contain singleton sets (self-pairs).
Classify failed/infeasible solves separately from feasible low-growth mutants.
A knockout's growth column means the model's objective, so ensure it is biomass.
model.medium values are positive import bounds, not measured concentrations.
Exchange flux signs depend on reaction stoichiometry; the textbook's one-reactant
exchanges use negative flux for uptake. open_exchanges=False retains the allowed
nutrient universe while the optimizer selects a nutrient subset and its import
bounds; it does not fix the selected nutrients or amounts. open_exchanges=True
expands that universe and can choose unintended carbon sources. Minimal media can
be nonunique; validate the returned medium with the intended growth objective.
4. Sample the same feasible region as the FVA comparison
from cobra.sampling import OptGPSampler
with model:
model.reactions.get_by_id(biomass_id).lower_bound = 0.9 * baseline
# The growth floor is already installed. fraction=0 adds no stronger optimum.
sampled_fva = flux_variability_analysis(
model, reaction_list=["PFK"], fraction_of_optimum=0.0, processes=1,
)
sampler = OptGPSampler(model, processes=1, thinning=100, seed=7)
samples = sampler.sample(200)
codes = sampler.validate(samples)
assert (codes == "v").all(), "Inspect bound/equality violations"
assert (samples[biomass_id] >= 0.9 * baseline - 1e-6).all()
print(samples["PFK"].describe(), sampled_fva)FVA does not leave its objective-fraction constraint on the model; sampling a fresh/unconstrained model explores a different space. Feasible samples are not a confidence interval for measured biology. Inspect independent chains, autocorrelation and effective sample size before interpreting distributions; 200 samples are a smoke test. Sampling can include internal cycles.
5. Production envelopes and design hypotheses
from cobra.flux_analysis import production_envelope
with model:
model.reactions.get_by_id(biomass_id).lower_bound = 0.1 * baseline
envelope = production_envelope(
model, reactions=["EX_glc__D_e"], objective="EX_ac_e",
carbon_sources=["EX_glc__D_e"], points=8,
)
print(envelope[["EX_glc__D_e", "flux_minimum", "flux_maximum"]])These are acetate flux extrema; carbon_yield_* and mass_yield_* are
separate outputs, potentially NaN when inputs or formulas are unsuitable.
A multi-reaction grid needs a surface/heatmap, not an arbitrary connected line.
When zero flux is already allowed for the affected reactions, a knockout only
removes feasible states and cannot improve the global product maximum under
otherwise identical constraints. Check that knockout bound replacement does not
relax an original forced nonzero flux. The design workflow
screens the minimum product flux at a common growth requirement and also reports
maximum growth, an explicit model-based coupling hypothesis requiring validation.
6. Build and gap-fill carefully
Use Model, Reaction, Metabolite, model.add_reactions([reaction]), and
reaction.gene_reaction_rule to build the network. Set formulas and charges;
include water/protons when needed for balanced chemistry. Exchanges belong to
external metabolites, demands remove metabolites, and sinks permit both directions.
Do not add arbitrary ATP sources to make a model grow.
The API reference includes a balanced toy
network and a gap-fill example with a known missing reaction. gapfill returns
a list of reaction lists, one per iteration; it does not modify the input
model. Candidate additions are hypotheses: check evidence, directionality,
chemistry, energy-generating cycles, and growth after adding copied reactions.
Export and troubleshooting
Prefer SBML for exchange, JSON for interoperable tooling, YAML for inspection.
Round-trip the file and compare reaction IDs, bounds, objective, and growth.
Use context managers for temporary objective/bound/GPR changes. Inspect statuses
before reading fluxes; do not turn NaN or every solver failure into zero growth.
When debugging infeasibility, test medium changes inside with model: and record
which constraints changed. Feasibility after opening all nutrients does not
establish biological validity. Keep CSV/PNG output in the task's chosen directory.
Citing Scientific Agent Skills
This skill is part of Scientific Agent Skills by K-Dense. If it materially contributed to a manuscript, report, presentation, or code release, add the paper to the references or software section and tell the user you did so:
Kassis, T., Agarwal, V., He, Y., Patel, D., & Brueckner, A. M. (2026). Scientific Agent Skills: A Library of Procedural Knowledge for Research Agents. arXiv:2609.00065. https://doi.org/10.48550/arXiv.2609.00065
Always cite the current version. The DOI and https://arxiv.org/abs/2609.00065 resolve to the
latest arXiv version, so never append a version suffix such as v1. When network access is
available, fetch https://arxiv.org/abs/2609.00065 (or
http://export.arxiv.org/api/query?id_list=2609.00065) before writing the reference and take
the author list, year, and version from that record. If the record lists a journal reference
or publisher DOI, cite the published version instead.
Files
- ATTRIBUTION.mdAdded by AutoGineer968 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md11.4 KiB
- references/api_quick_reference.md16.0 KiB
- references/workflows.md15.7 KiB
references/api_quick_reference.md
COBRApy API reference
Checked against cobra 0.32.1 installed signatures/source and current official
docs. Examples with model assume a fresh load_model("textbook"); placeholders
such as filename are illustrative, not standalone runnable commands.
Model I/O and repository contracts
from cobra.io import (
load_model, read_sbml_model, write_sbml_model,
load_json_model, save_json_model, load_yaml_model, save_yaml_model,
load_matlab_model, save_matlab_model,
)
model = load_model("textbook") # Local, model.id == "e_coli_core"
# Also local: load_model("iJO1366"), load_model("salmonella")
# Remote illustrative calls; adapters may fail at redirects (see below):
# model = load_model("e_coli_core")
# model = load_model("iML1515")
# Illustrative file I/O: use your actual paths.
# model = read_sbml_model("model.xml.gz")
# write_sbml_model(model, "model.xml")
# save_json_model(model, "model.json", pretty=True)
# model = load_json_model("model.json")
# save_yaml_model(model, "model.yml")
# model = load_yaml_model("model.yml")
# save_matlab_model(model, "model.mat", varname="model")
# model = load_matlab_model("model.mat", variable_name="model")MATLAB I/O needs SciPy (cobra[array]). Keep the default SBML f_replace mapping
unless intentionally preserving SBML-encoded IDs; f_replace={} disables prefix
and character conversion. Verify identifiers after round-trip before selecting an
objective. Formats may not retain arbitrary custom solver constraints; store those
separately and reconstruct them on reload.
load_model(model_id, repositories=..., cache=True) searches bundled data, BiGG,
then BioModels. In released 0.32.1 the cache argument is unused despite its
docstring: save downloaded files explicitly. A non-404 HTTP failure aborts lookup;
it does not necessarily fall through to the next provider. Repository-specific
IDs are not interchangeable. The BioModels adapter only supports a directly listed
XML file; OMEX-only records require an explicitly chosen SBML extraction workflow.
Verified unauthenticated provider routes (2026-09-30):
| Provider | Request and response | Current adapter caveat |
|---|---|---|
| BiGG | GET https://bigg.ucsd.edu/static/models/{id}.xml.gz returns gzip-compressed SBML; iML1515 parsed as 2,712 reactions | 0.32.1 uses HTTP and does not follow the HTTP-to-HTTPS redirect |
| BioModels files | GET https://www.biomodels.org/model/files/{id} with Accept: application/json; main is a list of file records with name and fileSize | 0.32.1 uses the bare hostname and does not follow its listing redirect |
| BioModels download | GET https://www.biomodels.org/model/download/{id}?filename={name} returns the selected file; follow redirects | Select an actual XML name from the listing, not an invented name or arbitrary first file |
These are single-model/file operations with no pagination or credentials. The
MODEL1510010000 listing and selected XML download were executed and parsed. That BioModels file lacked an optimization objective and many explicit flux bounds,
so its successful parse is not a validated FBA model. SDK
remote failures were observed separately; they do not mean the services retired.
A bounded BiGG fallback, executed on iML1515:
from pathlib import Path
from urllib.request import urlopen
from cobra.io import read_sbml_model
path = Path("iML1515.xml.gz") # Use the task's output directory.
with urlopen("https://bigg.ucsd.edu/static/models/iML1515.xml.gz", timeout=30) as response:
data = response.read(16 * 1024 * 1024 + 1)
if len(data) > 16 * 1024 * 1024:
raise ValueError("Model exceeds this example's 16 MiB download limit")
path.write_bytes(data)
model = read_sbml_model(path)
assert len(model.reactions) == 2712For BioModels, fetch the JSON listing, choose main entries whose name ends in
.xml, URL-encode that filename using urllib.parse.urlencode, and use the download
route in the table with the same finite timeout/size check. Save the original file,
retrieval date and checksum. Do not assume every SBML record is a constraint-based
metabolic model with the required objective and flux bounds.
Core objects and editing
from cobra import Model, Reaction, Metabolite, Gene
from cobra.io import load_model
model = load_model("textbook")
reaction = model.reactions.get_by_id("PFK")
metabolite = model.metabolites.get_by_id("atp_c")
print(reaction.bounds, reaction.gene_reaction_rule, metabolite.formula)
print(model.exchanges, model.demands, model.sinks, model.boundary)
# DictList.query uses a regular expression, case-sensitive by default.
import re
matches = model.reactions.query(re.compile("atp", re.IGNORECASE))
glycolytic = model.reactions.query(lambda r: r.subsystem == "Glycolysis")
assert "PFK" in model.reactions
# Temporary changes are restored when the model context exits.
with model:
reaction.bounds = (0, 5)
reaction.gene_reaction_rule = "gene1 and (gene2 or gene3)"
model.genes.get_by_id("gene1").knock_out()
solution = model.optimize()Use add_reactions([reaction]), not removed add_reaction. Set GPRs on reactions
so associated genes and reverse links are updated; do not mutate model.genes
directly to remove genes. For permanent deletion use
cobra.manipulation.remove_genes(model, ["gene_id"], remove_reactions=True) and
inspect affected GPRs/reactions. remove_reactions([...]) accepts IDs or objects;
remove_metabolites([...], destructive=False) removes them from stoichiometries
and needs biological review.
model.copy() creates an independent model. To form a subset, copy each reaction:
new_model.add_reactions([r.copy() for r in chosen_reactions]); adding the same
Reaction objects to another model risks moving their model/solver associations.
A reaction is reversible when both lower_bound < 0 and upper_bound > 0.
Balanced toy network and gap filling
A mass/charge-balanced isomerization illustrates building without creating an unphysical ATP source. Boundary reactions deliberately connect the model to its environment. The toy's demand objective is product export, not a growth rate.
from cobra import Model, Reaction, Metabolite
from cobra.flux_analysis import gapfill
model = Model("toy")
model.solver = "glpk"
a_e = Metabolite("a_e", formula="C6H12O6", charge=0, compartment="e")
a_c = Metabolite("a_c", formula="C6H12O6", charge=0, compartment="c")
b_c = Metabolite("b_c", formula="C6H12O6", charge=0, compartment="c")
transport = Reaction("T", lower_bound=0, upper_bound=1000)
transport.add_metabolites({a_e: -1, a_c: 1})
conversion = Reaction("A_TO_B", lower_bound=0, upper_bound=1000)
conversion.add_metabolites({a_c: -1, b_c: 1})
conversion.gene_reaction_rule = "(gene1 and gene2) or gene3"
model.add_reactions([transport, conversion])
model.add_boundary(a_e, type="exchange", lb=-10, ub=1000)
model.add_boundary(b_c, type="demand")
model.objective = "DM_b_c"
assert conversion.check_mass_balance() == {}
assert abs(model.slim_optimize(error_value=None) - 10) < 1e-6
universal = Model("candidates")
universal.add_reactions([conversion.copy()])
model.remove_reactions(["A_TO_B"])
assert abs(model.slim_optimize(error_value=None)) < 1e-6
solutions = gapfill(
model, universal=universal, lower_bound=1.0,
demand_reactions=False, exchange_reactions=False, iterations=1,
)
# Each entry is a LIST of Reaction objects; input model remains unchanged.
assert [[r.id for r in candidate] for candidate in solutions] == [["A_TO_B"]]
with model:
model.add_reactions([r.copy() for r in solutions[0]])
assert model.slim_optimize(error_value=None) >= 1 - 1e-6gapfill(..., penalties=None) supports reaction-ID and category penalties
(universal, exchange, demand). Defaults permit added demand reactions but not
exchanges. iterations=5 reuses one GapFiller and increases costs of used reactions;
five fresh calls do not preserve that penalty history or guarantee unique answers.
For real data, use a curated universal reaction model with matched metabolite IDs,
compartments, chemistry and directionality. Do not treat a MILP-selected reaction
as evidence that the organism encodes it.
Optimization and solution interpretation
from cobra.io import load_model
from cobra.flux_analysis import pfba, geometric_fba
model = load_model("textbook")
solution = model.optimize(raise_error=True)
print(solution.status, solution.objective_value)
print(solution.fluxes, solution.shadow_prices, solution.reduced_costs)
value = model.slim_optimize(error_value=None)
with model:
model.objective = "ATPM" # Also accepts Reaction or {Reaction: coefficient}.
model.objective_direction = "max"
atp_solution = model.optimize(raise_error=True)
print("ATPM flux:", atp_solution.objective_value) # Not biomass growth.
parsimonious = pfba(model, fraction_of_optimum=1.0)
centered = geometric_fba(model, epsilon=1e-6, max_tries=200, processes=1)pfba first optimizes the specified objective, then minimizes total absolute flux.
Its returned objective is that secondary sum. Read the biomass flux explicitly.
Dual values are solver/problem dependent; integer problems need not provide them.
A default slim_optimize() failure returns NaN; use error_value=None to raise.
Do not label any feasible objective as growth unless it is the growth objective.
model.solver.configuration exposes timeout, verbosity and supported tolerance
settings. Inspect cobra.util.solver.solvers before selecting glpk, hybrid,
cplex, or gurobi. Optional commercial solvers require installation/licensing;
GLPK does not support quadratic objectives. Set and report realistic tolerances,
not a silently unsupported solver-specific setting.
Analysis contracts
| Operation | Relevant arguments | Return and interpretation |
|---|---|---|
flux_variability_analysis | reaction_list=None, loopless=None, fraction_of_optimum=1.0, pfba_factor=None, processes=1 | DataFrame indexed by reaction ID, minimum/maximum; extrema optimized independently |
single_gene_deletion | gene_list=None, method="fba", solution=None, processes=1 | DataFrame columns ids (set), growth, status |
single_reaction_deletion | reaction_list=None, same method/solution/process arguments | Same schema; objective must be growth to call the result growth |
double_gene_deletion | gene_list1, gene_list2, method/solution/process arguments | Same schema; singleton sets are self-pairs, not double mutants |
double_reaction_deletion | reaction_list1, reaction_list2, method/solution/process arguments | Same schema; no MultiIndex assumption |
find_blocked_reactions | reaction_list=None, zero_cutoff=None, open_exchanges=False, processes=1 | List of ID strings in released implementation; cutoff cannot be smaller than model tolerance |
find_essential_genes / find_essential_reactions | threshold=None, processes=1 | Sets of Gene / Reaction objects; default cutoff is 1% of objective optimum; inspect failed solves separately |
production_envelope | reactions, objective=None, carbon_sources=None, points=20, threshold=None | Grid DataFrame with reaction coordinates, flux_minimum, flux_maximum, carbon_yield_*, mass_yield_*, carbon_source |
FVA loopless choices are "fastSNP" (optimal loopless bounds) and
"cycleFreeFlux" (loop removal without guaranteed optimal bounds); booleans are
deprecated. A pfba_factor greater than one caps the total flux relative to pFBA.
Loopless does not mean full thermodynamic consistency with measured energies.
production_envelope accepts IDs or reaction objects for scanned reactions.
The grid has points ** len(reactions) rows, so bound its dimension and resolution.
threshold is a numerical zero cutoff, not a minimum objective requirement;
default uses model tolerance. Set growth requirements explicitly. Yields need a
single interpretable output objective and suitable carbon/formula annotations;
missing or zero denominators can produce NaN. Two-axis plots should visualize the
objective value as a surface/color, not only scatter the input coordinates.
Sampling
from cobra.io import load_model
from cobra.sampling import sample, OptGPSampler, ACHRSampler
model = load_model("textbook")
samples = sample(model, n=20, method="achr", thinning=100, seed=7)
sampler = OptGPSampler(model, processes=1, thinning=100, seed=7)
samples = sampler.sample(20)
validation = sampler.validate(samples)
assert (validation == "v").all()
for batch in sampler.batch(10, 2):
assert len(batch) == 10sample(..., method="auto") now chooses CHRR if hopsy is installed, otherwise
OptGP. Use "optgp", "achr", or optional "chrr" explicitly. ACHR uses one
process; OptGP can return more than n samples when n is not divisible by
processes. CHRR requires cobra[chrr] and incurs an initial rounding cost;
that backend was not executed here. Validation codes v, l, u, e indicate
valid, lower-bound, upper-bound and equality checks; codes may combine violations.
Thinning and a passing feasibility check do not establish chain convergence.
Media
from cobra.medium import minimal_medium
medium = model.medium
medium["EX_glc__D_e"] = 10.0
medium["EX_o2_e"] = 20.0
model.medium = medium
min_medium = minimal_medium(
model, min_objective_value=0.1, exports=False,
minimize_components=False, open_exchanges=False,
)There is no penalties argument to minimal_medium in 0.32.1. Its default
minimizes total import flux; minimize_components=True uses MILP to minimize
component count. With open_exchanges=False, the allowed nutrient universe stays
fixed but the optimizer selects the subset and import bounds within it. An integer
greater than one asks for alternative media. The
return is a Series, a DataFrame of alternatives, or None on failure. exports
controls whether exporting fluxes appear in the returned medium; it does not
control whether secretion is allowed in the model. The medium mapping lists
positive import bounds; assigning it closes omitted import directions while
retaining export bounds.
Validation and summaries
reaction.check_mass_balance() returns elemental/charge imbalances or an empty
dict, but missing formulas or charges can prevent a meaningful check. The
cobra.manipulation.check_mass_balance(model) helper excludes annotated
boundary/biomass/pseudo reactions. check_metabolite_compartment_formula(model)
only checks whether nonempty formulas are alphanumeric: despite its name it does
not comprehensively validate chemical formulas, compartment assignment, or charges.
Use the explicit missing-data and exception reporting in workflows.
model.summary(), model.metabolites.atp_c.summary() and
model.reactions.PFK.summary() return summary objects. model.summary(fva=0.95)
adds FVA at that fraction. Summaries often compute pFBA internally; state the
constraints and objective rather than treating them as measured fluxes.
Official sources and release/source distinctions
Some generated API prose still describes the old deletion index or blocked-reaction object type. The released implementation, tutorial tables and executed return values are the authority for the schemas recorded here.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools, Needs network access, Needs Python
The author says: Requires Python 3.9+ and cobra; examples tested with Python 3.12 and cobra 0.32.1. GLPK installs via swiglpk; commercial solvers need separate installation/licensing. Remote model downloads need network access; bundled textbook examples run offline.
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- K-Dense Inc.
- Publisher
- K-Dense (Community)
- Source
- K-Dense-AI/scientific-agent-skills · skills/cobrapy · commit a25cf9e
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by K-Dense Inc. or K-Dense.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download cobrapy.zip