Skip to main content

PyOCE

Python Version License Ruff Mypy

PyOCE is a production-grade Python port of the CMS Integrated Outpatient Code Editor (I/OCE) — the official rules engine used by the Centers for Medicare & Medicaid Services to edit, group, and price hospital outpatient claims under the OPPS (Outpatient Prospective Payment System).

What Does the I/OCE Do?

The I/OCE applies 150+ clinical and administrative edit rules to each outpatient claim, including:

  • Validity checks — bill type, dates, diagnosis codes, HCPCS/CPT codes, modifiers, revenue codes
  • NCCI edits — procedure-to-procedure code pairs that should not be billed together
  • APC assignment — grouping services into Ambulatory Payment Classifications for pricing
  • Status indicator assignment — determining whether each line is payable, packaged, or denied
  • Discounting and packaging — applying OPPS payment logic (multiple procedure discounting, composite APCs, etc.)
  • Specialty handling — FQHC visits, biosimilars, telehealth, mental health, non-opioid therapies, Section 603, and more

PyOCE replicates this logic in pure Python, verified against the CMS Java reference implementation.

Features

  • Parity-tested — Cross-validated against official CMS Java TESTDB outputs across thousands of claims
  • High throughput — Optimized LMDB-backed reference data with zero-copy memory mapping; processes 1,000+ claims per second
  • Zero-config data — Reference database is bundled as a compressed archive and auto-extracted on first use
  • Version-aware — Full support for IOCE version ranges; lookups respect historical data boundaries
  • Thread-safe — LMDB supports concurrent reads from multiple processes/threads
  • Simple API — Plain dict in, plain dict out; no ORM, no protobuf, no ceremony
  • Self-contained — Single package with bundled reference data; no external services needed
  • Reusable engineIoceComponent gives access to edit descriptions, APC descriptions, and other lookup utilities

Installation

pip install pyoce

Requirements: Python 3.12+, no system dependencies beyond the Python standard library.

On first use, the bundled reference database (~2.7 MB compressed, ~10 MB uncompressed LMDB) is automatically inflated to ~/.cache/pyoce/.

Quick Start

import pyoce

claim = {
    "claimId": "DEMO-001",
    "billType": "131",
    "dateStarted": "20240101",
    "dateEnded": "20240101",
    "principalDiagnosisCode": {"diagnosis": "J449"},
    "lineItemList": [
        {
            "serviceDate": "20240101",
            "hcpcs": "99213",
            "revenueCode": "0510",
            "unitsInput": "1",
            "charge": "15000",
        }
    ],
}

result = pyoce.process_claim(claim)

# Inspect results
print(f"Return code: {result['processingInformation']['returnCode']}")
for li in result["lineItemList"]:
    print(f"  {li['hcpcs']} → APC {li['paymentApc']}, SI {li['statusIndicator']}")

# Look up edit descriptions (human-readable)
engine = pyoce.IoceComponent()
assert result is engine.process(claim)  # same API, reusable
print(engine.get_edit_description("001"))
print(engine.get_apc_description("5021"))

Input Fields

Field Type Notes
claimId str Unique claim identifier
billType str 3-char bill type (e.g. "131" for hospital outpatient)
dateStarted / dateEnded str YYYYMMDD format
receiptDate str YYYYMMDD, used for version range lookups
principalDiagnosisCode dict {"diagnosis": "J449", "presentOnAdmission": "Y"}
secondaryDiagnosisCodeList list[dict] Additional diagnosis codes
lineItemList list[dict] Per-line: hcpcs, revenueCode, serviceDate, unitsInput, charge, optional modifiers

See the src/pyoce/model/external/ package for the full external model.

Output Fields

The output dict mirrors the input structure with additions:

  • Claim-level: claimDisposition, claimRejectionEditList, claimDenialEditList, etc.
  • Line-level: paymentApc, statusIndicator, paymentIndicator, discountingFormula, rejectionDenialFlag, edit lists per buffer type
  • Processing metadata: returnCode, version, timing information

How It Works

Claims flow through a 5-phase sequential pipeline:

INITIALIZATION → PREPROCESSING → PROCESSING → POSTPROCESSING → FINALIZATION
Phase Responsibility
Initialization Load and validate reference data tables (cached after first claim)
Preprocessing Copy input to internal model, validate bill type/dates, load table data per claim, validate contractor overrides
Processing Execute 150+ edit rules, routed by bill type (see below)
Postprocessing Calculate disposition, payment flags, discounting, composite APCs, units
Finalization Copy internal processing state back to external output model

Bill Type Routing

