swagger_spec_validator
A Python library that validates Swagger 1.2 and Swagger 2.0 API specifications against their official schemas.
Repository Health
Technical Analysis
swagger-spec-validator is a focused Python library for checking that a Swagger/OpenAPI spec is actually correct before you rely on it. It validates both the legacy Swagger 1.2 resource-listing format and the widely-used Swagger 2.0 format, combining strict JSON Schema validation with hand-written semantic checks that catch mistakes a schema alone can’t express — duplicate operation IDs, undocumented path parameters, malformed discriminators, and default values that don’t match their declared type.
Built and maintained by Yelp, it grew out of the need to validate specs consumed by their internal Swagger tooling and has since become a standard building block for other Python Swagger/OpenAPI libraries (bravado, pyramid-swagger, and similar projects lean on it under the hood). It exposes a small, stable public API — validate_spec_url, validate_spec, validate_json — and wraps every failure in a single SwaggerValidationError so callers don’t need to catch a grab-bag of exception types.
Because it works directly on Python dicts (loaded from JSON or YAML), it fits cleanly into CI pipelines, pre-commit hooks, or one-off scripts that need to fail fast on a broken spec, without needing a running server or an external validation service.
What You Get
- Dual-version support - validates both Swagger 1.2 (resource listings/API declarations) and Swagger 2.0 specs, auto-detecting which version a spec uses.
- Bundled schemas - ships the official Swagger 1.2 and 2.0 JSON Schemas as package data, so no network access is required to validate against the spec itself.
- Semantic checks beyond JSON Schema - flags duplicate
operationIds, undocumented path parameters, invalid discriminators, and default values that don’t match their declared type. - Single exception type - every failure surfaces as
SwaggerValidationError, so callers don’t need to handle multiple underlying exception classes. - Reference ($ref) validation - detects
$refsiblings that get silently discarded and warns about$ref: nullvalues that usually indicate an authoring mistake. - Typed public API - ships a
py.typedmarker and full type hints, so it integrates cleanly with mypy-checked codebases.
Common Use Cases
- CI spec validation - run
validate_spec_urlorvalidate_specin a CI job to fail the build if an API’s swagger.json/yaml is malformed before it reaches consumers. - Pre-commit hooks - validate a checked-in spec file on every commit so authoring mistakes are caught locally, not in review.
- Foundation for higher-level tooling - libraries like bravado and pyramid-swagger use it internally to validate specs before generating clients or wiring routes.
- One-off spec debugging - point
validate_spec_urlat a live/swagger.jsonendpoint to quickly diagnose why downstream codegen or client tooling is failing.
Under The Hood
Architecture
The package exposes a small public surface (validate_spec_url, SwaggerValidationError) from __init__.py, backed by util.py’s get_validator, which inspects a spec dict’s swaggerVersion/swagger keys and dispatches to either the validator12 or validator20 module — a simple version-based strategy pattern. validator20.py does the real work: it first validates the raw spec against the bundled JSON Schema using a custom RefResolver-aware dereffing validator built on jsonschema’s Draft4Validator, then walks paths, definitions, and parameters performing semantic checks the schema can’t express (duplicate operation IDs, required path params, discriminator correctness). A separate validate_references pass walks the fully dereferenced tree specifically to warn about $ref siblings and null refs. Nearly every validate_* function takes a deref callable as an argument rather than mutating parsed structures, so the core deref/RefResolver abstraction is the load-bearing piece — changing it would ripple through the whole validator module.
Tech Stack
A pure-Python library (3.8+) with a deliberately small dependency set: jsonschema for schema validation, pyyaml (preferring the C-accelerated CSafeLoader with a pure-Python fallback) for parsing YAML/JSON specs, typing-extensions for ParamSpec, and importlib-resources for bundling the schema files as package data. No web framework is involved — read_url uses urllib directly for both local file:// and remote http(s):// spec sources. Packaging uses classic setuptools/setup.py with metadata centralized in __about__.py, and a py.typed marker signals first-class typing support to consumers.
Code Quality
The test suite mirrors the module layout (tests/validator12/, tests/validator20/, tests/util/) with extensive fixture data covering edge cases — nested and cross-file $refs, polymorphic specs, invalid external references, duplicate parameters — rather than just happy-path coverage. mypy.ini and a shipped py.typed marker back static type checking across the codebase, which consistently uses modern type hints via from __future__ import annotations. Error handling is centralized through a wrap_exception decorator applied to every public entry point, so any underlying failure surfaces as a single SwaggerValidationError with the original traceback preserved. Both GitHub Actions and AppVeyor CI run the suite, and pre-commit hooks enforce formatting.
What Makes It Unique
Rather than treating JSON Schema validation as sufficient, the library layers hand-written semantic checks on top: duplicate operationId detection across an entire spec, path-parameter/URL consistency checks, discriminator property and type validation, and default-value type checking against declared parameter/property schemas. These target real authoring mistakes that pure schema validation misses. The trade-off is a narrow, deliberate scope — it only supports Swagger 1.2 and 2.0, with no OpenAPI 3.x support — which keeps the implementation focused rather than attempting to be a general-purpose spec validator.