Python API
pip install asciichem-pyZero runtime dependencies — jsonschema and pytest are dev-only
for the conformance suite.
Parsing
Section titled “Parsing”from asciichem import parse_text, ParseError
formula = parse_text("2H_2 + O_2 -> 2H_2O") # => Formula
# All input grammars land in the same modelfrom asciichem.smiles import parse_smilesfrom asciichem.molfile import parse_molfile, write_molfile
aspirin = parse_smiles("CC(=O)OC1=CC=CC=C1C(=O)O")mol = parse_molfile(v2000_text) # coordinates preservedInvalid input raises ParseError (extends AsciiChemError) —
nothing is ever parsed “partially”.
Rendering
Section titled “Rendering”from asciichem.text import render # canonical text (round trip)from asciichem.mathml import render_mathml # presentation MathML, L2 goldensfrom asciichem.smiles import write_smiles # deterministic SMILES writer
render(formula)render_mathml(formula)write_smiles(aspirin) # round-trips exactlywrite_molfile(mol)The MathML output is byte-identical with the Ruby reference —
pinned by the shared corpus goldens (format/mathml/*), enforced in
CI.
The model is plain dataclasses
Section titled “The model is plain dataclasses”formula.nodes[0] # Molecule(...)mol.nodes[0] # Atom(element="H", subscript="2", ...)Introspectable with standard tools (dataclasses.asdict,
inspect); no framework magic. The class set mirrors the reference
model: Formula, Molecule, Atom, Group, Bond, Reaction,
ReactionCascade, ElectronConfiguration, EmbeddedMath, Text,
Crystal, Spectrum, Calculation, ZMatrix, Mechanism.
Wire form
Section titled “Wire form”The canonical JSON interchange (asciichem-model v1):
from asciichem.wire import to_model_json, from_model_json, to_wire
wire_json = to_model_json(formula) # JSON stringwire = to_wire(formula) # plain dictback = from_model_json(wire_json) # => Formula, losslesslyrender(back) == render(formula) # TrueStructure graph
Section titled “Structure graph”from asciichem.structure import build_graph
atoms, edges = build_graph(aspirin)len(atoms), len(edges) # atom list + bond list for downstream toolsInChI engine (optional extra)
Section titled “InChI engine (optional extra)”pip install 'asciichem-py[inchi]' # pulls in RDKit's InChI supportfrom asciichem.inchi import RdkitEngine, set_engine, identity_for
set_engine(RdkitEngine())identity = identity_for(molecule) # Identity(inchi=..., inchikey=...)Without an engine, identity_for raises EngineMissingError with
install guidance — the InChI algorithm is never reimplemented.
Claimed levels
Section titled “Claimed levels”Parse/reject · L0 emission · L1 text · L2 MathML · SMILES · molfile — 100% of the shared corpus. See Implementations for the full matrix.