Source code for poast.openapi3.spec.model.baseobj

"""
Base class for OpenApi 3.0 "Objects"

For more info, see:
 - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#format
"""

from abc import abstractmethod
from .entity import OpenApiEntity


[docs]class OpenApiBaseObject(OpenApiEntity, dict): """ Base class for OpenAPI specification objects. """
[docs] def __init__(self, data, doc_path='#'): self._defaults = {} OpenApiEntity.__init__(self, data, doc_path) return
[docs] def __missing__(self, key): """ If a value is missing from the spec, return the default, as defined by the standard, if possible. """ return self._defaults.get(key, None)
@classmethod @abstractmethod def _obj_spec(cls): """ Subclasses MUST override to provide a list of specifications for the fields in the object. """ pass def _field_names(self): for spec in self._obj_spec(): for field_name in spec: yield field_name def _init_data(self, data): if data is None: data = {} self.extensions = {} self._init_fields(data) self._init_defaults(self._defaults) self._init_extensions(data) self._post_init() return def _init_fields(self, data): """ Initialize each of the fields for this object from the input data. """ # Initialize all the fields to None first, for consistency: for field_name in self._field_names(): self[field_name] = None for field in self._obj_spec(): field_name, field_val = field.parse(self, data) if not field_name: continue self[field_name] = field_val return def _init_extensions(self, data): """ Find and store OpenAPI extension attributes. """ for k, v in data.items(): # Skip over non-extension items if not k.startswith("x-"): continue self.extensions[k] = v def _init_defaults(self, field_defaults): pass def _post_init(self): pass def _validate(self): pass
[docs] def accept(self, visitor): """ Depth first traversal, via visitor. Args: visitor (func): a function that takes a single OpenApiEntity as an argument. """ if not callable(visitor): raise ValueError("OpenApiObject visitor must be callable") for field_name in self._field_names(): field_val = self.get(field_name, None) if field_val is not None: field_val.accept(visitor) visitor(self) return
[docs] def validate(self): self._validate() for field_name in self._field_names(): field_val = self.get(field_name, None) if field_val: field_val.validate() return self
[docs] def value(self, show_unset=False): """ Gnarly (in the bad way) convenience/debug function used to return the document as a python dictionary for pprinting and dev validation. """ py_data = {} for field_name in self._field_names(): field_val = self.get(field_name, None) if field_val is not None: py_val = field_val.value() else: py_val = None if py_val or show_unset: py_data[field_name] = py_val return py_data