Using cellpy from an agent¶
This page is for coding agents (and humans directing them) that need to call cellpy as a library — for example a researcher building a small desktop GUI, web app, or notebook pipeline around cell cycling data.
For contributing to the cellpy codebase, start at AGENTS.md in the repo root and the developers guide.
Findability
Root AGENTS.md points here. Prefer this chapter for usage recipes; keep
AGENTS.md short (commands + link).
What cellpy is (and is not)¶
| Is | Is not |
|---|---|
| A Python library that loads battery-tester files into a consistent shape | A GUI or web server product |
| Builds step and summary tables from raw time-series | A plotting-first dashboard (helpers exist; bring your own UI) |
Ships a cellpy CLI (setup, info, serve → Jupyter) |
Long-running app hosting — serve only launches Jupyter |
Primary object: CellpyCell. Measurement frames live on c.data
(raw, steps, summary). Column names for the active schema are on
c.schema — prefer that over legacy headers_* attributes.
Install and smoke-check¶
Consumer install:
From a clone of this repo (dev):
Always run Python through the project environment (uv run … in this repo,
or the user's activated venv/conda env). Do not call bare python unless the
user already activated an env that has cellpy installed.
Minimal load → inspect → export¶
Use bundled example data when the agent has network access (first call may download small fixtures from GitHub):
from cellpy.utils import example_data
c = example_data.raw_file() # Arbin .res → CellpyCell with steps + summary
# Prefer schema-resolved column names (v2 native headers)
potential = c.data.raw[c.schema.raw.potential]
charge_cap = c.data.summary[c.schema.summary.charge_capacity]
print(c.data.summary.head())
print(c.get_cycle_numbers()[:5])
Load a path the user provides:
import cellpy
c = cellpy.get(
r"C:\data\my_cell_01.res",
mass=0.85, # active material mass in mg (instrument-dependent context)
instrument="arbin_res", # omit to use config default / extension guess
)
c.save("out/my_cell.cellpy") # HDF5 cellpy file — fast reload later
c.to_csv("out/csv_export")
Reload a .cellpy file the same way:
Core mental model for app code¶
cellpy.get(path, ...) → CellpyCell
├─ .data.raw # time-series (pandas DataFrame)
├─ .data.steps # per-step stats / types
├─ .data.summary # per-cycle summary
└─ .schema # stable names → actual columns
Useful methods on CellpyCell (non-exhaustive):
get_cycle_numbers()— list of cycle indicesget_cap(...)/ capacity–voltage style extracts (see API / examples)make_step_table()/make_summary()— usually already run bygetsave/to_csv/ Excel helpers — persist for the user's workflow
Deeper shape docs: Data structure. Human tutorial path: Basic usage, Examples.
Recipe: researcher GUI / app around cellpy¶
Typical agent task: “build a small app that loads my tester files and shows capacities.” Keep cellpy in the data layer; keep UI (Streamlit, Qt, Panel, FastAPI, …) thin.
Suggested layering:
- Load —
cellpy.get(path, mass=..., instrument=...)in a worker thread or async job so the UI stays responsive on large files. - Resolve columns — always via
c.schema.*, never hard-coded legacy strings, so v1→v2 and instrument differences hurt less. - Present — pass pandas frames or simple dicts to the UI
(
summaryfor cycle tables; slices ofrawfor plots). - Export — offer
.cellpy(canonical) plus CSV/Excel for the user.
Skeleton (UI-agnostic):
from dataclasses import dataclass
from pathlib import Path
import cellpy
@dataclass
class LoadRequest:
path: Path
mass_mg: float
instrument: str | None = None
def load_cell(req: LoadRequest):
kwargs = {"filename": str(req.path), "mass": req.mass_mg}
if req.instrument:
kwargs["instrument"] = req.instrument
return cellpy.get(**kwargs)
def cycle_table(c):
s = c.schema.summary
df = c.data.summary
cols = [s.charge_capacity, s.discharge_capacity]
cols = [col for col in cols if col in df.columns]
return df[cols].copy()
Instrument strings and formats: see Loading different formats and the instruments API. Coming from cellpy 1.x: migration guide.
Pitfalls agents hit¶
- Hard-coded column names — use
c.schema.raw.potential(etc.), not remembered 1.x header strings. - Blocking the UI thread —
geton large.res/ SQL dumps can take seconds; load off the main thread. - Missing mass / instrument — wrong capacities or wrong loader; surface these as required inputs in the GUI.
- Writing into the install tree — treat user data dirs as read/write;
never assume repo
testdata/exists for end users. - Committing secrets / local config —
cellpy setupwrites.env_cellpyand a usercellpy.toml(legacy installs may still have~/.cellpy_prms_*.conf); do not commit those. - Plot backends in headless CI — set
MPLBACKEND=Aggwhen running tests or batch plot export without a display.
Where to read next¶
| Need | Page |
|---|---|
| Install / config / CLI checkup | Installation, Configuration, Checkup |
Frames and schema |
Data structure |
| Tutorials | Examples |
| API signatures | API reference |
| Contribute to cellpy itself | Developers guide |
Maintaining this page¶
When you change the public cellpy.get / CellpyCell / schema / CLI
surface, update this file and the short pointer section in root
AGENTS.md in the same PR. That rule is also recorded in
.issueflows/04-designs-and-guides/this-project.md.