Guide 5 — Cell descriptors#

Cell descriptors go beyond datasheet-level specifications. They capture electrode composition, electrolyte formulation, separator properties, and cell construction — the detail needed for research-grade records and curated cell libraries.

Estimated time: 40 minutes Prerequisites: Guide 2 — Describing a cell

Everything writes under _scratch/guide-05/.

[1]:
import json
from pathlib import Path

# This notebook runs from its own folder (docs/guides). Everything it
# writes lands in a throwaway scratch folder next to it.
SCRATCH = Path("_scratch/guide-05").resolve()
SCRATCH.mkdir(parents=True, exist_ok=True)

Step 1: Individual materials#

[2]:
from battinfo.authoring import material, properties

# Positive electrode
lfp   = material("LFP",          mass_fraction={"value": 90,  "unit": "%"},
                  comment="LiFePO4, olivine structure, D50 ~ 3 µm (Aleees GEN2)")
pvdf  = material("PVDF",         mass_fraction={"value":  5,  "unit": "%"})
c65   = material("Carbon black", mass_fraction={"value":  5,  "unit": "%"},
                  comment="Imerys C65")

# Negative electrode
graphite = material("Graphite",  mass_fraction={"value": 95.5, "unit": "%"},
                     comment="Natural graphite, D50 ~ 20 µm")
cmc  = material("CMC", mass_fraction={"value": 1.5, "unit": "%"})
sbr  = material("SBR", mass_fraction={"value": 2.5, "unit": "%"})
c_ng = material("Carbon black", mass_fraction={"value": 0.5, "unit": "%"})

print("Materials defined.")
Materials defined.

Step 2: Bills of materials#

[3]:
from battinfo.authoring import bom

positive_bom = bom(active_material=lfp,      binder=pvdf,       additive=c65)
negative_bom = bom(active_material=graphite, binder=[cmc, sbr], additive=c_ng)

print("Positive active:", positive_bom.active_material[0].name)
print("Negative binders:", [m.name for m in negative_bom.binder])
Positive active: LFP
Negative binders: ['CMC', 'SBR']

Step 3: Electrodes#

[4]:
from battinfo.authoring import electrode

positive_electrode = electrode(
    bom=positive_bom,
    loading={"value": 12.5, "unit": "mg/cm2"},
    calendered_density={"value": 2.4, "unit": "g/cm3"},
    current_collector="Aluminium foil",
    current_collector_thickness={"value": 16.0, "unit": "µm"},
    coating_comment="NMP-cast, roll-calendered to 85% theoretical density",
)

negative_electrode = electrode(
    bom=negative_bom,
    loading={"value": 7.8, "unit": "mg/cm2"},
    calendered_density={"value": 1.55, "unit": "g/cm3"},
    current_collector="Copper foil",
    current_collector_thickness={"value": 10.0, "unit": "µm"},
)

print("Positive loading:", positive_electrode.coating.property.get("loading"))
print("Negative density:", negative_electrode.coating.property.get("calendered_density"))
Positive loading: {'value': 12.5, 'unit': 'mg/cm2'}
Negative density: {'value': 1.55, 'unit': 'g/cm3'}

Step 4: Electrolyte#

[5]:
from battinfo.authoring import electrolyte_recipe, material as mat

# Salts are materials like any other constituent: the same material(...) form
# as solvents, with the concentration carried inline.
lp30 = electrolyte_recipe(
    family="organic",
    salt=mat("LiPF6", concentration={"value": 1.0, "unit": "mol/L"}),
    solvents=[
        mat("EC",  volume_fraction={"value": 50, "unit": "%"}),
        mat("DMC", volume_fraction={"value": 50, "unit": "%"}),
    ],
    additives=[
        mat("VC",  mass_fraction={"value": 2.0, "unit": "%"}, comment="SEI-forming additive"),
        mat("FEC", mass_fraction={"value": 1.0, "unit": "%"}, comment="Fluoroethylene carbonate"),
    ],
    comment="LP30 + 2% VC + 1% FEC",
)

print("Salt:", lp30.salt.name, "at", lp30.salt.property.get("concentration"))
print("Solvents:", [s.name for s in lp30.solvent_mixture.component])
print("Additives:", [a.name for a in lp30.additive])
Salt: LiPF6 at {'value': 1.0, 'unit': 'mol/L'}
Solvents: ['EC', 'DMC']
Additives: ['VC', 'FEC']

