Skip to content

Parameters and configuration

The configuration stack and the column schemas.

See Configuration settings for the generated table of every setting and its default.

Configuration

config

Parallel pydantic-settings configuration stack (issues #452, #453).

Production code should use cellpy.config directly. Legacy cellpy.parameters.prms forwards here via a deprecated shim.

CellpyConfig

Bases: BaseModel

Root configuration object (parallel to legacy prms).

model_dump_for_file

model_dump_for_file() -> dict[str, Any]

Dump config suitable for TOML persistence (secrets excluded).

LoadOptions dataclass

LoadOptions(user_config_file: Path | None = None, project_config_file: Path | None = None, env_file: Path | None = None, cwd: Path | None = None, skip_files: bool = False, skip_env: bool = False, legacy_yaml_file: Path | None = None)

Hooks for tests and explicit reload paths.

override

override(**sections: Any) -> Iterator[CellpyConfig]

Scoped runtime overrides (stacked, LIFO restore).

reload

reload(overrides: dict[str, Any] | None = None, *, options: LoadOptions | None = None) -> CellpyConfig

Explicit (re)load from layered sources.

reset_session

reset_session() -> None

Clear cached config (tests).

models

Pydantic models mirroring legacy prms sections (issue #452).

ArbinConfig

Bases: BaseModel

Arbin instrument knobs (SQL credentials live in secrets).

BatchConfig

Bases: BaseModel

Settings for batch processing.

CellInfoDefaults

Bases: BaseModel

Default cell parameters (values in cellpy units by convention).

CellpyConfig

Bases: BaseModel

Root configuration object (parallel to legacy prms).

model_dump_for_file

model_dump_for_file() -> dict[str, Any]

Dump config suitable for TOML persistence (secrets excluded).

DbColsConfig

Bases: BaseModel

Column names for the simple excel database reader.

DbConfig

Bases: BaseModel

Settings for the simple database.

FileNamesConfig

Bases: BaseModel

Settings for file names and file handling.

InstrumentsConfig

Bases: BaseModel

Instrument settings (legacy capitalized instrument keys preserved).

MaterialsDefaults

Bases: BaseModel

Default material-specific values (cellpy units by convention).

PathsConfig

Bases: BaseModel

Paths used in cellpy.

ReaderConfig

Bases: BaseModel

Settings for reading data.

ScienceDefaults

Bases: BaseModel

Merged CellInfo + Materials defaults for metadata construction.

SecretsConfig

Bases: BaseModel

Credentials — env / .env only; never read from or written to TOML.

password is a :class:~pydantic.SecretStr, so it does not leak through repr(), logs, tracebacks or model_dump(). Read the actual value with :meth:get_password at the point of use, never earlier.

The other three are not secret material — a host, a user name and a path to a key file — so they stay plain strings. They live here because they arrive from the same env layer and the same consumers need them together (config plan decision 5).

get_password

get_password() -> str | None

The plain password, or None. Call at the point of use.

UnitsConfig

Bases: BaseModel

Session unit policy; keys validated against cellpycore.units.CellpyUnits.

default_inventory_config

default_inventory_config(root: Path) -> CellpyConfig

Fresh config for inventory parity (fixed path root, otherwise model defaults).

inventory_paths_config

inventory_paths_config(root: Path) -> PathsConfig

Build PathsConfig with every directory rooted at root (parity tests).

credentials

The one place that resolves cellpy credentials (config plan Step 6, #565).

Before this module four call sites — internals/otherpath.py, internals/connections.py, readers/filefinder.py and readers/instruments/arbin_sql_config.py — each knew the CELLPY_* environment variable names and each read them with a bare os.getenv. That is the scatter the config plan set out to remove: four places to update when a variable is renamed, and four different answers when one of them is stale.

Resolution order, per credential:

  1. the session config (cellpy.config.secrets) — this is where the config loader has already deposited the environment and .env layers, and where an explicit runtime assignment lands;
  2. the live environment — consulted only if the session value is unset, so that a variable exported after cellpy was imported still works (a normal notebook pattern) without letting the environment silently override a value the user set deliberately at runtime.

Credentials are never read from a config file: the loader refuses a [secrets] section outright (config plan decision 5).

get_host

get_host() -> str | None

Remote host, or None if unset.

get_key_filename

get_key_filename() -> str | None

Path to the ssh key file, or None if unset.

get_password

get_password() -> str | None

The ssh/SQL password, or None if unset.

get_user

get_user() -> str | None

Remote user name, or None if unset.

resolve_credentials

resolve_credentials() -> SecretsConfig

All four credentials as a fresh :class:SecretsConfig.

Convenience for callers that need more than one; the password comes back wrapped in a SecretStr again, so use .get_password() on the result.

Column schema

cell_schema

The public column-name API for a cell (native-headers Phase 4, issue #558).

CellpyCell.schema answers one question: what is this column called on the frames this cell is carrying? It is the sanctioned replacement for the legacy headers_normal / headers_step_table / headers_summary attributes, which are now a deprecation shim (legacy_header_shim, D6).

>>> c = cellpy.get(...)                                    # doctest: +SKIP
>>> c.data.raw[c.schema.raw.potential]                     # doctest: +SKIP
>>> c.data.summary[c.schema.summary.charge_capacity]       # doctest: +SKIP

Frame names follow the frames, not cellpy-core. cellpycore.config.Schema spells its three frames raw / step / cycle; the frames a user holds are c.data.raw / c.data.steps / c.data.summary. This wrapper closes that gap — c.schema.summary sits next to c.data.summary — so there is exactly one public spelling per frame. Internals that want the cellpy-core object keep using c.core.schema.

You always spell the column the native way; the value tracks the runtime. c.schema.raw.potential is how you ask for the potential column on any cell. On the native runtime (the cellpy 2 default) it returns "potential". On the legacy runtime (native_schema=False, the retiring v8/bridge compatibility path) the frames still carry legacy column names, so the same attribute returns "voltage" — the name that actually indexes that frame. That uniformity is what lets cellpy's own internals, which must run on both runtimes, be written once against the native vocabulary.

The contract in one line: whatever c.schema.<frame>.<column> returns is a valid key into c.data.<frame>.

CellSchema

CellSchema(core_schema: 'config.Schema', native: bool = True)

Column names for one cell's three frames.

Parameters:

  • core_schema ('config.Schema') –

    the Schema-like object owned by the cell's core (CellpyCell.core.schema). Its raw / step / cycle frames are re-exposed here as raw / steps / summary.

  • native (bool, default: True ) –

    whether the cell's frames carry native column names. When False the frames are wrapped so native attribute spelling still resolves — to the legacy column names those frames actually use.

raw property

raw

Column names of c.data.raw.

steps property

steps

Column names of c.data.steps.

summary property

summary

Column names of c.data.summary.

Units

units

Unit presentation helpers (unit plan Phase 4, issue #564).

Plots and reports need to say what a number is measured in. Before this module every caller composed that string by hand::

f"Capacity ({c.cellpy_units.charge}/{c.cellpy_units.specific_gravimetric})"

which is where gravimetric/areal/absolute mix-ups live: the mode is encoded in the choice of attribute, so picking the wrong one is a silent mislabel rather than an error. These two helpers make the mode an argument instead:

>>> units_label("charge", mode="gravimetric")          # doctest: +SKIP
'mAh/g'
>>> with_cellpy_unit("Capacity", "charge", "areal")    # doctest: +SKIP
'Capacity (mAh/cm**2)'

units defaults to the session's cellpy units. Pass a cell's own units explicitly — units_label("charge", "gravimetric", units=c.cellpy_units) — whenever the label describes that cell's frames rather than session policy. Values cross the seam, never config objects (architecture plan §4).

units_label

units_label(physical_property: str, mode: Optional[str] = None, *, units: Optional['CellpyUnits'] = None) -> str

Return the unit string for a physical property, e.g. "mAh/g".

Parameters:

  • physical_property (str) –

    what is being measured — a field of the cellpy unit spec ("charge", "voltage", "time", "energy", …). "potential" and "capacity" are accepted spellings of "voltage" and "charge".

  • mode (Optional[str], default: None ) –

    "gravimetric", "areal", "volumetric", or "absolute"/None for the bare unit. A specific mode appends that mode's denominator.

  • units (Optional['CellpyUnits'], default: None ) –

    the unit spec to read. Defaults to the session's cellpy units; pass c.cellpy_units when labelling a particular cell.

Returns:

  • str

    The unit string — "mAh", "mAh/g", "mAh/cm**2", "V", …

Raises:

  • UnitsError

    if the property or the mode is unknown. Mislabelled axes are worse than a traceback, so this fails loudly rather than returning a placeholder (conventions plan §4).

with_cellpy_unit

with_cellpy_unit(name: str, physical_property: str, mode: Optional[str] = None, *, units: Optional['CellpyUnits'] = None) -> str

Return an axis label: name followed by its unit in parentheses.

Parameters:

  • name (str) –

    the human-readable quantity name, e.g. "Capacity".

  • physical_property (str) –

    as :func:units_label.

  • mode (Optional[str], default: None ) –

    as :func:units_label.

  • units (Optional['CellpyUnits'], default: None ) –

    as :func:units_label.

Returns:

  • str

    e.g. "Capacity (mAh/g)", "Voltage (V)".