Metadata-Version: 2.5
Name: openlabel-checker
Version: 0.1.0
Summary: Validator and quality checker for ASAM OpenLABEL 1.0.0 annotation files.
Project-URL: Homepage, https://github.com/deepenai/openlabel-checker
Project-URL: Issues, https://github.com/deepenai/openlabel-checker/issues
Author: Mohammad Musa
License-Expression: MPL-2.0
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.9
Requires-Dist: jsonschema>=4.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# openlabel-checker

A validator and quality checker for [ASAM OpenLABEL](https://www.asam.net/standards/detail/openlabel/)
1.0.0 annotation files.

OpenLABEL is the JSON-based format ASAM standardizes for object, action,
event, and context annotations in autonomous-driving and robotics data. ASAM
publishes an official [Quality Checker framework](https://github.com/asam-ev/qc-framework)
(MPL-2.0) with checker bundles for OpenDRIVE, OpenSCENARIO XML, OTX, and
OpenMATERIAL 3D — but no equivalent exists yet for OpenLABEL. This project
fills that gap: it validates a file against the official OpenLABEL JSON
Schema and runs a set of structural/semantic checks the schema alone can't
express (dangling references, inverted frame intervals, negative bounding
box dimensions, and so on).

## Install

```sh
pip install openlabel-checker
```

## Usage

```sh
openlabel-check annotations.json
```

```
openlabel-check: annotations.json
  ERROR check_geometry: bbox 'bbox_shape' has negative dimension w=-5.0 [openlabel.objects.1.object_data.bbox[0]]
  WARN  check_frame_intervals: frame_intervals[1] (0-3) overlaps frame_intervals[2] (2-4) [openlabel.objects.1]
summary: 1 error(s), 1 warning(s), 0 info
```

Exit code is `0` if no `error`-severity issues were found, `1` otherwise —
so it's usable as a CI gate.

Pass `--json` for a machine-readable report:

```sh
openlabel-check annotations.json --json
```

```json
{
  "file": "annotations.json",
  "checkers": [
    {
      "checker_id": "check_geometry",
      "description": "Checks bbox/rbbox/cuboid values parse and have non-negative dimensions.",
      "status": "completed",
      "issues": [
        {
          "checker_id": "check_geometry",
          "severity": "error",
          "message": "bbox 'bbox_shape' has negative dimension w=-5.0",
          "path": "openlabel.objects.1.object_data.bbox[0]"
        }
      ]
    }
  ],
  "summary": { "error": 1, "warning": 0, "info": 0 }
}
```

## Checkers

Every checker has a stable, `check_`-prefixed ID and a severity per issue
(`error` / `warning` / `info`). `check_json_schema` validates against the
schema; everything else is a structural or semantic check the schema can't
express on its own.

| Checker ID | What it checks |
|---|---|
| `check_json_schema` | Conformance to the official ASAM OpenLABEL v1.0.0 JSON Schema (draft-07). |
| `check_frame_intervals` | Frame intervals aren't inverted or negative, don't overlap within one element, and are consistent with the frames actually declared in `openlabel.frames`. |
| `check_element_references` | Objects/actions/events/contexts referenced by a frame, or by a relation's `rdf_subjects`/`rdf_objects`, are declared at the top level. |
| `check_geometry` | `bbox`, `rbbox`, and `cuboid` values parse as numbers, have the right length, and have non-negative width/height/dimensions. |
| `check_timestamps_monotonic` | `frame_properties.timestamp`, and any per-stream `timestamp` override, is non-decreasing across ascending frame numbers. |
| `check_coordinate_systems` | `coordinate_system` references (on objects and their geometric data) and `coordinate_systems[*].parent`/`children` point at declared coordinate systems; frame-level stream references point at declared streams. |
| `check_element_data_pointers` | An object's `object_data_pointers` agree with the `object_data` actually present in its declared frame intervals, in both directions. |
| `check_duplicate_uids` | No UID (or frame number) is written twice in the same JSON object — a case `json` parsers silently collapse by keeping the last value, hiding real data loss. |

## Design notes

- The vendored schema is the official file ASAM serves at
  `https://openlabel.asam.net/V1-0-0/schema/openlabel_json_schema.json`
  (see `src/openlabel_checker/schema_data/PROVENANCE.md`). No local
  modifications.
- The `Issue` model (`checker_id`, `severity`, `message`, `path`) deliberately
  mirrors the ASAM qc-framework's `CheckerBundle` → `Checker` → `Issue` result
  model, so this tool's output can be re-serialized into that framework's
  `.xqar` result format later without a redesign — the goal is that this
  project could eventually become the framework's `qc-openlabel` bundle.
  That serializer (an `--format asam-qc` flag) is out of scope for this first
  version; only the internal model is shaped to make it a straightforward
  follow-up.

## Development

```sh
pip install -e ".[dev]"
pytest
```

## Contributing

Issues and PRs welcome. Checkers live one-per-file under
`src/openlabel_checker/checkers/`; each is a plain function from the parsed
document to a `CheckerOutcome`, with fixtures in `tests/fixtures/` that trip
it. Keep new checkers narrowly scoped and add a fixture alongside them.

## License

MPL-2.0. See [LICENSE](LICENSE).