Step 5: Separator#

[6]:
from battinfo.authoring import separator_spec

sep = separator_spec(
    material="Polypropylene",
    thickness={"value": 25.0, "unit": "µm"},
    properties=properties(porosity={"value": 41, "unit": "%"}),
    comment="Celgard 2500, single-layer PP",
)

print("Material:", sep.material)
print("Thickness:", sep.property.get("thickness"))
print("Porosity:", sep.property.get("porosity"))
Material: Polypropylene
Thickness: {'value': 25.0, 'unit': 'µm'}
Porosity: {'value': 41, 'unit': '%'}

Step 6: Construction#

[7]:
from battinfo.authoring import construction

build = construction(
    assembly_type="wound",
    layering="single_layer",
    layer_count=1,
    comment="Single jelly-roll, wound on 4 mm mandrel",
)

print("Assembly:", build.assembly_type, "/", build.layering)
Assembly: wound / single_layer

Step 7: Provenance#

[8]:
from battinfo.authoring import source

prov = source(
    type="datasheet",
    name="ANR26650M1-B Product Datasheet Rev B",
    url="https://example.com/a123-anr26650m1-b.pdf",
    retrieved_at=1746230400,
    curated_by="Jane Smith",
)

print("Source type:", prov.type)
print("Curated by:", prov.curated_by)
Source type: datasheet
Curated by: Jane Smith

Step 8: Cell description#

[9]:
from battinfo.authoring import cell_description

# Use the known IRI for the A123 ANR26650M1-B example cell spec.
# For new records: publish a CellSpec first to get the IRI, then use it here.
A123_IRI = "https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5"

spec = cell_description(
    id=A123_IRI,
    manufacturer="A123 Systems",
    model="ANR26650M1-B",
    format="cylindrical",
    chemistry="Li-ion",
    positive_electrode_basis="LFP",
    negative_electrode_basis="graphite",
    size_code="R26650",
    positive_electrode=positive_electrode,
    negative_electrode=negative_electrode,
    electrolyte=lp30,
    separator=sep,
    construction=build,
    source=prov,
    comment=[
        "Descriptor curated from manufacturer datasheet and published literature.",
        "Electrode loadings estimated from capacity balance and assumed density.",
    ],
)

print("Cell ID:", spec.id)
print("Model:", spec.model)
Cell ID: https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5
Model: ANR26650M1-B

Step 9: Materials as first-class records#

Every material embedded above can also stand alone. extract_material_specs walks the descriptor — electrode coatings, electrolyte, separator — and lifts each distinct material into a standalone material-spec record with a deterministic IRI (the same material always mints the same IRI, so specs deduplicate across cells). Components then reference their spec via material_spec_id — the same spec-and-instance pattern cells use:

[10]:
from battinfo.materials import extract_material_specs

material_specs = extract_material_specs(spec.model_dump())
print(f"{len(material_specs)} standalone material spec(s):")
for record in material_specs:
    m = record["material_spec"]
    print(f"  {m['name']:14s} {m.get('material_class', '?'):22s} {m['id']}")
14 standalone material spec(s):
  LFP            active_material        https://w3id.org/battinfo/spec/s6y8-5mne-94gx-e5ve
  PVDF           binder                 https://w3id.org/battinfo/spec/fm9p-sqkk-tbx3-rr66
  Carbon black   conductive_additive    https://w3id.org/battinfo/spec/xz03-r714-wpa0-bwpb
  Aluminium foil current_collector      https://w3id.org/battinfo/spec/92ny-p3qm-6j9n-vrym
  Graphite       active_material        https://w3id.org/battinfo/spec/sm7b-n4y5-2hrk-dv6h
  CMC            binder                 https://w3id.org/battinfo/spec/t4wz-ff8s-6vp6-af48
  SBR            binder                 https://w3id.org/battinfo/spec/7p3d-2e22-7yae-spyb
  Copper foil    current_collector      https://w3id.org/battinfo/spec/ftdw-5z5h-mbn7-x13m
  LiPF6          electrolyte_salt       https://w3id.org/battinfo/spec/xcv1-hpy1-b0bw-z5s2
  EC             electrolyte_solvent    https://w3id.org/battinfo/spec/z6sr-a9yw-gryf-3q55
  DMC            electrolyte_solvent    https://w3id.org/battinfo/spec/va82-gnpn-v0bt-3qed
  VC             electrolyte_additive   https://w3id.org/battinfo/spec/nbz6-pn8h-4458-dh91
  FEC            electrolyte_additive   https://w3id.org/battinfo/spec/t59c-yz22-48as-tdkx
  Polypropylene  separator_material     https://w3id.org/battinfo/spec/n24p-ymxz-gj1j-q6pb

