Skip to main content

ansi-x12

PyPI version Python versions CI Coverage License

A framework-independent Python library for generic ANSI X12 processing and incremental transaction-set support.

ansi-x12 provides a byte-oriented core for separator discovery, tokenization, envelope parsing, structural validation, and inspection. Transaction-specific support is layered separately under x12.transactions.

The generic core remains transaction-neutral and trading-partner-neutral. Transaction packages may understand standard transaction meaning and structure, while implementation-guide rules and application-specific behavior remain in the consuming integration.

Installation

Install the latest release from PyPI:

pip install ansi-x12

The distribution name is ansi-x12; the Python import package is x12:

import x12

The package has no runtime dependencies.

Quick Start

from pathlib import Path

from x12 import (
    inspect_x12_interchange,
    parse_x12_interchange,
    tokenize_x12,
)

payload = Path("message.x12").read_bytes()

document = tokenize_x12(payload)
interchange = parse_x12_interchange(document)
inspection = inspect_x12_interchange(interchange)

print(interchange.control_number)
print(inspection.transaction_set_codes)
print(inspection.total_segment_count)

The parser accepts bytes, preserves the original payload on X12Document.raw, and returns immutable structural models.

Package Scope

The package is divided into two intentional layers:

x12.core
    Generic ANSI X12 syntax, envelopes, parsing, validation, and inspection

x12.transactions
    Transaction-specific ANSI X12 models and parsers

Dependency direction is one-way:

x12.transactions  →  x12.core
x12.core          ✕  x12.transactions

The core must remain usable without loading or understanding transaction definitions.

Applications may build an additional layer above the package for implementation-guide rules, partner-specific restrictions, persistence, transport, and business mappings.

Generic Core

The current core provides:

  • separator discovery from the fixed-width ISA segment;
  • byte-oriented tokenization;
  • immutable segment and document models;
  • ISA/IEA interchange parsing;
  • TA1 interchange acknowledgment support;
  • GS/GE functional-group parsing;
  • ST/SE transaction-set parsing;
  • envelope ordering and nesting validation;
  • control-number validation;
  • declared-count validation;
  • structural inspection and segment inventories;
  • inline type information through py.typed.

What the Core Does

x12.core handles concerns common to X12 interchanges regardless of the transaction-set type:

  • derives the element, repetition, component, and segment separators;
  • supports non-default separator bytes;
  • preserves empty positional elements;
  • preserves element values as raw bytes;
  • retains original document bytes and source segment order;
  • assigns contiguous, zero-based segment indexes;
  • exposes one-based X12 element access;
  • organizes flat segment streams into immutable envelope models;
  • validates envelope boundaries and nesting;
  • validates matching ISA13/IEA02, GS06/GE02, and ST02/SE02 values;
  • validates IEA01, GE01, and SE01 declared counts;
  • preserves optional ST03 and ST04 references;
  • supports TA1-only interchanges and TA1 segments before functional groups;
  • rejects empty functional groups;
  • produces transaction, group, segment, and frequency summaries.

What the Core Does Not Do

The generic core does not interpret transaction-specific business meaning.

It does not:

  • decide what a transaction-set code means;
  • interpret transaction-specific segments or qualifiers;
  • validate implementation-guide or companion-guide rules;
  • map X12 data into application or database models;
  • manage trading-partner profiles;
  • persist data;
  • send messages through AS2, SFTP, APIs, or other transports;
  • depend on Django, Flask, FastAPI, or another application framework.

Those concerns belong in x12.transactions or in a higher application layer.

Transaction Support

Transaction-specific support lives under x12.transactions.

The first supported transaction package is:

x12.transactions.t322

It provides typed support for ANSI X12 322 Terminal Operations and Intermodal Ramp Activity transactions while preserving the same design principles as the core:

  • immutable models;
  • raw byte values;
  • deterministic parsing;
  • explicit structure;
  • no framework dependency;
  • no trading-partner-specific validation in the generic package.

Example:

from x12 import parse_x12_interchange, tokenize_x12
from x12.transactions.t322 import parse_x12_322

document = tokenize_x12(payload)
interchange = parse_x12_interchange(document)

for group in interchange.groups:
    for transaction in group.transactions:
        if transaction.transaction_set_code == b"322":
            message = parse_x12_322(transaction)
            print(message.control_number)

