Avion & Avstar Ingestion Pipelines

Deterministic data movement between traffic management systems and broadcast automation platforms is the operational prerequisite for reliable commercial scheduling, log generation, and playout execution. The Avion and Avstar ecosystem forms the foundational infrastructure for terrestrial and hybrid broadcast environments, where schedule accuracy directly governs revenue realization and regulatory compliance. This guide establishes the architectural model, the canonical data taxonomy, and the production-grade ingestion workflows required to bridge traffic-system exports with automation scheduling engines. It is written for broadcast traffic managers, media operations engineers, ad-technology developers, and Python automation builders who maintain resilient, auditable scheduling pipelines under legacy-system constraints. The end-to-end path spans four cooperating workstreams — parsing Avion export formats at the ingestion boundary, schema validation with Pydantic for traffic data before records enter the queue, async batch processing for high-volume logs for throughput, and Avstar API authentication and rate limits at the scheduling-submission handoff.

Avion export → ingestion layer → Avstar automation system boundary The Avion traffic system export feeds a bounded ingestion layer that extracts, normalizes, validates, and transforms records; invalid records are quarantined and every state transition is written as a source_hash receipt to an append-only audit ledger. Validated payloads are submitted to the Avstar automation platform over its API, while billing and ad verification sit downstream, outside the ingestion boundary. INGESTION LAYER Avion traffic export Extract source_hash Normalize UTC times Validate schema Transform payload Quarantine dead-letter Append-only audit ledger immutable source_hash receipts Avstar automation API Billing & ad verification API archive

Figure — The ingestion layer is a sealed boundary between the Avion traffic export and the Avstar automation API: records are extracted, normalized, validated, and transformed, with rejects quarantined and every transition written as an immutable source_hash receipt. Billing and ad verification are deliberately downstream, outside the boundary.

Core Taxonomy & Data Model

Building an ingestion pipeline requires strict agreement on the underlying data structures before any code ships. Traffic exports describe the commercial inventory schedule as planned by sales and traffic teams; as-run logs capture the actualized playout events recorded after broadcast. The normalized entity hierarchy runs from the finest to the coarsest grain — spot → avail → order → campaign — and every ingestion record must be resolvable back up that chain for billing lineage and audit reconstruction.

  • Spot — a discrete airing of a single creative asset at a specific time, carrying a stable spot ID, duration, ISCI/Ad-ID, and clearance code. The spot is the atomic unit the automation system ultimately plays. Field-level structure follows the canonical spot schema and metadata.
  • Avail — an available inventory position inside a commercial break (the break structure), defined by daypart, program, and position priority. Mapping raw break slots to avails follows the conventions in avails mapping strategies for linear TV.
  • Order — the contractual line item that books spots against avails for an advertiser, holding flight dates, rate, and separation constraints.
  • Campaign — the advertiser-level grouping that aggregates orders for reporting, pacing, and revenue recognition.

The following typed table defines the minimum canonical fields the ingestion layer must produce for each spot before a record is eligible for scheduling submission. Types are expressed as the Python types the Pydantic validators enforce at the boundary.

Field Type Constraint Broadcast meaning
spot_id str non-empty, unique per broadcast day Stable primary key across traffic, automation, and as-run reconciliation
air_datetime datetime timezone-aware, normalized to UTC Scheduled air time; source local time resolved through DST transitions
duration_frames int > 0, matches SMPTE frame rate Exact spot length; frame-accurate to prevent break overrun
break_id str resolvable to an avail Commercial break the spot occupies
position int >= 1 Ordinal slot within the break (competitive separation depends on it)
isci str 8–20 chars, alphanumeric Creative/asset identifier handed to automation for media resolution
billing_code str matches canonical code set Normalized per standardizing billing codes across traffic systems
clearance_code str enumerated Legal/traffic clearance status gating whether the spot may air
source_hash str SHA-256 hex Cryptographic fingerprint of the originating export line for lineage

Spot identifiers, break structures, programmatic metadata payloads, and clearance codes form the atomic units of scheduling; every other artifact in the system derives from them. The ingestion layer sits strictly between traffic-system exports and automation-system APIs. It does not perform ad verification, dynamic ad insertion (DAI), billing reconciliation, or predictive yield optimization. Those responsibilities belong to downstream systems that consume validated, normalized traffic data. Fixing these boundaries prevents scope creep, isolates failure domains, and keeps execution paths deterministic for mission-critical broadcast operations.

End-to-End Workflow

