Skip to content

Commit d88b4b1

Browse files
authored
Merge pull request #93 from Beirdo/master
Switched to using requests rather than direct use of urllib3
2 parents 76b4e2a + f1267ac commit d88b4b1

File tree

9 files changed

+151
-48
lines changed

9 files changed

+151
-48
lines changed

openapi_spec_validator/handlers.py

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from openapi_spec_validator.handlers.file import FileObjectHandler
2+
try:
3+
from openapi_spec_validator.handlers.requests import (
4+
UrlRequestsHandler as UrlHandler,
5+
)
6+
except ImportError:
7+
from openapi_spec_validator.handlers.urllib import (
8+
UrllibHandler as UrlHandler,
9+
)
10+
11+
__all__ = ['FileObjectHandler', 'UrlHandler']
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""OpenAPI spec validator handlers file module."""
2+
from openapi_spec_validator.loaders import ExtendedSafeLoader
3+
4+
5+
class BaseHandler(object):
6+
"""OpenAPI spec validator base handler."""
7+
8+
def __init__(self, **options):
9+
self.options = options
10+
11+
@property
12+
def loader(self):
13+
return self.options.get('loader', ExtendedSafeLoader)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""OpenAPI spec validator handlers file module."""
2+
from six import StringIO
3+
from yaml import load
4+
5+
from openapi_spec_validator.handlers.base import BaseHandler
6+
7+
8+
class FileObjectHandler(BaseHandler):
9+
"""OpenAPI spec validator file-like object handler."""
10+
11+
def __call__(self, f):
12+
return load(f, self.loader)
13+
14+
15+
class FileHandler(FileObjectHandler):
16+
"""OpenAPI spec validator file path handler."""
17+
18+
def __call__(self, f):
19+
if isinstance(f, StringIO):
20+
return super(FileHandler, self).__call__(f)
21+
22+
assert f.startswith("file")
23+
24+
filename = f[7:]
25+
with open(filename) as fh:
26+
return super(FileHandler, self).__call__(fh)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""OpenAPI spec validator handlers requests module."""
2+
from __future__ import absolute_import
3+
import contextlib
4+
5+
from six import StringIO
6+
from six.moves.urllib.parse import urlparse
7+
import requests
8+
9+
from openapi_spec_validator.handlers.file import FileHandler
10+
11+
12+
class UrlRequestsHandler(FileHandler):
13+
"""OpenAPI spec validator URL (requests) scheme handler."""
14+
15+
def __init__(self, *allowed_schemes, **options):
16+
super(UrlRequestsHandler, self).__init__(**options)
17+
self.allowed_schemes = allowed_schemes
18+
19+
def __call__(self, url, timeout=1):
20+
scheme = urlparse(url).scheme
21+
assert scheme in self.allowed_schemes
22+
23+
if scheme == "file":
24+
return super(UrlRequestsHandler, self).__call__(url)
25+
26+
response = requests.get(url, timeout=timeout)
27+
response.raise_for_status()
28+
29+
data = StringIO(response.text)
30+
with contextlib.closing(data) as fh:
31+
return super(UrlRequestsHandler, self).__call__(fh)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""OpenAPI spec validator handlers requests module."""
2+
import contextlib
3+
4+
from six.moves.urllib.parse import urlparse
5+
from six.moves.urllib.request import urlopen
6+
7+
from openapi_spec_validator.handlers.file import FileObjectHandler
8+
9+
10+
class UrllibHandler(FileObjectHandler):
11+
"""OpenAPI spec validator URL (urllib) scheme handler."""
12+
13+
def __init__(self, *allowed_schemes, **options):
14+
super(UrllibHandler, self).__init__(**options)
15+
self.allowed_schemes = allowed_schemes
16+
17+
def __call__(self, url, timeout=1):
18+
assert urlparse(url).scheme in self.allowed_schemes
19+
20+
f = urlopen(url, timeout=timeout)
21+
22+
with contextlib.closing(f) as fh:
23+
return super(UrllibHandler, self).__call__(fh)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
jsonschema
22
PyYAML==4.2b4
33
six==1.12.0
4+
requests

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ exclude =
4646

4747
[options.extras_require]
4848
dev = pre-commit
49+
requests = requests
4950

5051
[tool:pytest]
5152
addopts = -sv --flake8 --junitxml reports/junit.xml --cov openapi_spec_validator --cov-report term-missing --cov-report xml:reports/coverage.xml

tests/integration/test_shortcuts.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import pytest
22