The processing phase dispatches to one of 24 bill-type-specific logic paths based on the claim's bill type, OPPS/non-OPPS flag, and condition codes. The most common path — 13x (Hospital Outpatient) — applies approximately 150 sequential rule checks including NCCI edits, status/payment indicator assignment, add-on code pairing, modifier validation, and specialty payment logic.

For a complete bill-type routing table, see the internal architecture documentation.

Reference Data

PyOCE ships with a pre-built LMDB database containing 39 CMS reference tables (213,277 records) covering APC assignments, HCPCS code attributes, ICD-10 diagnoses, NCCI edit pairs, offset tables, status/payment indicators, composite APCs, and all add-on code mappings — versioned across the full IOCE version range.

Overriding the Database Location

from pyoce.dao.provider import LmdbDataProvider

# Point to a custom LMDB database
LmdbDataProvider.reset_instance()
provider = LmdbDataProvider(env_path="/path/to/pyoce.mdb")

Rebuilding the Database

To rebuild the LMDB database from CMS flat files:

uv run python scripts/build_db.py

This reads Report-Tables/ (not included in the repository) and writes src/pyoce/data/pyoce.mdb.xz.

Development

# Clone and install in editable mode with dev dependencies
git clone https://github.com/cms-gov/pyoce.git
cd pyoce
uv pip install -e ".[dev]"

CI Verification

Run the exact checks used in CI:

uv run ruff format --check .   # code formatting
uv run ruff check .             # linting
uv run mypy src                 # strict type checking
uv run pytest                   # full test suite

Testing

Suite Command Requires
Unit tests uv run pytest tests/unit Nothing
Integration (parity) uv run pytest tests/integration cms_mf/claims.json (CMS TESTDB)
Full suite uv run pytest cms_mf/claims.json

Unit tests cover flag enums, data providers, DAOs, external models, converters, utilities, and individual logic rules. Integration tests feed real CMS TESTDB claims through the engine and compare output field-by-field against the Java reference implementation.

Parity Report

Generate a detailed mismatch report for all claims with expected outputs:

PYTHONPATH=. uv run python tests/integration/test_parity_report.py

Or test a single claim by ID:

PYTHONPATH=. uv run python tests/integration/test_parity_report.py --claim <id>

Project Structure

src/pyoce/
├── __init__.py             # Public API: process_claim(), IoceComponent
├── api/                    # Entry points, claim execution engine
├── model/
│   ├── external/           # Public claim/line models (dataclasses)
│   └── internal/           # Processing state models (~50 fields per claim)
├── logic/
│   ├── initialization/     # Phase 1: load & validate tables
│   ├── preprocessing/      # Phase 2: validate inputs, load per-claim data
│   ├── processing/         # Phase 3: 150+ edit rules, bill-type paths
│   │   ├── addon/          # Add-on code pairing logic
│   │   └── specialty/      # FQHC, biosimilar, telehealth, S603, etc.
│   ├── postprocessing/     # Phase 4: disposition, flags, composites
│   └── finalization/       # Phase 5: output marshaling
├── dao/                    # Data access layer (42 table DAOs, description provider)
├── rsc/                    # Flag enums, edit registry, constants
├── util/                   # FlagSet, Navigator, range maps, utilities
└── data/                   # Bundled LMDB database (compressed)

License

Apache License, Version 2.0 — see LICENSE.

Contributing

See CONTRIBUTING.md for development setup, coding standards, and pull request guidelines.

Release files for pyoce 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyoce 0.1.0
File Size Uploaded
pyoce-0.1.0.tar.gz 3.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pyoce 0.1.0
File Interpreter ABI Platform
pyoce-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 6.4 MB

Release files / pyoce-0.1.0.tar.gz

Download URL pyoce-0.1.0.tar.gz
Size 3.1 MB
Tags Source
SHA-256 checksum
How to use checksums
00b82ae43d44c5fed7825c46c953c5119722300d55e2e4346ac391af790e0dea
BLAKE2b-256 checksum
How to use checksums
3f692a42b73ffc427d829decff4a387e7bf2391ad05aa89b95c7a62dc80d34ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Release files / pyoce-0.1.0-py3-none-any.whl

Download URL pyoce-0.1.0-py3-none-any.whl
Size 3.3 MB
Tags Python 3
SHA-256 checksum
How to use checksums
f55810c1d036b6cd7cf9ba4ba8c2f1d67f997f19c9695976fb557cdb2c45e7be
BLAKE2b-256 checksum
How to use checksums
18653bf115ff1724555b647762041f62eba83aa468f593a5644d9fe37a9428b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page