Step 10: Serialise the descriptor#

[11]:
# Write the descriptor to disk for inspection and downstream use.
desc_dir = SCRATCH / "descriptors"
desc_dir.mkdir(parents=True, exist_ok=True)
desc_path = desc_dir / "a123-anr26650m1-b.descriptor.json"
spec_dict = {"schema_version": "1.0.0", "specification": spec.to_json()}
desc_path.write_text(json.dumps(spec_dict, indent=2, ensure_ascii=False), encoding="utf-8")
print("Written:", desc_path)
print("Top-level keys:", list(spec_dict.keys())[:8])
Written: <repo>\docs\guides\_scratch\guide-05\descriptors\a123-anr26650m1-b.descriptor.json
Top-level keys: ['schema_version', 'specification']

Step 11: Map to domain-battery JSON-LD#

[12]:
from battinfo.transform.json_to_jsonld import to_jsonld

descriptor_doc = json.loads(desc_path.read_text(encoding="utf-8"))
desc_jsonld = to_jsonld(descriptor_doc, target="domain-battery")

battery = desc_jsonld["@graph"][0]
print("@type:", battery["@type"])
print()
pos = battery.get("hasPositiveElectrode", {})
print("Positive electrode @type:", pos.get("@type"))
neg = battery.get("hasNegativeElectrode", {})
print("Negative electrode @type:", neg.get("@type"))
@type: ['BatteryCellSpecification', 'schema:CreativeWork']

Positive electrode @type: LithiumIronPhosphateElectrode
Negative electrode @type: GraphiteElectrode
[13]:
# Export the domain-battery JSON-LD to disk
desc_jsonld_path = SCRATCH / "descriptors" / "a123-anr26650m1-b.domain-battery.jsonld"
desc_jsonld_path.write_text(
    json.dumps(desc_jsonld, indent=2, ensure_ascii=False),
    encoding="utf-8",
)
print(f"Domain-battery JSON-LD exported to: {desc_jsonld_path}")
print()
print(json.dumps(desc_jsonld, indent=2))
Domain-battery JSON-LD exported to: <repo>\docs\guides\_scratch\guide-05\descriptors\a123-anr26650m1-b.domain-battery.jsonld

