2017-09-21 11:51:37 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""OpenAPI core specs module"""
|
|
|
|
import logging
|
2017-09-22 08:54:37 +00:00
|
|
|
from functools import partialmethod, lru_cache
|
2017-09-21 11:51:37 +00:00
|
|
|
|
|
|
|
from openapi_spec_validator import openapi_v3_spec_validator
|
|
|
|
|
2017-09-22 08:14:07 +00:00
|
|
|
from openapi_core.components import ComponentsFactory
|
2017-10-19 09:34:20 +00:00
|
|
|
from openapi_core.exceptions import InvalidOperationError
|
2017-09-22 08:14:07 +00:00
|
|
|
from openapi_core.infos import InfoFactory
|
2017-09-21 11:51:37 +00:00
|
|
|
from openapi_core.paths import PathsGenerator
|
2017-09-22 08:54:37 +00:00
|
|
|
from openapi_core.schemas import SchemaRegistry
|
2017-09-25 11:22:55 +00:00
|
|
|
from openapi_core.servers import ServersGenerator
|
2017-09-21 11:51:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class Spec(object):
|
|
|
|
"""Represents an OpenAPI Specification for a service."""
|
|
|
|
|
2017-09-22 08:14:07 +00:00
|
|
|
def __init__(self, info, paths, servers=None, components=None):
|
|
|
|
self.info = info
|
|
|
|
self.paths = paths and dict(paths)
|
2017-09-21 11:51:37 +00:00
|
|
|
self.servers = servers or []
|
2017-09-22 08:14:07 +00:00
|
|
|
self.components = components
|
2017-09-21 11:51:37 +00:00
|
|
|
|
|
|
|
def __getitem__(self, path_name):
|
|
|
|
return self.paths[path_name]
|
|
|
|
|
2017-09-25 11:22:55 +00:00
|
|
|
@property
|
|
|
|
def default_url(self):
|
|
|
|
return self.servers[0].default_url
|
|
|
|
|
2017-09-21 11:51:37 +00:00
|
|
|
def get_server_url(self, index=0):
|
2017-09-25 11:22:55 +00:00
|
|
|
return self.servers[index].default_url
|
2017-09-21 11:51:37 +00:00
|
|
|
|
|
|
|
def get_operation(self, path_pattern, http_method):
|
2017-10-19 09:34:20 +00:00
|
|
|
try:
|
|
|
|
return self.paths[path_pattern].operations[http_method]
|
|
|
|
except KeyError:
|
|
|
|
raise InvalidOperationError(
|
|
|
|
"Unknown operation path {0} with method {1}".format(
|
|
|
|
path_pattern, http_method))
|
2017-09-21 11:51:37 +00:00
|
|
|
|
2017-09-22 08:14:07 +00:00
|
|
|
def get_schema(self, name):
|
|
|
|
return self.components.schemas[name]
|
|
|
|
|
2017-09-21 11:51:37 +00:00
|
|
|
# operations shortcuts
|
|
|
|
|
|
|
|
get = partialmethod(get_operation, http_method='get')
|
|
|
|
put = partialmethod(get_operation, http_method='put')
|
|
|
|
post = partialmethod(get_operation, http_method='post')
|
|
|
|
delete = partialmethod(get_operation, http_method='delete')
|
|
|
|
options = partialmethod(get_operation, http_method='options')
|
|
|
|
head = partialmethod(get_operation, http_method='head')
|
|
|
|
patch = partialmethod(get_operation, http_method='patch')
|
|
|
|
|
|
|
|
|
|
|
|
class SpecFactory(object):
|
|
|
|
|
|
|
|
def __init__(self, dereferencer, config=None):
|
|
|
|
self.dereferencer = dereferencer
|
|
|
|
self.config = config or {}
|
|
|
|
|
|
|
|
def create(self, spec_dict, spec_url=''):
|
|
|
|
if self.config.get('validate_spec', True):
|
|
|
|
openapi_v3_spec_validator.validate(spec_dict, spec_url=spec_url)
|
|
|
|
|
|
|
|
spec_dict_deref = self.dereferencer.dereference(spec_dict)
|
|
|
|
|
2017-09-22 08:14:07 +00:00
|
|
|
info_spec = spec_dict_deref.get('info', [])
|
2017-09-25 11:22:55 +00:00
|
|
|
servers_spec = spec_dict_deref.get('servers', [])
|
2017-09-21 11:51:37 +00:00
|
|
|
paths = spec_dict_deref.get('paths', [])
|
2017-09-22 08:14:07 +00:00
|
|
|
components_spec = spec_dict_deref.get('components', [])
|
|
|
|
|
2017-09-22 08:54:37 +00:00
|
|
|
info = self.info_factory.create(info_spec)
|
2017-09-25 11:22:55 +00:00
|
|
|
servers = self.servers_generator.generate(servers_spec)
|
2017-09-22 08:54:37 +00:00
|
|
|
paths = self.paths_generator.generate(paths)
|
|
|
|
components = self.components_factory.create(components_spec)
|
2017-09-25 11:22:55 +00:00
|
|
|
spec = Spec(
|
|
|
|
info, list(paths), servers=list(servers), components=components)
|
2017-09-22 08:14:07 +00:00
|
|
|
return spec
|
|
|
|
|
2017-09-22 08:54:37 +00:00
|
|
|
@property
|
|
|
|
@lru_cache()
|
|
|
|
def schemas_registry(self):
|
|
|
|
return SchemaRegistry(self.dereferencer)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lru_cache()
|
|
|
|
def info_factory(self):
|
|
|
|
return InfoFactory(self.dereferencer)
|
|
|
|
|
2017-09-25 11:22:55 +00:00
|
|
|
@property
|
|
|
|
@lru_cache()
|
|
|
|
def servers_generator(self):
|
|
|
|
return ServersGenerator(self.dereferencer)
|
|
|
|
|
2017-09-22 08:54:37 +00:00
|
|
|
@property
|
|
|
|
@lru_cache()
|
|
|
|
def paths_generator(self):
|
|
|
|
return PathsGenerator(self.dereferencer, self.schemas_registry)
|
|
|
|
|
|
|
|
@property
|
|
|
|
@lru_cache()
|
|
|
|
def components_factory(self):
|
|
|
|
return ComponentsFactory(self.dereferencer, self.schemas_registry)
|