From ca413004d350b710df937139388a9aa85235053e Mon Sep 17 00:00:00 2001 From: Artur Maciag Date: Fri, 22 Sep 2017 09:54:37 +0100 Subject: [PATCH] schemas registry --- openapi_core/components.py | 13 +++++++++---- openapi_core/media_types.py | 12 +++--------- openapi_core/operations.py | 21 ++++++++++++++------- openapi_core/parameters.py | 12 +++--------- openapi_core/paths.py | 13 +++++++++---- openapi_core/request_bodies.py | 13 +++++++++---- openapi_core/schemas.py | 25 ++++++++++--------------- openapi_core/specs.py | 32 ++++++++++++++++++++++---------- 8 files changed, 79 insertions(+), 62 deletions(-) diff --git a/openapi_core/components.py b/openapi_core/components.py index 54a5311..978aef2 100644 --- a/openapi_core/components.py +++ b/openapi_core/components.py @@ -1,3 +1,5 @@ +from functools import lru_cache + from openapi_core.schemas import SchemasGenerator @@ -15,8 +17,9 @@ class Components(object): class ComponentsFactory(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def create(self, components_spec): components_deref = self.dereferencer.dereference(components_spec) @@ -26,7 +29,7 @@ class ComponentsFactory(object): parameters_spec = components_deref.get('parameters', []) request_bodies_spec = components_deref.get('request_bodies', []) - schemas = self._generate_schemas(schemas_spec) + schemas = self.schemas_generator.generate(schemas_spec) responses = self._generate_response(responses_spec) parameters = self._generate_parameters(parameters_spec) request_bodies = self._generate_request_bodies(request_bodies_spec) @@ -35,8 +38,10 @@ class ComponentsFactory(object): request_bodies=request_bodies, ) - def _generate_schemas(self, schemas_spec): - return SchemasGenerator(self.dereferencer).generate(schemas_spec) + @property + @lru_cache() + def schemas_generator(self): + return SchemasGenerator(self.dereferencer, self.schemas_registry) def _generate_response(self, responses_spec): return responses_spec diff --git a/openapi_core/media_types.py b/openapi_core/media_types.py index f4c8295..cb0fd85 100644 --- a/openapi_core/media_types.py +++ b/openapi_core/media_types.py @@ -1,8 +1,6 @@ """OpenAPI core mediaTypes module""" from six import iteritems -from openapi_core.schemas import SchemaRegistry - class MediaType(object): """Represents an OpenAPI MediaType.""" @@ -20,8 +18,9 @@ class MediaType(object): class MediaTypeGenerator(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def generate(self, content): for content_type, media_type in iteritems(content): @@ -29,11 +28,6 @@ class MediaTypeGenerator(object): schema = None if schema_spec: - schema = self._create_schema(schema_spec) + schema, _ = self.schemas_registry.get_or_create(schema_spec) yield content_type, MediaType(content_type, schema) - - def _create_schema(self, schema_spec): - schema, _ = SchemaRegistry(self.dereferencer).get_or_create( - schema_spec) - return schema diff --git a/openapi_core/operations.py b/openapi_core/operations.py index 57e59e9..707826b 100644 --- a/openapi_core/operations.py +++ b/openapi_core/operations.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """OpenAPI core operations module""" import logging +from functools import lru_cache from six import iteritems @@ -30,8 +31,9 @@ class Operation(object): class OperationsGenerator(object): """Represents an OpenAPI Operation in a service.""" - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def generate(self, path_name, path): path_deref = self.dereferencer.dereference(path) @@ -42,12 +44,13 @@ class OperationsGenerator(object): operation_deref = self.dereferencer.dereference(operation) deprecated = operation_deref.get('deprecated', False) parameters_list = operation_deref.get('parameters', []) - parameters = self._generate_parameters(parameters_list) + parameters = self.parameters_generator.generate(parameters_list) request_body = None if 'requestBody' in operation_deref: request_body_spec = operation_deref.get('requestBody') - request_body = self._create_request_body(request_body_spec) + request_body = self.request_body_factory.create( + request_body_spec) yield ( http_method, @@ -57,8 +60,12 @@ class OperationsGenerator(object): ), ) - def _generate_parameters(self, parameters): - return ParametersGenerator(self.dereferencer).generate(parameters) + @property + @lru_cache() + def parameters_generator(self): + return ParametersGenerator(self.dereferencer, self.schemas_registry) - def _create_request_body(self, request_body_spec): - return RequestBodyFactory(self.dereferencer).create(request_body_spec) + @property + @lru_cache() + def request_body_factory(self): + return RequestBodyFactory(self.dereferencer, self.schemas_registry) diff --git a/openapi_core/parameters.py b/openapi_core/parameters.py index 676bfc8..4f25f68 100644 --- a/openapi_core/parameters.py +++ b/openapi_core/parameters.py @@ -1,8 +1,6 @@ """OpenAPI core parameters module""" import logging -from openapi_core.schemas import SchemaRegistry - log = logging.getLogger(__name__) @@ -32,8 +30,9 @@ class Parameter(object): class ParametersGenerator(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def generate(self, paramters): for parameter in paramters: @@ -45,7 +44,7 @@ class ParametersGenerator(object): schema_spec = parameter_deref.get('schema', None) schema = None if schema_spec: - schema = self._create_schema(schema_spec) + schema, _ = self.schemas_registry.get_or_create(schema_spec) yield ( parameter_deref['name'], @@ -54,8 +53,3 @@ class ParametersGenerator(object): schema=schema, default=default, required=required, ), ) - - def _create_schema(self, schema_spec): - schema, _ = SchemaRegistry(self.dereferencer).get_or_create( - schema_spec) - return schema diff --git a/openapi_core/paths.py b/openapi_core/paths.py index ff590ad..97ad858 100644 --- a/openapi_core/paths.py +++ b/openapi_core/paths.py @@ -1,4 +1,6 @@ """OpenAPI core paths module""" +from functools import lru_cache + from six import iteritems from openapi_core.operations import OperationsGenerator @@ -17,14 +19,17 @@ class Path(object): class PathsGenerator(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def generate(self, paths): paths_deref = self.dereferencer.dereference(paths) for path_name, path in iteritems(paths_deref): - operations = self._generate_operations(path_name, path) + operations = self.operations_generator.generate(path_name, path) yield path_name, Path(path_name, list(operations)) - def _generate_operations(self, path_name, path): - return OperationsGenerator(self.dereferencer).generate(path_name, path) + @property + @lru_cache() + def operations_generator(self): + return OperationsGenerator(self.dereferencer, self.schemas_registry) diff --git a/openapi_core/request_bodies.py b/openapi_core/request_bodies.py index 63ce895..0e94c52 100644 --- a/openapi_core/request_bodies.py +++ b/openapi_core/request_bodies.py @@ -1,4 +1,6 @@ """OpenAPI core requestBodies module""" +from functools import lru_cache + from openapi_core.media_types import MediaTypeGenerator @@ -15,16 +17,19 @@ class RequestBody(object): class RequestBodyFactory(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def create(self, request_body_spec): request_body_deref = self.dereferencer.dereference( request_body_spec) content = request_body_deref['content'] - media_types = self._generate_media_types(content) + media_types = self.media_types_generator.generate(content) required = request_body_deref.get('required', False) return RequestBody(media_types, required=required) - def _generate_media_types(self, content): - return MediaTypeGenerator(self.dereferencer).generate(content) + @property + @lru_cache() + def media_types_generator(self): + return MediaTypeGenerator(self.dereferencer, self.schemas_registry) diff --git a/openapi_core/schemas.py b/openapi_core/schemas.py index 97630d5..b631bee 100644 --- a/openapi_core/schemas.py +++ b/openapi_core/schemas.py @@ -1,7 +1,8 @@ """OpenAPI core schemas module""" import logging -from distutils.util import strtobool from collections import defaultdict +from distutils.util import strtobool +from functools import lru_cache from json import loads from six import iteritems @@ -114,7 +115,7 @@ class SchemaFactory(object): properties = None if properties_spec: - properties = self._generate_properties(properties_spec) + properties = self.properties_generator.generate(properties_spec) items = None if items_spec: @@ -125,8 +126,10 @@ class SchemaFactory(object): required=required, ) - def _generate_properties(self, properties_spec): - return PropertiesGenerator(self.dereferencer).generate(properties_spec) + @property + @lru_cache() + def properties_generator(self): + return PropertiesGenerator(self.dereferencer) def _create_items(self, items_spec): return self.create(items_spec) @@ -147,24 +150,16 @@ class SchemaRegistry(SchemaFactory): return self.create(schema_deref), True - def _create_items(self, items_spec): - schema, _ = self.get_or_create(items_spec) - return schema - class SchemasGenerator(object): - def __init__(self, dereferencer): + def __init__(self, dereferencer, schemas_registry): self.dereferencer = dereferencer + self.schemas_registry = schemas_registry def generate(self, schemas_spec): schemas_deref = self.dereferencer.dereference(schemas_spec) for schema_name, schema_spec in iteritems(schemas_deref): - schema = self._create_schema(schema_spec) + schema, _ = self.schemas_registry.get_or_create(schema_spec) yield schema_name, schema - - def _create_schema(self, schema_spec): - schema, _ = SchemaRegistry(self.dereferencer).get_or_create( - schema_spec) - return schema diff --git a/openapi_core/specs.py b/openapi_core/specs.py index f10dc46..d064184 100644 --- a/openapi_core/specs.py +++ b/openapi_core/specs.py @@ -1,13 +1,14 @@ # -*- coding: utf-8 -*- """OpenAPI core specs module""" import logging -from functools import partialmethod +from functools import partialmethod, lru_cache from openapi_spec_validator import openapi_v3_spec_validator from openapi_core.components import ComponentsFactory from openapi_core.infos import InfoFactory from openapi_core.paths import PathsGenerator +from openapi_core.schemas import SchemaRegistry log = logging.getLogger(__name__) @@ -62,17 +63,28 @@ class SpecFactory(object): paths = spec_dict_deref.get('paths', []) components_spec = spec_dict_deref.get('components', []) - info = self._create_info(info_spec) - paths = self._generate_paths(paths) - components = self._create_components(components_spec) + info = self.info_factory.create(info_spec) + paths = self.paths_generator.generate(paths) + components = self.components_factory.create(components_spec) spec = Spec(info, list(paths), servers=servers, components=components) return spec - def _create_info(self, info_spec): - return InfoFactory(self.dereferencer).create(info_spec) + @property + @lru_cache() + def schemas_registry(self): + return SchemaRegistry(self.dereferencer) - def _generate_paths(self, paths): - return PathsGenerator(self.dereferencer).generate(paths) + @property + @lru_cache() + def info_factory(self): + return InfoFactory(self.dereferencer) - def _create_components(self, components_spec): - return ComponentsFactory(self.dereferencer).create(components_spec) + @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)