Skip to main content

Parser for the French CIM-10 (ICD-10-FR) classification in ClaML format

Project description

cim10-claml

Parser for the French CIM-10 (ICD-10-FR) classification distributed by the ATIH in ClaML format. No dependencies outside the standard library.

Beyond reading the raw XML, the parser applies the CIM-10-specific ClaML semantics needed to get a usable code table:

  • Hierarchy — chapters, blocks, categories and subcategories with parent links, materialized paths (IX/I20-I25/I21/I21.0) and depths.
  • Chapter letter ranges — chapter IX gets I00-I99, so WHO-style cross-references (which cite a letter range like "I00-I99" rather than the chapter number IX) can be resolved to chapters.
  • Composed labels — ClaML subcategory labels are contextual (D48.6 is just "Sein"); the parent label is prepended so every code is self-descriptive ("Tumeur…, Sein").
  • Modifier semanticsModifiedBy inheritance down the parent chain, ExcludeModifier subtraction, and materialization of the modified codes: dotted sub-codes create a new level (E11 + .0E11.0), non-dotted sub-codes extend it (E11.0 + 0E11.00), chained when a leaf has both. Composed codes like I21.38 come out as regular entries with kind="modified".
  • Rubric rendering — inclusion / exclusion / note rubrics parsed from the fragment structure into HTML blocks: shared prefixes become nested lists, item runs become brace-groups (the typographic { layout of the printed CIM-10), with dagger/aster references preserved. Each block carries its French title ("Comprend :", "À l'exclusion de :", …).

Installation

pip install cim10-claml

Usage

from cim10_claml import parse_cim10

result = parse_cim10("cim10.xml")  # ClaML file from the ATIH

for cls in result.classes:
    print(cls.code, cls.kind, cls.label)
    # cls.parent_code, cls.path, cls.depth
    # cls.modifier_codes  — effective modifiers (inherited, minus exclusions)
    # cls.rubrics         — [{"kind": "exclusion", "title": "À l'exclusion de :", "html": ...}]

result.modifiers         # [ClamlModifier(code, description)]
result.modifier_classes  # [ClamlModifierClass(modifier, sub_code, label, usage, rubrics)]

Rendering helpers can also be used standalone on ClaML elements:

import xml.etree.ElementTree as ET
from cim10_claml import render_label_plain, render_rubric_blocks

el = ET.fromstring('<Label>Choléra</Label>')
render_label_plain(el)  # "Choléra"

Fragment rendering

In ClaML, inclusion/exclusion rubrics encode the printed layout of the CIM-10 book as <Fragment> sequences repeated across sibling rubrics. The fragment type sequence always follows the grammar item* list* item*: type="list" fragments sharing a prefix form indented lists, while type="item" fragments at the edges form the brace groups ({) of the printed book. render_rubric_blocks reconstitutes both.

Shared list prefix → nested list. The prefix "amnésie :" is repeated in every rubric; the renderer factors it out as a parent node (F04, reduced):

<Class code="F04">
  <Rubric kind="exclusion"><Label>
    <Fragment type="list">amnésie :</Fragment>
    <Fragment type="list">SAI<Reference class="in brackets">R41.3</Reference></Fragment>
  </Label></Rubric>
  <Rubric kind="exclusion"><Label>
    <Fragment type="list">amnésie :</Fragment>
    <Fragment type="list">antérograde<Reference class="in brackets">R41.1</Reference></Fragment>
  </Label></Rubric>
  <Rubric kind="exclusion"><Label>
    <Fragment type="list">amnésie :</Fragment>
    <Fragment type="list">dissociative<Reference class="in brackets">F44.0</Reference></Fragment>
  </Label></Rubric>
</Class>
render_rubric_blocks(ET.fromstring(xml))

returns one block (kind="exclusion", title="À l'exclusion de :") whose html is (whitespace added for readability):

<ul class="cim10-frag-list">
  <li>amnésie :
    <ul class="cim10-frag-list">
      <li>SAI (<a class="cim10-ref cim10-bracketed" data-link="class:R41.3">R41.3</a>)</li>
      <li>antérograde (<a class="cim10-ref cim10-bracketed" data-link="class:R41.1">R41.1</a>)</li>
      <li>dissociative (<a class="cim10-ref cim10-bracketed" data-link="class:F44.0">F44.0</a>)</li>
    </ul>
  </li>
</ul>

Shared item suffix → brace group. Here every rubric repeats the trailing item "à Salmonella"; the renderer emits one column per fragment position, with distinct values deduplicated — the on-screen equivalent of the printed brace. Fragment-level usage="dagger" propagates to the <li> and appends the glyph; aster references get * (A02.2, reduced):

<Class code="A02.2">
  <Rubric kind="inclusion"><Label>
    <Fragment type="item" usage="dagger">Arthrite<Reference class="in brackets" usage="aster">M01.3</Reference></Fragment>
    <Fragment type="item">à Salmonella</Fragment>
  </Label></Rubric>
  <Rubric kind="inclusion"><Label>
    <Fragment type="item" usage="dagger">Méningite<Reference class="in brackets" usage="aster">G01</Reference></Fragment>
    <Fragment type="item">à Salmonella</Fragment>
  </Label></Rubric>
  <Rubric kind="inclusion"><Label>
    <Fragment type="item" usage="dagger">Ostéomyélite<Reference class="in brackets" usage="aster">M90.2</Reference></Fragment>
    <Fragment type="item">à Salmonella</Fragment>
  </Label></Rubric>
</Class>

returns one block (kind="inclusion", title="Comprend :"):

<div class="cim10-brace-group" data-cols="2" style="--cols:2">
  <ul class="cim10-brace-col">
    <li class="cim10-dagger">Arthrite† (<a class="cim10-ref cim10-bracketed cim10-aster" data-link="class:M01.3">M01.3*</a>)</li>
    <li class="cim10-dagger">Méningite† (<a class="cim10-ref cim10-bracketed cim10-aster" data-link="class:G01">G01*</a>)</li>
    <li class="cim10-dagger">Ostéomyélite† (<a class="cim10-ref cim10-bracketed cim10-aster" data-link="class:M90.2">M90.2*</a>)</li>
  </ul>
  <ul class="cim10-brace-col">
    <li>à Salmonella</li>
  </ul>
</div>

The rubric HTML is intentionally unstyled structure (brace-group, brace-col, frag-list, ref CSS classes; data-link="class:J45" / data-link="modifier:S04E10_4" attributes on references). Styling — CSS grid columns from --cols, drawing the brace, list bullets — and link resolution are up to the consumer.

Every emitted CSS class is namespaced to avoid clashing with the consumer's stylesheet. The prefix defaults to cim10- (so refcim10-ref, brace-groupcim10-brace-group, and classes carried through from the source XML like <Para class="headingIntro">cim10-headingIntro) and is configurable via css_prefix on both parse_cim10 and render_rubric_blocks:

parse_cim10("cim10.xml", css_prefix="icd-")   # icd-ref, icd-brace-group, …
render_rubric_blocks(el, css_prefix="")        # bare: ref, brace-group, …

For the full format survey (rubric kinds, all 13 fragment patterns found in the 2025 corpus, edge cases), see docs/claml-format.md and docs/fragment-cases.md.

Data

This package contains no CIM-10 data — only a parser. The classification itself is published by the ATIH (and derives from the WHO ICD-10, licensed CC BY-NC-ND 3.0 IGO); obtain the ClaML XML from the ATIH and check its license terms for your use case.

License

MIT (the code only — see the data note above).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cim10_claml-0.1.0.tar.gz (42.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cim10_claml-0.1.0-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file cim10_claml-0.1.0.tar.gz.

File metadata

  • Download URL: cim10_claml-0.1.0.tar.gz
  • Upload date:
  • Size: 42.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cim10_claml-0.1.0.tar.gz
Algorithm Hash digest
SHA256 95d781434c2148567e005257b0e5231ac27b545a0d758f6f8c31b7eeb99a5cec
MD5 1fff694f8ba2a586d55f1f1f5ba97ff4
BLAKE2b-256 2ce212b9be689b2351dbe95ebffae259c0894cf71b95c2107257ce83d0766e7b

See more details on using hashes here.

File details

Details for the file cim10_claml-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cim10_claml-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cim10_claml-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b396a0c4b9d8764e740cfe93a5d634c25d675e084bfdf128e5a42ad790d851e6
MD5 f7da9942f28fa52e800a9beb223a7d68
BLAKE2b-256 698b91ba3c12956c0a789b14b5962ed36071b5c0b23ef6c7de4f4436618e99f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page