Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

jentic-openapi-parser

A Python library for parsing OpenAPI documents using pluggable parser backends. This package is part of the Jentic OpenAPI Tools ecosystem and provides a flexible, extensible architecture for OpenAPI document parsing with support for multiple YAML/JSON parsing libraries.

Features

  • Pluggable Backend Architecture: Support for multiple parsing strategies via entry points
  • Multiple Input Formats: Parse OpenAPI documents from file URIs or text strings (JSON/YAML)
  • Multiple Parser Backends: Choose from PyYAML, ruamel.yaml (safe/roundtrip/AST modes), or typed datamodels
  • Low-Level Datamodels: Parse directly to typed OpenAPI30/OpenAPI31 objects with source tracking
  • Enhanced JSON Serialization: Built-in support for datetime, UUID, Path, Decimal, Enum, and attrs classes
  • Type Safety: Full type hints with overloaded methods for precise return types
  • Extensible Design: Easy integration of third-party parser backends

Installation

pip install jentic-openapi-parser

Prerequisites:

  • Python 3.11+

Quick Start

Basic Parsing

from jentic.apitools.openapi.parser.core import OpenAPIParser

# Create parser with default backend (pyyaml)
parser = OpenAPIParser()

# Parse from file URI
doc = parser.parse("file:///path/to/openapi.yaml")
print(doc["info"]["title"])

# Parse from JSON string
json_doc = '{"openapi":"3.1.2","info":{"title":"My API","version":"1.0.0"}}'
doc = parser.parse(json_doc)

# Parse from YAML string
yaml_doc = """
openapi: 3.1.2
info:
  title: My API
  version: 1.0.0
"""
doc = parser.parse(yaml_doc)

Parse with Type Conversion

from ruamel.yaml import CommentedMap

# Parse with specific return type
parser = OpenAPIParser("ruamel-roundtrip")
doc = parser.parse(yaml_doc, return_type=CommentedMap)

# Parse with strict type checking
doc = parser.parse(yaml_doc, return_type=CommentedMap, strict=True)

Using Different Backends

# Use PyYAML backend (default)
parser = OpenAPIParser("pyyaml")
doc = parser.parse("file:///path/to/openapi.yaml")

# Use ruamel.yaml backend (safe mode)
parser = OpenAPIParser("ruamel-safe")
doc = parser.parse("file:///path/to/openapi.yaml")

# Use ruamel.yaml roundtrip mode (preserves comments and formatting info)
parser = OpenAPIParser("ruamel-roundtrip")
doc = parser.parse("file:///path/to/openapi.yaml", return_type=CommentedMap)
# Access line/column information
print(doc.lc.line, doc.lc.col)

# Use ruamel.yaml AST mode (returns YAML nodes with source tracking)
from jentic.apitools.openapi.parser.backends.ruamel_ast import MappingNode
parser = OpenAPIParser("ruamel-ast")
node = parser.parse("file:///path/to/openapi.yaml", return_type=MappingNode)
# Access precise line/column for any node
for key_node, value_node in node.value:
    print(f"{key_node.value} at line {key_node.start_mark.line}")

Configuration Options

Backend Selection

# Use backend by name
parser = OpenAPIParser("pyyaml")

# Pass backend instance directly
from jentic.apitools.openapi.parser.backends.pyyaml import PyYAMLParserBackend
backend = PyYAMLParserBackend()
parser = OpenAPIParser(backend=backend)

# Pass backend class
parser = OpenAPIParser(backend=PyYAMLParserBackend)

Custom Configuration

import logging

# Configure with custom logger and timeouts
logger = logging.getLogger(__name__)
parser = OpenAPIParser(
    backend="pyyaml",
    logger=logger,
    conn_timeout=10,  # Connection timeout in seconds
    read_timeout=30   # Read timeout in seconds
)

Working with Return Types

The parser supports flexible return type handling:

from ruamel.yaml import CommentedMap

parser = OpenAPIParser("ruamel-roundtrip")

# Without return_type: Returns plain dict
doc = parser.parse(yaml_doc)
assert isinstance(doc, dict)

# With return_type: Returns specified type
doc = parser.parse(yaml_doc, return_type=CommentedMap)
assert isinstance(doc, CommentedMap)

# With strict=True: Raises error if type doesn't match
try:
    doc = parser.parse(yaml_doc, return_type=list, strict=True)
except TypeConversionError:
    print("Type mismatch!")

API Reference

OpenAPIParser

