Metadata-Version: 2.4
Name: opencbam
Version: 0.1.0
Summary: Open-source validation and calculation toolkit for EU CBAM data workflows
Project-URL: Homepage, https://github.com/ia-climateops/opencbam-core
Project-URL: Repository, https://github.com/ia-climateops/opencbam-core
Project-URL: Issues, https://github.com/ia-climateops/opencbam-core/issues
Author: IA Climate Ops
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: carbon,carbon-border,cbam,climate,compliance,emissions,eu
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: openpyxl>=3.1; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: xlsx
Requires-Dist: openpyxl>=3.1; extra == 'xlsx'
Description-Content-Type: text/markdown

# OpenCBAM Core

**Open-source validation and calculation toolkit for EU CBAM data workflows.**

The EU Carbon Border Adjustment Mechanism (CBAM) is a live regulation: from 2026, importers of covered
goods owe a real, per-shipment financial liability tied to the embedded emissions of what they bring in.
The numbers behind that liability — default values, benchmarks, free allocation, certificates due — come
straight from EU regulation, but until now there has been no open, auditable reference implementation of
them. OpenCBAM Core is that implementation: a stateless, dependency-free Python toolkit where every formula
is traceable to a regulation and every result ships with a plain-language audit trail.

[![CI](https://github.com/ia-climateops/opencbam-core/actions/workflows/ci.yml/badge.svg)](https://github.com/ia-climateops/opencbam-core/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/opencbam.svg)](https://pypi.org/project/opencbam/)
[![Python](https://img.shields.io/pypi/pyversions/opencbam.svg)](https://pypi.org/project/opencbam/)
[![License: Apache-2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)

---

## Contents

- [Install](#install)
- [Quickstart](#quickstart)
  - [Python](#python)
  - [CLI](#cli)
- [What's in the box](#whats-in-the-box)
- [Open core](#open-core)
- [Grounded in regulation](#grounded-in-regulation)
- [Not legal advice](#not-legal-advice)
- [Contributing](#contributing)

---

## Install

```bash
pip install opencbam
```

Zero runtime dependencies — pure Python standard library, Python 3.10+. The optional `openpyxl` extra is
only needed to read `.xlsx` inputs (`.csv` works out of the box):

```bash
pip install "opencbam[xlsx]"
```

---

## Quickstart

### Python

Assess 100 t of steel wire rod imported from Türkiye, using default values, at an 80 EUR/t certificate
price. The commented values below are the **real output** of running this snippet:

```python
from decimal import Decimal
from opencbam import assess_good
from opencbam.engine.types import DataSource, Sector

r = assess_good(
    cn_code="72071111",
    country="Türkiye",
    mass=Decimal("100"),
    year=2026,
    data_source=DataSource.DEFAULT,
    sector=Sector.IRON_STEEL,
    certificate_price=Decimal("80"),
)

r.embedded_emissions   # Decimal("254.100")     t CO2e
r.free_allocation      # Decimal("132.990000")  free allocation
r.certificates_due     # Decimal("121.110")     CBAM certificates
r.liability_eur        # Decimal("9688.80")     EUR at 80/t
r.audit                # 5 human-readable trace lines explaining every step
```

Every field uses `decimal.Decimal` — never float — and `r.audit` explains each step in plain language, e.g.:

```text
free allocation: benchmark 1.364 (Column B (default)) x CBAM_y 0.975 x CSCF 1 = SEFA 1.329900; FAA 132.990000
certificates due = max(0, 254.100 - 132.990000 - 0.000) = 121.110; liability = 9688.80 EUR @ 80/t
```

`assess_good(...)` is keyword-only and returns a typed [`GoodAssessment`](src/opencbam/engine/orchestrator.py).
It raises `ValueError` for years before 2026.

### CLI

Installing the package also installs the `opencbam` command (or run `python -m opencbam`). All six
subcommands work today.

**Is a CN / commodity code covered by CBAM Annex I?**

```bash
$ opencbam covered 72071111
72071111: covered
  sector : iron_steel
  good   : Rolled or obtained by continuous casting of free-cutting steel
```

**Run a full assessment from the shell** — the same scenario as the Python example above:

```bash
$ opencbam calculate --cn 72071111 --country Türkiye --mass 100 --price 80
✓ 72071111 — Türkiye, 100 t (iron_steel, default values, year 2026)
  embedded emissions : 254.100 t CO2e
  free allocation    : 132.990000 t CO2e
  certificates due   : 121.110 certificates
  liability          : 9688.80 EUR
  audit trail:
    · … 5 lines explaining every step (SEE, benchmark, free allocation, certificates, liability)
```

**Validate a supplier file** (`.csv`, or `.xlsx` with the `opencbam[xlsx]` extra):

```bash
$ opencbam validate examples/supplier-data.csv
✗ 8 rows validated
  WARNING row 5  Duplicate of row 1 (same CN, country and shipment/installation id)
  ERROR   row 6  CN code '84073290' is not a CBAM Annex I covered good
  ERROR   row 7  Emissions value -15.0 is negative
  ERROR   row 8  Missing required field 'quantity'
  3 error(s), 1 warning(s)
```

It exits non-zero when there are errors, so it drops cleanly into scripts and CI.

**Score a file's data quality:**

```bash
$ opencbam check-quality examples/supplier-data.csv
Data Quality Score: 60/100
  Missing fields    : 1
  Invalid units     : 1
  Duplicate records : 1
  Suspicious values : 0
```

**Convert units** with exact `Decimal` arithmetic: `opencbam convert 5 MWh kWh` prints `5000 kWh`.

`calculate`, `validate`, and `check-quality` accept `--json` for machine-readable output. Extending the CLI
(more ERP connectors, `--strict` / `--quiet`, batch mode) is where many of the
[good first issues](docs/ISSUE_BACKLOG.md) live.

---

## What's in the box

- **Calculation engine** — embedded emissions, attribution, free allocation, certificates due and EUR
  liability via a single `assess_good` entry point.
- **Covered-goods + CN lookup** — `is_covered_cn`, `lookup_good`, `sector_for_cn`, `search_goods` over the
  CBAM Annex I goods list.
- **Default values** — marked-up default emission values by country and CN code (`get_default_value`,
  `get_marked_up_default`, `country_is_listed`).
- **Electricity track** — the CN 2716 imported-electricity methodology (`electricity_emission_factor`,
  `embedded_electricity`, indirect grid factors). The IEA CC BY-NC-SA grid-factor _data_ is **not bundled**;
  the code is, and you supply the factors under an appropriate licence (see [`docs/DATA.md`](docs/DATA.md)).
- **Data-quality grading (A–E)** — `grade_emission_profile`, `grade_supplier_form`, `aggregate` for scoring
  how trustworthy a supplier's numbers are.
- **Unit conversions** — exact, `Decimal`-based conversion between CBAM quantity units.
- **Row-level validation** — structured pass/fail checks over supplier data files.
- **CLI** — the `opencbam` command-line tool.
- **Typed Python SDK** — fully type-hinted (`py.typed`), stdlib-only, ready to import.

---

## Open core

OpenCBAM Core is the open, stateless **calculation and validation core** of the commercial
[IA Climate Ops](https://github.com/ia-climateops) CBAM platform. The numbers live here, in the open, where
anyone can read and verify them. The platform builds the workflow, data, and collaboration layer on top.

| In this repo (Apache-2.0) | Added by the IA Climate Ops platform |
| --- | --- |
| Stateless calculation of embedded emissions, free allocation, certificates & liability | Client, facility and supplier management |
| Covered-goods / CN lookup, default values, electricity factors | Supplier portal for collecting primary data |
| Data-quality grading (A–E) | Annual declaration workflows |
| Unit conversion & row-level validation | CBAM certificate cockpit |
| CLI + typed Python SDK | Article 9 evidence vault & audit trail |
| Regulation-traceable formulas with audit trails | Multi-tenancy, RBAC, AI copilot / RAG, billing, consultant dashboard |

If you only need to compute or validate the numbers, this repo is all you need.

---

## Grounded in regulation

Every formula and bundled dataset is traceable to a specific EU legal source, including:

- **IR (EU) 2025/2620** — free-allocation benchmarks.
- **IR (EU) 2025/2621** — default values, indirect and precursor emission factors, electricity factors.
- **Reg (EU) 2023/956** — the CBAM Regulation and its Annex I covered-goods list.

The full source-to-code mapping is in [`SOURCES.md`](SOURCES.md). The engine ships with **266 golden tests**
that pin each calculation to its expected regulatory result, run on every push across Python 3.10–3.12.

---

## Not legal advice

This software is **not legal, tax or compliance advice**, and is **not affiliated with, endorsed by, or an
official product of the European Union** or any EU institution. Regulatory texts and default values change,
and some figures (for example the cross-sectoral correction factor) are provisional until the Commission
publishes final values. Always confirm results against the current official regulation and consult a
qualified professional before relying on them for a declaration. Provided "as is" under the
[Apache-2.0 License](LICENSE), without warranty of any kind.

---

## Contributing

Contributions are welcome — the CLI command surface, in particular, is a great on-ramp. Start with
[`CONTRIBUTING.md`](CONTRIBUTING.md) for setup, house style and the test workflow, and browse
[`docs/ISSUE_BACKLOG.md`](docs/ISSUE_BACKLOG.md) — **good first issues welcome**.

---

_Maintained by IA Climate Ops._