A production-ready ingestion pipeline follows a linear, auditable progression. Each numbered phase must preserve referential integrity back to the source export, enforce strict type constraints, and emit immutable audit records suitable for regulatory review.

  1. Extraction — read the raw Avion export (flat file, CSV variant, or legacy XML), tokenize deterministically, and capture a source_hash of every line before any mutation. The structural conventions, header-parsing strategies, and edge-case handling live in parsing Avion export formats.
  2. Normalization — reconcile mid-day revisions, resolve conflicting spot priorities, sanitize control characters, and convert all timestamps to UTC so cross-market schedules cannot collide.
  3. Validation — check every normalized record against the canonical schema. Malformed fields, missing mandatory attributes, and out-of-range values are caught at the boundary by the Pydantic traffic-data validators; rejected records are quarantined, never silently dropped.
  4. Transformation — project validated records into the exact payload shape the automation API expects, attaching idempotency keys and versioned headers.
  5. Scheduling submission — push the transformed log to Avstar under managed authentication and rate limiting, then poll for explicit acknowledgment. Credential lifecycle, token caching, and throttling are covered in Avstar API authentication and rate limits.
  6. Archival — persist raw export, normalized payload, and submission receipt in append-only storage keyed by source_hash for audit reconstruction.

Real-time synchronization is rarely required for commercial traffic; scheduled delta syncs and full-day log pushes deliver optimal throughput with minimal API contention. For high-volume stations and multi-station aggregation, async batch processing for high-volume logs decouples I/O-bound file reads from CPU-bound validation using non-blocking execution.

End-to-end ingestion pipeline flow A vertical flow: a traffic system export is extracted, then normalized, then checked at a schema-validation decision. Valid records proceed to transformation, scheduling submission, and archival; invalid records branch off to a quarantine dead-letter store. Traffic system export Extraction Normalization Schema validation Quarantine / dead-letter Transformation Scheduling submission Archival valid invalid

Figure — End-to-end ingestion pipeline from traffic export through extraction, normalization, schema validation, and transformation to scheduling submission and archival, with failed records routed to a quarantine store.

Architectural Boundaries & Integration Patterns

The single most important design decision is how the ingestion layer talks to Avion and Avstar. Three integration surfaces exist, and mixing them without discipline is the most common source of production incidents.

API contract vs. direct database access. Where Avstar exposes a documented API, the ingestion layer must treat it as the sole write path and never reach into the automation database directly. Direct DB writes bypass the platform’s own validation, break its internal caches, and make vendor upgrades hazardous. Read-only replicas are acceptable for reconciliation, but the write contract stays at the API. When direct access to a traffic database is genuinely required — for example, bulk historical extraction — it must be gated by the controls in security boundaries for traffic database access, with least-privilege roles and audited connections.

Legacy EDI/SOAP bridges. Many Avion deployments still emit fixed-width dumps or expose SOAP endpoints with proprietary XML dialects. Rather than let those dialects leak into the core, wrap each legacy source in a thin adapter that converts it to the canonical schema at the edge. The adapter owns all vendor-specific quirks — delimiter conventions, escape characters, non-standard line endings — so the rest of the pipeline only ever sees normalized records.

Message-broker decoupling. In multi-station or high-availability topologies, insert a durable message broker (RabbitMQ or Kafka) between extraction and validation. Publishing raw-but-fingerprinted records to a topic lets validation and submission workers scale independently, absorb export bursts, and replay a broadcast day deterministically from the log. The broker also provides the natural home for the dead-letter queue that quarantined records land in. This event-driven decoupling is what makes async batch processing for high-volume logs safe under load: back-pressure is handled by the broker instead of by unbounded in-process buffers.

Adapter-and-broker integration pattern Two legacy Avion sources — a fixed-width dump and a SOAP/XML endpoint — each sit behind a per-source adapter that converts them to the canonical schema at the edge. The adapters publish raw-but-fingerprinted records to a message broker topic (RabbitMQ or Kafka). Validation and submission worker pools consume the topic independently; the submission pool is the sole API write path into Avstar, and a dead-letter queue branches off the broker for quarantined records. Fixed-width dump SOAP / XML endpoint Avion legacy sources Adapter → canonical schema Adapter → canonical schema Message broker RabbitMQ / Kafka fingerprinted topic Dead-letter queue operator review Validation worker pool Submission worker pool Avstar API write path publish API only

Figure — Each legacy Avion source is wrapped in a thin per-source adapter that emits canonical records to a durable broker topic. Validation and submission worker pools scale independently off that topic, the submission pool is the only path that writes to the Avstar API, and quarantined records land in a dead-letter queue.

Python Automation Stack

The reference stack favors small, well-typed components over a monolithic framework. Every code block below uses strict type hints and emits a log line in the traffic-ops pattern timestamp | level | module | message, where the message carries the spot_id so incidents can be traced to a single airing.

  • Pydantic — declarative models enforce the canonical schema at the ingestion boundary and produce structured validation errors for quarantine payloads.
  • asyncio — non-blocking concurrency for the I/O-bound legs (file reads, broker publishes, API submission) without threading overhead.
  • SQLAlchemy / TimescaleDB — the append-only audit ledger and as-run store; TimescaleDB’s hypertables keep time-indexed reconciliation queries fast.
  • Idempotency — every submission carries a deterministic idempotency key derived from source_hash, so a retried push can never duplicate a commercial break.
  • Structured logging — JSON-formatted records with a stable spot_id field feed centralized aggregation, satisfying the visibility that SOC 2 and ISO 27001 audits require.