{
  "@context": [
    "https://w3id.org/emmo/domain/battery/context",
    {
      "schema": "https://schema.org/",
      "dcterms": "http://purl.org/dc/terms/"
    }
  ],
  "@graph": [
    {
      "@type": [
        "BatteryCellSpecification",
        "schema:CreativeWork"
      ],
      "isDescriptionFor": {
        "@type": [
          "BatteryCell",
          "CylindricalBattery",
          "LithiumIonBattery",
          "LithiumIonIronPhosphateBattery",
          "LithiumIonGraphiteBattery"
        ]
      },
      "@id": "https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5",
      "schema:name": "A123 Systems ANR26650M1-B",
      "schema:model": "ANR26650M1-B",
      "schema:manufacturer": {
        "@type": "schema:Organization",
        "schema:name": "A123 Systems"
      },
      "schema:size": "R26650",
      "hasPositiveElectrode": {
        "hasCoating": {
          "@type": "ElectrodeCoating",
          "hasActiveMaterial": {
            "@type": [
              "LithiumIronPhosphate",
              "ActiveMaterial"
            ],
            "schema:name": "LFP",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.9
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            },
            "schema:description": "LiFePO4, olivine structure, D50 ~ 3 \u00b5m (Aleees GEN2)"
          },
          "hasBinder": {
            "@type": [
              "PolyvinylideneFluoride",
              "Binder"
            ],
            "schema:name": "PVDF",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.05
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            }
          },
          "hasConductiveAdditive": {
            "@type": [
              "CarbonBlack",
              "ConductiveAdditive"
            ],
            "schema:name": "Carbon black",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.05
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            },
            "schema:description": "Imerys C65"
          },
          "hasProperty": [
            {
              "@type": [
                "CalenderedDensity",
                "ConventionalProperty"
              ],
              "skos:prefLabel": "CalenderedDensity",
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 2.4
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#GramPerCubicCentiMetre"
            },
            {
              "@type": [
                "ActiveMassLoading",
                "ConventionalProperty"
              ],
              "skos:prefLabel": "ActiveMassLoading",
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 12.5
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#MilliGramPerSquareCentiMetre"
            }
          ],
          "schema:description": "NMP-cast, roll-calendered to 85% theoretical density"
        },
        "hasCurrentCollector": {
          "@type": [
            "CurrentCollector",
            "Aluminium",
            "Foil"
          ],
          "schema:name": "Aluminium foil",
          "hasProperty": {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 16.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MicroMetre"
          }
        },
        "@type": "LithiumIronPhosphateElectrode"
      },
      "hasNegativeElectrode": {
        "hasCoating": {
          "@type": "ElectrodeCoating",
          "hasActiveMaterial": {
            "@type": [
              "Graphite",
              "ActiveMaterial"
            ],
            "schema:name": "Graphite",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.955
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            },
            "schema:description": "Natural graphite, D50 ~ 20 \u00b5m"
          },
          "hasBinder": [
            {
              "@type": [
                "CarboxymethylCellulose",
                "Binder"
              ],
              "schema:name": "CMC",
              "hasProperty": {
                "@type": [
                  "MassFraction",
                  "ConventionalProperty"
                ],
                "hasNumericalPart": {
                  "@type": "RealData",
                  "hasNumberValue": 0.015
                },
                "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
              }
            },
            {
              "@type": [
                "StyreneButadiene",
                "Binder"
              ],
              "schema:name": "SBR",
              "hasProperty": {
                "@type": [
                  "MassFraction",
                  "ConventionalProperty"
                ],
                "hasNumericalPart": {
                  "@type": "RealData",
                  "hasNumberValue": 0.025
                },
                "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
              }
            }
          ],
          "hasConductiveAdditive": {
            "@type": [
              "CarbonBlack",
              "ConductiveAdditive"
            ],
            "schema:name": "Carbon black",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.005
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            }
          },
          "hasProperty": [
            {
              "@type": [
                "CalenderedDensity",
                "ConventionalProperty"
              ],
              "skos:prefLabel": "CalenderedDensity",
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 1.55
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#GramPerCubicCentiMetre"
            },
            {
              "@type": [
                "ActiveMassLoading",
                "ConventionalProperty"
              ],
              "skos:prefLabel": "ActiveMassLoading",
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 7.8
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#MilliGramPerSquareCentiMetre"
            }
          ]
        },
        "hasCurrentCollector": {
          "@type": [
            "CurrentCollector",
            "Copper",
            "Foil"
          ],
          "schema:name": "Copper foil",
          "hasProperty": {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 10.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MicroMetre"
          }
        },
        "@type": "GraphiteElectrode"
      },
      "hasElectrolyte": {
        "@type": "OrganicElectrolyte",
        "hasSolute": {
          "@type": [
            "LithiumHexafluorophosphate",
            "Solute"
          ],
          "schema:name": "LiPF6",
          "hasProperty": {
            "@type": [
              "AmountConcentration",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "AmountConcentration",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 1.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MolePerLitre"
          }
        },
        "hasSolvent": [
          {
            "@type": [
              "EthyleneCarbonate",
              "Solvent"
            ],
            "schema:name": "EC",
            "hasProperty": {
              "@type": [
                "VolumeFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.5
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            }
          },
          {
            "@type": [
              "DimethylCarbonate",
              "Solvent"
            ],
            "schema:name": "DMC",
            "hasProperty": {
              "@type": [
                "VolumeFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.5
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            }
          }
        ],
        "hasAdditive": [
          {
            "@type": [
              "VinyleneCarbonate",
              "ElectrolyteAdditive"
            ],
            "schema:name": "VC",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.02
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            },
            "schema:description": "SEI-forming additive"
          },
          {
            "@type": [
              "FluoroethyleneCarbonate",
              "ElectrolyteAdditive"
            ],
            "schema:name": "FEC",
            "hasProperty": {
              "@type": [
                "MassFraction",
                "ConventionalProperty"
              ],
              "hasNumericalPart": {
                "@type": "RealData",
                "hasNumberValue": 0.01
              },
              "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
            },
            "schema:description": "Fluoroethylene carbonate"
          }
        ],
        "schema:description": "LP30 + 2% VC + 1% FEC"
      },
      "hasSeparator": {
        "@type": [
          "Polypropylene",
          "Separator"
        ],
        "schema:name": "Polypropylene",
        "hasProperty": [
          {
            "@type": [
              "Porosity",
              "ConventionalProperty"
            ],
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 0.41
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#EMMO_5ebd5e01_0ed3_49a2_a30d_cd05cbe72978"
          },
          {
            "@type": [
              "Thickness",
              "ConventionalProperty"
            ],
            "skos:prefLabel": "Thickness",
            "hasNumericalPart": {
              "@type": "RealData",
              "hasNumberValue": 25.0
            },
            "hasMeasurementUnit": "https://w3id.org/emmo#MicroMetre"
          }
        ],
        "schema:description": "Celgard 2500, single-layer PP"
      },
      "schema:additionalProperty": [
        {
          "@type": "schema:PropertyValue",
          "schema:propertyID": "construction.assembly_type",
          "schema:name": "Assembly Type",
          "schema:value": "wound"
        },
        {
          "@type": "schema:PropertyValue",
          "schema:propertyID": "construction.layering",
          "schema:name": "Layering",
          "schema:value": "single_layer"
        },
        {
          "@type": "schema:PropertyValue",
          "schema:propertyID": "construction.layer_count",
          "schema:name": "Layer Count",
          "schema:value": 1
        },
        {
          "@type": "schema:PropertyValue",
          "schema:propertyID": "construction.comment",
          "schema:name": "Construction Comment",
          "schema:value": "Single jelly-roll, wound on 4 mm mandrel"
        }
      ],
      "schema:description": [
        "Descriptor curated from manufacturer datasheet and published literature.",
        "Electrode loadings estimated from capacity balance and assumed density."
      ],
      "schema:schemaVersion": "1.0.0"
    }
  ]
}