For detailed 322 usage, models, extension guidance, and application integration patterns, see docs/322.md.

Transaction-specific names are intentionally not re-exported from top-level x12. This keeps the public hierarchy explicit and scalable as additional transaction sets are added.

Architecture

Generic parsing follows this flow:

Raw X12 bytes
    │
    ▼
Separator discovery
    │
    ▼
Tokenizer
    │
    ▼
X12Document and X12Segment
    │
    ▼
Envelope parser and structural validation
    │
    ▼
X12Interchange
    │
    ▼
Structural inspection

When a supported transaction parser is used, the flow continues:

X12TransactionSet
    │
    ▼
x12.transactions.<transaction>
    │
    ▼
Typed transaction model
    │
    ▼
Application profile / mapper

The package layout mirrors that separation:

x12
├── __init__.py          Curated generic public API
├── py.typed             PEP 561 type marker
├── core/                Generic X12 infrastructure
└── transactions/        Transaction-specific packages

Core Models

Separators

derive_x12_separators() reads separator bytes from the fixed-width ISA segment:

from x12 import derive_x12_separators

separators = derive_x12_separators(payload)

print(separators.element)
print(separators.repetition)
print(separators.component)
print(separators.segment)

X12Separators contains:

  • element
  • repetition
  • component
  • segment

For interchange version 00402 and later, ISA11 is exposed as the repetition separator. Earlier versions expose None for repetition.

Segments and Documents

tokenize_x12() converts raw bytes into an immutable X12Document:

from x12 import tokenize_x12

document = tokenize_x12(payload)

Each X12Segment contains:

  • a zero-based source index;
  • an ASCII segment tag;
  • ordered raw-byte elements;
  • the raw segment bytes.

Element access uses one-based X12 positions:

segment = document.find_segments("ST")[0]

assert segment.element(1) == b"999"
assert segment.element(2) == b"0001"
assert segment.element(3) is None

Empty and missing values remain distinct:

assert segment.element(1) == b""
assert segment.element(20) is None

Documents support iteration and length:

for segment in document:
    print(segment.index, segment.tag)

print(len(document))

The tokenizer ignores permitted formatting whitespace between segments while retaining the complete original payload in document.raw.

Envelopes

parse_x12_interchange() converts a tokenized document into a validated envelope hierarchy:

from x12 import parse_x12_interchange

interchange = parse_x12_interchange(document)

The resulting hierarchy is:

ISA
├── TA1, when present
├── GS
│   ├── ST
│   │   ├── transaction body
│   │   └── SE
│   └── GE
└── IEA

The immutable envelope models are:

  • X12TransactionSet
  • X12FunctionalGroup
  • X12Interchange

They expose structural values such as control numbers, versions, declared counts, actual counts, ordered segment collections, and transaction-set codes.

Structural Validation

The parser validates:

  • ISA as the first segment;
  • IEA as the final segment;
  • valid TA1 placement;
  • GS/GE functional-group boundaries;
  • ST/SE transaction-set boundaries;
  • required envelope elements;
  • envelope element counts;
  • invalid nested envelope segments;
  • matching ST02 and SE02 values;
  • matching GS06 and GE02 values;
  • matching ISA13 and IEA02 values;
  • SE01 transaction segment counts;
  • GE01 transaction-set counts;
  • IEA01 functional-group counts;
  • at least one transaction set in each functional group;
  • at least one TA1 acknowledgment or functional group in an interchange.

Inspection

inspect_x12_interchange() builds an immutable X12InspectionResult from a validated interchange:

from x12 import inspect_x12_interchange

inspection = inspect_x12_interchange(interchange)

print(inspection.transaction_set_codes)
print(inspection.total_segment_count)
print(inspection.unique_segment_tags)
print(inspection.repeating_segment_tags)

Inspection models include:

  • X12SegmentFrequency
  • X12TransactionInspection
  • X12FunctionalGroupInspection
  • X12InspectionResult

Inspection reports structural metadata only. It does not interpret transaction-specific business content.

Public API

Generic application code should import from the package root:

from x12 import (
    X12Document,
    X12EnvelopeError,
    X12Error,
    X12FunctionalGroup,
    X12FunctionalGroupInspection,
    X12InspectionResult,
    X12Interchange,
    X12Segment,
    X12SegmentError,
    X12SegmentFrequency,
    X12SeparatorError,
    X12Separators,
    X12TokenizerError,
    X12TransactionInspection,
    X12TransactionSet,
    derive_x12_separators,
    inspect_x12_interchange,
    parse_x12_interchange,
    tokenize_x12,
)

Most generic consumers only need:

from x12 import (
    inspect_x12_interchange,
    parse_x12_interchange,
    tokenize_x12,
)

Transaction-specific APIs should be imported from their dedicated package:

from x12.transactions.t322 import X12322, parse_x12_322

Implementation modules under x12.core and individual transaction modules are organized internally. The curated package entry points should be preferred by application code.

Exception Hierarchy

Generic structural errors use:

X12Error
├── X12EnvelopeError
│   └── X12SeparatorError
└── X12TokenizerError
    └── X12SegmentError

Catch X12Error when structural failures should be handled together:

from x12 import X12Error

try:
    document = tokenize_x12(payload)
    interchange = parse_x12_interchange(document)
except X12Error as exc:
    print(f"Invalid X12 document: {exc}")

Transaction-specific parsers may additionally raise errors appropriate to their transaction layer when a validated generic transaction cannot be interpreted safely.

Byte-Oriented API

The parsing API accepts bytes, not text strings:

payload = Path("message.x12").read_bytes()
document = tokenize_x12(payload)

This is intentional. X12 separators are single-byte structural values, and the ISA separator positions are fixed byte offsets. A byte-oriented API avoids accidental decoding, normalization, or whitespace changes before structural processing is complete.

Applications may decode individual element values later using the character encoding required by their implementation guide or trading partner.

Immutability

Core, inspection, and current transaction models use frozen dataclasses with slots.

Immutability makes parsed results:

  • deterministic;
  • resistant to accidental modification;
  • easier to validate, test, and audit;
  • safe to pass through application layers without in-place mutation.

Construction and serialization will use explicit APIs rather than mutating parsed objects in place.

Type Information

The wheel includes a py.typed marker and inline annotations. Type checkers can consume the installed package directly:

from x12 import X12Interchange, parse_x12_interchange
from x12.transactions.t322 import X12322

The project is checked with mypy in strict mode.

Package Layout

.
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── publish.yml
├── docs/
│   ├── 322.md
│   └── RELEASING.md
├── scripts/
├── src/
│   └── x12/
│       ├── __init__.py
│       ├── py.typed
│       ├── core/
│       │   ├── __init__.py
│       │   ├── envelopes.py
│       │   ├── exceptions.py
│       │   ├── inspection.py
│       │   ├── inspector.py
│       │   ├── parser.py
│       │   ├── segments.py
│       │   ├── separators.py
│       │   └── tokenizer.py
│       └── transactions/
│           ├── __init__.py
│           └── t322/
│               ├── __init__.py
│               ├── details.py
│               ├── equipment.py
│               ├── location.py
│               ├── loops.py
│               ├── models.py
│               ├── parser.py
│               ├── parties.py
│               └── status.py
├── tests/
│   ├── core/
│   ├── transactions/
│   │   └── t322/
│   └── test_public_api.py
├── CODE_OF_CONDUCT.md
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── pyproject.toml
└── uv.lock

Local private development data may also exist under private_data/. That directory is ignored by Git and is not part of the package or public test corpus.

Current Limitations

The project is intentionally focused and does not yet provide:

  • serialization of structured models back to X12 bytes;
  • builders for creating new interchanges;
  • automatic envelope or control-number generation;
  • streaming tokenization;
  • length-aware BIN segment parsing;
  • ISX release-character support;
  • comprehensive support for every X12 transaction set;
  • implementation-guide or trading-partner validation in the generic package.

These are explicit boundaries, not hidden behavior. Features are added only when they can preserve the package's generic, deterministic architecture.

Development

The project uses:

  • uv
  • pytest
  • pytest-cov
  • pytest-xdist
  • Ruff
  • mypy
  • build
  • Twine

Clone and install development dependencies:

git clone https://github.com/fifoa-labs/x12.git
cd x12
make sync

Common commands:

make format          # Apply formatting and safe fixes
make format-check    # Check formatting
make lint            # Run Ruff linting
make typecheck       # Run strict mypy checks
make test            # Run the test suite
make test-fast       # Run tests in parallel
make coverage        # Run statement and branch coverage
make check           # Run normal local validation
make release-check   # Run full release validation and build checks

Repository maintainers may also have transaction-specific local smoke or inspection utilities backed by ignored private development data. Those tools are intentionally separate from CI and the public package.

Testing and Quality

The test suite covers:

  • separator extraction and separator invariants;
  • custom separators;
  • legacy and modern ISA versions;
  • malformed fixed-width ISA segments;
  • byte-oriented tokenization;
  • empty positional elements;
  • inter-segment formatting whitespace;
  • invalid segment identifiers;
  • immutable model invariants;
  • envelope ordering and nesting;
  • TA1 interchange acknowledgments;
  • optional ST03 and ST04 references;
  • missing envelope boundaries;
  • empty functional-group rejection;
  • control-number matching;
  • declared-count validation;
  • inspection summaries;
  • segment-frequency ordering;
  • complete synthetic interchange fixtures;
  • transaction-specific typed models and parsing;
  • public API exports;
  • runtime type-hint resolution;
  • wheel-safe type metadata.

The project requires 100% statement and branch coverage.

Committed fixtures are synthetic and generic. Private or production messages may be used locally for development validation but must not be committed or included in distributions.

Building and Releasing

Build the source distribution and wheel:

make build

Validate distribution metadata:

make check-dist

Inspect the wheel:

make wheel-contents

Install the wheel into a temporary clean environment:

make install-wheel

Run the complete release validation:

make release-check

The wheel should contain:

x12/__init__.py
x12/py.typed
x12/core/
x12/transactions/

It should not contain tests, repository scripts, private data, development caches, coverage files, local configuration, or application-specific code.

Releases are published through GitHub Actions using PyPI Trusted Publishing. See docs/RELEASING.md for the complete procedure.

Roadmap

Near-term improvements include:

  1. serialize validated interchanges back to X12 bytes;
  2. guarantee parse/serialize round trips;
  3. add explicit builders for segments, transactions, groups, and interchanges;
  4. calculate envelope counts and control values during construction;
  5. add structured validation reports and richer diagnostics;
  6. extend transaction support only when driven by real integrations;
  7. add length-aware BIN support;
  8. add streaming support where real workloads require it.

Transaction packages should grow incrementally from real X12 usage rather than attempting to model the entire standard in advance.

Extension Rules

A contribution to x12.core should remain:

  • generic;
  • structural;
  • deterministic;
  • framework independent;
  • transaction-set agnostic;
  • trading-partner agnostic.

A contribution to x12.transactions may interpret standard transaction, segment, qualifier, or loop meaning, but should remain reusable across unrelated applications.

Trading-partner-specific companion-guide rules and application-specific behavior belong in a higher integration layer unless they represent genuine standard X12 behavior.

Guiding Principle

x12.core understands how X12 is structured.

x12.transactions understands what supported X12 transactions mean.

Applications understand their trading partners and business rules.

License

MIT


Built and maintained by FIFOA Labs.

Metadata

Release files for ansi-x12 0.2.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 ansi-x12 0.2.0
File Size Uploaded
ansi_x12-0.2.0.tar.gz 23.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ansi-x12 0.2.0
File Interpreter ABI Platform
ansi_x12-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 55.9 kB

Release files / ansi_x12-0.2.0.tar.gz

Download URL ansi_x12-0.2.0.tar.gz
Size 23.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0f84d2c5689c19558909a971a84297cf7c99b433c66cbecab5df28cf166195cc
BLAKE2b-256 checksum
How to use checksums
43ee227c9ebfcada7692bc87a6993233db8151b7e3af94e10e37cf2750ac41f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 13, 2026.

Transparency log

Release files / ansi_x12-0.2.0-py3-none-any.whl

Download URL ansi_x12-0.2.0-py3-none-any.whl
Size 33.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
23cb6d1b5e4eb32ea3a7b0a5c7d90404e37b2d4d15c28640b1464a8a99324169
BLAKE2b-256 checksum
How to use checksums
84b173446f2ed44c7db7fa4f940fc73a29c65ff8f6c249cef448f573780bcdb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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