3-
from openapi_spec_validator import validate_spec, validate_spec_url
4-
from openapi_spec_validator import validate_v2_spec, validate_v2_spec_url
3+
from openapi_spec_validator import (
4+
validate_spec, validate_spec_url,
5+
validate_v2_spec, validate_v2_spec_url,
6+
validate_spec_url_factory,
7+
openapi_v2_spec_validator, openapi_v3_spec_validator,
8+
)
59
from openapi_spec_validator.exceptions import OpenAPIValidationError
10+
from openapi_spec_validator.handlers.urllib import UrllibHandler
611

712

813
class BaseTestValidValidteV2Spec:
@@ -31,11 +36,32 @@ def test_failed(self, spec):
3136
validate_spec(spec)
3237

3338

34-
class BaseTestValidValidteV2SpecUrl:
39+
class BaseTestValidValidateSpecUrl:
40+
41+
@pytest.fixture
42+
def urllib_handlers(self):
43+
all_urls_handler = UrllibHandler('http', 'https', 'file')
44+
return {
45+
'<all_urls>': all_urls_handler,
46+
'http': UrllibHandler('http'),
47+
'https': UrllibHandler('https'),
48+
'file': UrllibHandler('file'),
49+
}
50+
51+
52+
class BaseTestValidValidateV2SpecUrl(BaseTestValidValidateSpecUrl):
53+
54+
@pytest.fixture
55+
def validate_spec_url_callable(self, urllib_handlers):
56+
return validate_spec_url_factory(
57+
openapi_v2_spec_validator.validate, urllib_handlers)
3558

3659
def test_valid(self, spec_url):
3760
validate_v2_spec_url(spec_url)
3861

62+
def test_urllib_valid(self, validate_spec_url_callable, spec_url):
63+
validate_spec_url_callable(spec_url)
64+
3965

4066
class BaseTestFaliedValidateV2SpecUrl:
4167

@@ -44,11 +70,19 @@ def test_failed(self, spec_url):
4470
validate_v2_spec_url(spec_url)
4571

4672

47-
class BaseTestValidValidteSpecUrl:
73+
class BaseTestValidValidateV3SpecUrl(BaseTestValidValidateSpecUrl):
4874

49-
def test_valid(self, spec_url):
75+
@pytest.fixture
76+
def validate_spec_url_callable(self, urllib_handlers):
77+
return validate_spec_url_factory(
78+
openapi_v3_spec_validator.validate, urllib_handlers)
79+
80+
def test_default_valid(self, spec_url):
5081
validate_spec_url(spec_url)
5182

83+
def test_urllib_valid(self, validate_spec_url_callable, spec_url):
84+
validate_spec_url_callable(spec_url)
85+
5286

5387
class BaseTestFaliedValidateSpecUrl:
5488

@@ -78,7 +112,7 @@ def spec(self, factory):
78112
return factory.spec_from_file("data/v3.0/petstore.yaml")
79113

80114

81-
class TestPetstoreV2Example(BaseTestValidValidteV2SpecUrl):
115+
class TestPetstoreV2Example(BaseTestValidValidateV2SpecUrl):
82116

83117
@pytest.fixture
84118
def spec_url(self):
@@ -89,7 +123,7 @@ def spec_url(self):
89123
)
90124

91125

92-
class TestApiV2WithExampe(BaseTestValidValidteV2SpecUrl):
126+
class TestApiV2WithExampe(BaseTestValidValidateV2SpecUrl):
93127

94128
@pytest.fixture
95129
def spec_url(self):
@@ -100,7 +134,7 @@ def spec_url(self):
100134
)
101135

102136

103-
class TestPetstoreV2ExpandedExample(BaseTestValidValidteV2SpecUrl):
137+
class TestPetstoreV2ExpandedExample(BaseTestValidValidateV2SpecUrl):
104138

105139
@pytest.fixture
106140
def spec_url(self):
@@ -111,7 +145,7 @@ def spec_url(self):
111145
)
112146

113147

114-
class TestPetstoreExample(BaseTestValidValidteSpecUrl):
148+
class TestPetstoreExample(BaseTestValidValidateV3SpecUrl):
115149

116150
@pytest.fixture
117151
def spec_url(self):
@@ -122,7 +156,7 @@ def spec_url(self):
122156
)
123157

124158

125-
class TestApiWithExampe(BaseTestValidValidteSpecUrl):
159+
class TestApiWithExampe(BaseTestValidValidateV3SpecUrl):
126160

127161
@pytest.fixture
128162
def spec_url(self):
@@ -133,7 +167,7 @@ def spec_url(self):
133167
)
134168

135169

136-
class TestPetstoreExpandedExample(BaseTestValidValidteSpecUrl):
170+
class TestPetstoreExpandedExample(BaseTestValidValidateV3SpecUrl):
137171

138172
@pytest.fixture
139173
def spec_url(self):

0 commit comments

Comments
 (0)