The following snippet shows the idempotent transform-and-submit core: a validated record is fingerprinted into an idempotency key, and the submission is logged with the traffic-ops formatter.

python
import hashlib
import logging
from datetime import datetime, timezone

from pydantic import BaseModel, Field

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
)
logger = logging.getLogger("avstar.submit")


class ValidatedSpot(BaseModel):
    """Canonical spot record accepted for scheduling submission."""

    spot_id: str = Field(min_length=1)
    air_datetime: datetime           # timezone-aware, normalized to UTC upstream
    duration_frames: int = Field(gt=0)
    break_id: str
    isci: str = Field(min_length=8, max_length=20)
    billing_code: str
    source_hash: str                 # SHA-256 of the originating export line


def idempotency_key(spot: ValidatedSpot) -> str:
    """Deterministic key so a retried push cannot duplicate a break."""
    seed = f"{spot.spot_id}:{spot.air_datetime.isoformat()}:{spot.source_hash}"
    return hashlib.sha256(seed.encode("utf-8")).hexdigest()


def submit(spot: ValidatedSpot) -> str:
    """Transform to the Avstar payload and submit under an idempotency key."""
    if spot.air_datetime.tzinfo is None:
        raise ValueError(f"air_datetime for spot {spot.spot_id} must be timezone-aware")

    key: str = idempotency_key(spot)
    payload: dict[str, object] = {
        "id": spot.spot_id,
        "air": spot.air_datetime.astimezone(timezone.utc).isoformat(),
        "frames": spot.duration_frames,
        "break": spot.break_id,
        "asset": spot.isci,
        "billing": spot.billing_code,
        "idempotency_key": key,
    }
    # ... POST payload to the Avstar API here, honoring rate limits ...
    logger.info("submitted spot_id=%s key=%s break=%s", spot.spot_id, key[:12], spot.break_id)
    return key

Normalizing timezones to UTC before this stage, and enforcing frame-accurate durations, are what keep the automation platform from rejecting an entire log for one malformed record.

Compliance & Regulatory Constraints

Broadcast operations run under strict regulatory frameworks that mandate accurate commercial logging, transparent schedule execution, and verifiable audit trails. The ingestion pipeline is where much of that evidence is created, so compliance cannot be an afterthought bolted on downstream.

  • FCC political file. Political and issue-advertising spots must be logged with the metadata that populates the public inspection file — advertiser, purchaser, rate, and airing schedule. The ingestion layer must preserve these attributes intact and refuse to normalize them away; billing-code handling for political inventory follows standardizing billing codes across traffic systems.
  • SCTE-104 / SCTE-35. Splice metadata that instructs downstream insertion and blackout must survive the ingestion round-trip. Where an Avion export carries splice descriptors, the adapter maps them onto the canonical record so the automation platform can emit the correct SCTE-35 messages at playout.
  • EAS halt protocols. Emergency Alert System activations preempt scheduled inventory. Ingestion must tolerate preemption and make-good deltas arriving as appended records rather than full log replacements, and never overwrite an as-run that reflects an EAS halt.
  • Audit-log immutability. Every state transition — raw export received, validation outcome, submission acknowledged — is persisted to append-only storage with a cryptographic hash of the payload. Immutable, hash-chained receipts are what let an operator prove, months later, that the log that aired matched the log that was booked.

Cryptographic hashes of raw exports, normalized payloads, and submission receipts, combined with structured JSON logs in centralized aggregation, provide the traceability that FCC commercial-operations rules and internal audit standards demand.

Failure Modes & Resilience

Ingestion scripts in broadcast environments must survive transient network failures, malformed payloads, and system timeouts without manual intervention. The resilience model is built from a few well-understood patterns.

  • Circuit breakers. When the Avstar API begins returning errors or timing out, a circuit breaker opens after a failure threshold and halts submission rather than hammering a degraded endpoint. After a cool-down it admits probe requests and closes on the first success. Detailed session-timeout handling is covered in handling Avstar session timeouts in Python.
  • Make-good fallback. Preempted or rejected spots must be routed for rebooking rather than lost. The ingestion layer flags the displaced record, preserves its contractual lineage, and hands it to downstream make-good routing so advertiser obligations are still met.
  • Network-partition handling. With a message broker in place, a partition between workers and Avstar degrades gracefully: records accumulate durably in the topic and drain when connectivity returns, instead of being dropped. Recoverable failures trigger exponential backoff with jitter; fatal errors route to the dead-letter queue for operator review.
  • Duplicate-placement prevention. Idempotent submission — the deterministic key derived from source_hash — guarantees that a retried or replayed push never double-books a break. This is the single most important safeguard against corrupting a schedule during recovery.

Large daily logs and multi-station workloads strain memory, so streaming parsers, generator-based transformations, and chunked processing keep worker footprints stable enough to run on constrained edge servers without triggering OOM conditions or degrading playout responsiveness. Validation failures always produce a structured error payload — original line, field path, constraint violation, and correlation ID — preserving lineage and accelerating operator troubleshooting.