Step 12: Validate the descriptor JSON-LD#

[14]:
from battinfo.validate.jsonld import validate_jsonld_report

# Validate the domain-battery JSON-LD produced from the descriptor
report = validate_jsonld_report(desc_jsonld)
print("ok:", report.ok, "| errors:", len(report.errors), "| warnings:", len(report.warnings))
for issue in report.issues:
    print(f"  [{issue.severity}] {issue.code}: {issue.message}")
ok: True | errors: 0 | warnings: 0

Step 13: Publish#

The descriptor is the cell-spec record — publish it directly and the composition travels with it (note the positive_electrode key in the saved record, and that the IRI set in Step 8 is preserved):

[15]:
from battinfo import publish
from battinfo.api import publish_record

pub = publish(spec, destination="local", root=SCRATCH / "published")
record = json.loads(Path(pub.debug_paths["canonical_record_path"]).read_text(encoding="utf-8"))

print("IRI:         ", pub.canonical_iri)
print("Record keys: ", list(record.keys()))
IRI:          https://w3id.org/battinfo/spec/7d9k-2m4p-8t3x-6nq5
Record keys:  ['schema_version', 'cell_spec', 'properties', 'provenance', 'notes', 'construction', 'positive_electrode', 'negative_electrode', 'electrolyte', 'separator']
[16]:
output = publish_record(
    pub.debug_paths["canonical_record_path"],
    target_root=SCRATCH / "resolver",
)
jsonld_out = json.loads(
    Path(output["output_dir"], "index.jsonld").read_text(encoding="utf-8")
)

print("@type:", jsonld_out["@type"])
@type: ['BatteryCellSpecification', 'schema:CreativeWork']

Next#

Return to Guide 3 — Linked records to connect this descriptor cell spec to instances, tests, and datasets.