class OpenAPIParser:
    def __init__(
        self,
        backend: str | BaseParserBackend | Type[BaseParserBackend] | None = None,
        *,
        logger: logging.Logger | None = None,
        conn_timeout: int = 5,
        read_timeout: int = 10,
    ) -> None

Parameters:

  • backend: Parser backend to use. Can be:
    • str: Name of a backend registered via entry points (e.g., "pyyaml", "ruamel-safe", "ruamel-roundtrip", "ruamel-ast", "datamodel-low")
    • BaseParserBackend: Instance of a parser backend
    • Type[BaseParserBackend]: Class of a parser backend (will be instantiated)
    • Defaults to "pyyaml" if None
  • logger: Custom logger instance (optional)
  • conn_timeout: Connection timeout in seconds for URI loading
  • read_timeout: Read timeout in seconds for URI loading

Methods:

  • parse(document: str) -> dict[str, Any]

    • Parse without type conversion, returns plain dict
  • parse(document: str, *, return_type: type[T], strict: bool = False) -> T

    • Parse with optional type conversion
    • document: File URI or text string (JSON/YAML)
    • return_type: Expected return type (e.g., dict, CommentedMap)
    • strict: If True, raises TypeConversionError if result doesn't match return_type
    • Returns: Parsed document
  • load_uri(uri: str) -> str

    • Load content from a URI (HTTP(S), file://, or local file path)
  • list_backends() -> list[str]

    • Static method to list all available parser backends

JSON Serialization

The parser includes enhanced JSON serialization utilities for working with OpenAPI documents:

from jentic.apitools.openapi.parser.core import json_dumps

# Serialize with special type support
from datetime import datetime
from pathlib import Path
from uuid import UUID

data = {
    "timestamp": datetime(2025, 10, 1, 12, 0, 0),
    "id": UUID("550e8400-e29b-41d4-a716-446655440000"),
    "path": Path("/var/log/app.log")
}

json_str = json_dumps(data, indent=2)
# Output:
# {
#   "id": "550e8400-e29b-41d4-a716-446655440000",
#   "path": "/var/log/app.log",
#   "timestamp": "2025-10-01T12:00:00"
# }

Supported Types:

  • datetime / date - Serialized to ISO 8601 format
  • UUID - Converted to string
  • Path - Converted to string
  • Decimal - Converted to float
  • Enum - Serialized using enum value
  • attrs classes - Converted to dictionaries

Exceptions

from jentic.apitools.openapi.parser.core.exceptions import (
    OpenAPIParserError,        # Base exception
    DocumentParseError,        # Parsing failed
    DocumentLoadError,         # URI loading failed
    InvalidBackendError,       # Backend initialization failed
    BackendNotFoundError,      # Backend not found
    TypeConversionError,       # Type conversion failed
)

Available Backends

pyyaml (Default)

Standard PyYAML-based parser. Fast and reliable for basic parsing needs.

Accepts: text (JSON/YAML strings)

parser = OpenAPIParser("pyyaml")
doc = parser.parse(content)

ruamel-safe

ruamel.yaml-based parser with safe loading. Provides better YAML 1.2 support than PyYAML.

Accepts: text (JSON/YAML strings), uri (file paths/URLs)

parser = OpenAPIParser("ruamel-safe")
doc = parser.parse(content)

ruamel-roundtrip

ruamel.yaml roundtrip mode that preserves comments, formatting, and provides line/column information.

Accepts: text (JSON/YAML strings), uri (file paths/URLs)

from ruamel.yaml import CommentedMap

parser = OpenAPIParser("ruamel-roundtrip")
doc = parser.parse(content, return_type=CommentedMap)

# Access line/column information
print(f"Line: {doc.lc.line}, Column: {doc.lc.col}")

ruamel-ast

ruamel.yaml AST mode that returns YAML nodes with complete source location tracking. Ideal for building low-level data models with precise error reporting.

Accepts: text (JSON/YAML strings), uri (file paths/URLs)

Returns: yaml.MappingNode (YAML AST) instead of dictionaries

from jentic.apitools.openapi.parser.backends.ruamel_ast import MappingNode

parser = OpenAPIParser("ruamel-ast")
node = parser.parse(content, return_type=MappingNode)

# Access YAML nodes with source information
assert isinstance(node, MappingNode)

# Get precise line/column information for any node
for key_node, value_node in node.value:
    print(f"Key: {key_node.value}")
    print(f"  Line: {key_node.start_mark.line}, Column: {key_node.start_mark.column}")

# Perfect for building low-level datamodels with source tracking
# Works seamlessly with jentic-openapi-datamodels

Note: You can also import directly from ruamel.yaml if preferred:

from ruamel.yaml import MappingNode  # Alternative import

Use Cases:

  • Building low-level data models that preserve source locations
  • Implementing precise error reporting with line/column numbers
  • AST-based transformations and analysis
  • Integration with validation tools that need exact source positions

datamodel-low

Low-level OpenAPI data model parser that automatically detects the OpenAPI version (3.0.x or 3.1.x) and returns the appropriate typed datamodel with complete source tracking.

Accepts: text (JSON/YAML strings), uri (file paths/URLs)

Returns: OpenAPI30 or OpenAPI31 data model (from jentic-openapi-datamodels)

from jentic.apitools.openapi.parser.core import OpenAPIParser
from jentic.apitools.openapi.parser.backends.datamodel_low import DataModelLow
from jentic.apitools.openapi.datamodels.low.v30.openapi import OpenAPI30
from jentic.apitools.openapi.datamodels.low.v31.openapi import OpenAPI31


parser = OpenAPIParser("datamodel-low")

# Parse OpenAPI 3.0.x document
doc = parser.parse("file:///path/to/openapi-3.0.yaml", return_type=OpenAPI30)
assert isinstance(doc, OpenAPI30)
print(doc.openapi.value)  # "3.0.4"
print(doc.info.value.title.value)  # Access with source tracking

# Parse OpenAPI 3.1.x document
doc = parser.parse("file:///path/to/openapi-3.1.yaml", return_type=OpenAPI31)
assert isinstance(doc, OpenAPI31)
print(doc.openapi.value)  # "3.1.2"

# Access fields with source information
print(f"Title at line {doc.info.key_node.start_mark.line}")

doc = parser.parse("file:///path/to/openapi.yaml", return_type=DataModelLow)
# Type checker sees 'Any', runtime type will be one of: OpenAPI30, OpenAPI31, or ValueSource
print(type(doc).__name__)  # "OpenAPI30" or "OpenAPI31"

# Optional: Enable strict runtime validation
doc = parser.parse("file:///path/to/openapi.yaml", return_type=DataModelLow, strict=True)
# Raises TypeConversionError if result is not one of the union types

Features:

  • Automatic Version Detection: Parses openapi field and routes to correct builder
  • Typed Datamodels: Returns strongly-typed OpenAPI30 or OpenAPI31 objects
  • Complete Source Tracking: Every field preserves YAML node information
  • Error Handling: Clear errors for unsupported versions (2.0, 3.2+)

Supported Versions:

  • OpenAPI 3.0.x → returns OpenAPI30
  • OpenAPI 3.1.x → returns OpenAPI31

Unsupported (raises ValueError):

  • OpenAPI 2.0 (Swagger)
  • OpenAPI 3.2.x and above

Use Cases:

  • Type-safe OpenAPI document manipulation
  • Building validation tools with precise error messages
  • Code generation from OpenAPI specifications
  • AST transformations with version-aware logic

Testing

Run the test suite:

uv run --package jentic-openapi-parser pytest packages/jentic-openapi-parser -v

Metadata

Release files for jentic-openapi-parser 1.0.0a57

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

Source distribution (sdist)

Source distribution for jentic-openapi-parser 1.0.0a57
File Size Uploaded
jentic_openapi_parser-1.0.0a57.tar.gz 14.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jentic-openapi-parser 1.0.0a57
File Interpreter ABI Platform
jentic_openapi_parser-1.0.0a57-py3-none-any.whl Python 3 none any Details

Total release size: 37.6 kB

Release files / jentic_openapi_parser-1.0.0a57.tar.gz

Download URL jentic_openapi_parser-1.0.0a57.tar.gz
Size 14.7 kB
Tags Source
SHA-256 checksum
How to use checksums
abad02f2da33b1c0cbbad8254f577762bfe252829042de52da01b0dd44b6f70f
BLAKE2b-256 checksum
How to use checksums
918d5819e8473268c6d9926c91da52c021e3dbeef338740e72965a0b64c61d71
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 Jun 10, 2026.

Transparency log

Release files / jentic_openapi_parser-1.0.0a57-py3-none-any.whl

Download URL jentic_openapi_parser-1.0.0a57-py3-none-any.whl
Size 22.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1a2faf5af88daa79b00d59d6ae7d3e6083c72309dd609aacdd182a0c4618aa9e
BLAKE2b-256 checksum
How to use checksums
9f0faa22a737e22b9b8086c24264ddcca7387a6f3f7d6bb3be8c1b9e02992b6c
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 Jun 10, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0a57 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