Skip to content

Commit f22a7a7

Browse files
Fix spec clone method and usage of raw vs resolved spec (#2089)
This PR fixes an issue introduced in #2002, and the original issue #2002 was trying to address. The original issue was that a cloned spec did not have properly resolved references. #2002 fixed this incorrectly by cloning the resolved spec, while the `Spec` initializer expects a raw spec. This PR fixes this by cloning the raw spec, and passing the `base_uri` required to resolve it along to the initializer of the new `Spec` instance. The swagger ui was also updated to use the resolved spec instead of the raw spec. Supersedes: #1889 #2080 Fixes: #1890 #1909 #2028 #2029
1 parent 0bf9d1f commit f22a7a7

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

connexion/middleware/swagger_ui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def _spec_for_prefix(self, request) -> dict:
7070
This is needed when behind a path-altering reverse proxy.
7171
"""
7272
base_path = self._base_path_for_prefix(request)
73-
return self.specification.with_base_path(base_path).raw
73+
return self.specification.with_base_path(base_path).spec
7474

7575
def add_openapi_json(self):
7676
"""

connexion/spec.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def __init__(self, raw_spec, *, base_uri=""):
8181
self._set_defaults(raw_spec)
8282
self._validate_spec(raw_spec)
8383
self._spec = resolve_refs(raw_spec, base_uri=base_uri)
84+
self._base_uri = base_uri
8485

8586
@classmethod
8687
@abc.abstractmethod
@@ -107,6 +108,10 @@ def get_operation(self, path, method):
107108
def raw(self):
108109
return self._raw_spec
109110

111+
@property
112+
def spec(self):
113+
return self._spec
114+
110115
@property
111116
def version(self):
112117
return self._get_spec_version(self._spec)
@@ -204,7 +209,7 @@ def enforce_string_keys(obj):
204209
return OpenAPISpecification(spec, base_uri=base_uri)
205210

206211
def clone(self):
207-
return type(self)(copy.deepcopy(self._spec))
212+
return type(self)(copy.deepcopy(self._raw_spec), base_uri=self._base_uri)
208213

209214
@classmethod
210215
def load(cls, spec, *, arguments=None):

tests/test_api.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77
from connexion import FlaskApi
88
from connexion.exceptions import InvalidSpecification, ResolverError
9+
from connexion.jsonifier import Jsonifier
910
from connexion.spec import Specification, canonical_base_path
1011
from yaml import YAMLError
1112

@@ -198,9 +199,18 @@ def test_validation_error_on_completely_invalid_swagger_spec():
198199

199200

200201
def test_relative_refs(relative_refs, spec):
202+
jsonifier = Jsonifier()
203+
201204
spec_path = relative_refs / spec
202205
specification = Specification.load(spec_path)
203-
assert "$ref" not in specification.raw
206+
207+
assert "$ref" in jsonifier.dumps(specification.raw)
208+
assert "$ref" not in jsonifier.dumps(specification.spec)
209+
210+
cloned_specification = specification.clone()
211+
212+
assert "$ref" in jsonifier.dumps(cloned_specification.raw)
213+
assert "$ref" not in jsonifier.dumps(cloned_specification.spec)
204214

205215

206216
@pytest.fixture

0 commit comments

Comments
 (0)