def test_absurl_relfile(): base = 'http://foo.bar' test = 'relative.file' with pytest.raises(url.ResolutionError): url.absurl(test) with pytest.raises(url.ResolutionError): url.absurl(test, base)
def test_absurl_fragment(): base = 'file:///etc/passwd' test = '#frag' with pytest.raises(url.ResolutionError): url.absurl(test) res = url.absurl(test, base) assert res.geturl() == 'file:///etc/passwd#frag'
def test_fetch_url_text_cached(): from prance.util import fs cache = {} content1, _ = url.fetch_url_text(url.absurl(fs.abspath('tests/specs/with_externals.yaml')), cache) content2, _ = url.fetch_url_text(url.absurl(fs.abspath('tests/specs/with_externals.yaml')), cache) # Strings are immutable, therefore IDs should be identical assert id(content1) == id(content2)
def test_absurl_paths_win32(): base = 'c:\\windows\\notepad.exe' test = "regedit.exe" expect = 'file:///c:/windows/regedit.exe' with pytest.raises(url.ResolutionError): url.absurl(test) res = url.absurl(test, base) assert res.geturl() == expect
def test_absurl_paths_posix(): base = '/etc/passwd' test = 'group' expect = 'file:///etc/group' with pytest.raises(url.ResolutionError): url.absurl(test) res = url.absurl(test, base) assert res.geturl() == expect
def test_fetch_url_cached(): from prance.util import fs cache = {} content1 = url.fetch_url(url.absurl(fs.abspath('tests/specs/with_externals.yaml')), cache) assert content1['swagger'] == '2.0' content2 = url.fetch_url(url.absurl(fs.abspath('tests/specs/with_externals.yaml')), cache) assert content2['swagger'] == '2.0' # Dicts are mutable, therefore we can't compare IDs. But individual # string fields should not be copied, because we shallow copy. assert id(content1['swagger']) == id(content2['swagger'])
def test_absurl_paths(): if sys.platform == "win32": base = 'c:\\windows\\notepad.exe' test = "regedit.exe" expect = 'file:///c:/windows/regedit.exe' else: base = '/etc/passwd' test = 'group' expect = 'file:///etc/group' with pytest.raises(url.ResolutionError): url.absurl(test) res = url.absurl(test, base) assert res.geturl() == expect
def __init__(self, specs, url=None): """ Construct a JSON reference resolver. The resolved specs are in the `specs` member after a call to `resolve_references` has been made. If a URL is given, it is used as a base for calculating the absolute URL of relative file references. :param dict specs: The parsed specs in which to resolve any references. :param str url: [optional] The URL to base relative references on. """ import copy self.specs = copy.deepcopy(specs) self.url = url if self.url: self.parsed_url = _url.absurl(self.url) self._url_key = _url.urlresource(self.parsed_url) else: self.parsed_url = self._url_key = None self.__resolution_status = self.__RS_UNRESOLVED self.__recursion_protection = set()
def get(self): """Endpoint to get the OpenAPI json.""" absurl = url.absurl( request.base_url.replace(request.path, cfg.prefix + '/swagger.json')) content, _ = convert_url(absurl) return json.loads(content)
def _dereference(self, urlstring): """ Dereference the URL string. Returns the parsed URL, the object path extraced from the URL, and the dereferenced object. """ # Parse URL parsed_url = _url.absurl(urlstring, self.parsed_url) # In order to start dereferencing anything in the referenced URL, we have # to read and parse it, of course. parsed_url, referenced = self._fetch_url(parsed_url) obj_path = parsed_url.fragment.split('/') while len(obj_path) and not obj_path[0]: obj_path = obj_path[1:] # In this inner parser's specification, we can now look for the referenced # object. value = referenced if len(obj_path) != 0: from dpath import util as dutil try: value = dutil.get(referenced, obj_path) except KeyError: raise _url.ResolutionError('Cannot resolve reference "%s"!' % (urlstring, )) return parsed_url, obj_path, value
def test_split_url_reference(): base = url.absurl('http://foo.bar/') # Relative reference parsed, path = url.split_url_reference(base, '#foo/bar') assert parsed.netloc == 'foo.bar' assert len(path) == 2 assert path[0] == 'foo' assert path[1] == 'bar' # Leading slashes are stripped parsed, path = url.split_url_reference(base, '#///foo/bar') assert parsed.netloc == 'foo.bar' assert len(path) == 2 assert path[0] == 'foo' assert path[1] == 'bar' # Absolute reference parsed, path = url.split_url_reference(base, 'http://somewhere/#foo/bar') assert parsed.netloc == 'somewhere' assert len(path) == 2 assert path[0] == 'foo' assert path[1] == 'bar' # Reference with escaped parts parsed, path = url.split_url_reference( base, 'http://somewhere/#foo/bar~1baz~1quux~0foo') assert parsed.netloc == 'somewhere' assert len(path) == 2 assert path[0] == 'foo' assert path[1] == 'bar/baz/quux~foo'
def test_split_url_reference(): base = url.absurl("http://foo.bar/") # Relative reference parsed, path = url.split_url_reference(base, "#foo/bar") assert parsed.netloc == "foo.bar" assert len(path) == 2 assert path[0] == "foo" assert path[1] == "bar" # Leading slashes are stripped parsed, path = url.split_url_reference(base, "#///foo/bar") assert parsed.netloc == "foo.bar" assert len(path) == 2 assert path[0] == "foo" assert path[1] == "bar" # Absolute reference parsed, path = url.split_url_reference(base, "http://somewhere/#foo/bar") assert parsed.netloc == "somewhere" assert len(path) == 2 assert path[0] == "foo" assert path[1] == "bar" # Reference with escaped parts parsed, path = url.split_url_reference( base, "http://somewhere/#foo/bar~1baz~1quux~0foo") assert parsed.netloc == "somewhere" assert len(path) == 2 assert path[0] == "foo" assert path[1] == "bar/baz/quux~foo"
def __init__(self, specs, url): """ Construct a JSON reference translator. The translated specs are in the `specs` member after a call to `translate_references` has been made. If a URL is given, it is used as a base for calculating the absolute URL of relative file references. :param dict specs: The parsed specs in which to translate any references. :param str url: [optional] The URL to base relative references on. """ import copy self.specs = copy.deepcopy(specs) self.__strict = True self.__reference_cache = {} self.__collected_references = {} if url: self.url = _url.absurl(url) url_key = (_url.urlresource(self.url), self.__strict) # If we have a url, we want to add ourselves to the reference cache # - that creates a reference loop, but prevents child resolvers from # creating a new resolver for this url. self.__reference_cache[url_key] = self.specs else: self.url = None
def test_absurl_absfile(): if sys.platform == "win32": test = 'file:///c:/windows/notepad.exe' else: test = 'file:///etc/passwd' res = url.absurl(test) assert res.geturl() == test
def test_absurl_http_fragment(): base = 'http://foo.bar/asdf/#lala/quux' test = '#another' res = url.absurl(test, base) assert res.scheme == 'http' assert res.netloc == 'foo.bar' assert res.path == '/asdf/' assert res.fragment == 'another'
def test_absurl_http_fragment(): base = "http://foo.bar/asdf/#lala/quux" test = "#another" res = url.absurl(test, base) assert res.scheme == "http" assert res.netloc == "foo.bar" assert res.path == "/asdf/" assert res.fragment == "another"
def __init__(self, specs, url=None, **options): """ Construct a JSON reference resolver. The resolved specs are in the `specs` member after a call to `resolve_references` has been made. If a URL is given, it is used as a base for calculating the absolute URL of relative file references. :param dict specs: The parsed specs in which to resolve any references. :param str url: [optional] The URL to base relative references on. :param dict reference_cache: [optional] Reference cache to use. When encountering references, nested RefResolvers are created, and this parameter is used by the RefResolver hierarchy to create only one resolver per unique URL. If you wish to use this optimization across distinct RefResolver instances, pass a dict here for the RefResolvers you create yourself. It's safe to ignore this parameter in other cases. :param int recursion_limit: [optional] set the limit on recursive references. The default is 1, indicating that an element may be refered to exactly once when resolving references. When the limit is reached, the recursion_limit_handler is invoked. :param callable recursion_limit_handler: [optional] A callable that gets invoked when the recursion_limit is reached. Defaults to raising ResolutionError. Receives the recursion_limit as the first parameter, and the parsed reference URL as the second. As the last parameter, it receives a tuple of references that have been detected as recursions. :param str encoding: [optional] The encoding to use. If not given, detect_encoding is used to determine the encoding. :param int resolve_types: [optional] Specify which types of references to resolve. Defaults to RESOLVE_ALL. """ import copy self.specs = copy.deepcopy(specs) self.url = url self.__reclimit = options.get('recursion_limit', 1) self.__reclimit_handler = options.get('recursion_limit_handler', default_reclimit_handler) self.__reference_cache = options.get('reference_cache', {}) if self.url: self.parsed_url = _url.absurl(self.url) self._url_key = _url.urlresource(self.parsed_url) # If we have a url, we want to add ourselves to the reference cache # - that creates a reference loop, but prevents child resolvers from # creating a new resolver for this url. if self.specs: self.__reference_cache[self._url_key] = self.specs else: self.parsed_url = self._url_key = None self.__resolve_types = options.get('resolve_types', RESOLVE_ALL) self.__encoding = options.get('encoding', None)
def test_absurl_file(): if sys.platform == "win32": base = 'file:///c:/windows/notepad.exe' test = "regedit.exe" expect = 'file:///c:/windows/regedit.exe' else: base = 'file:///etc/passwd' test = 'group' expect = 'file:///etc/group' res = url.absurl(test, base) assert res.geturl() == expect
def test_convert_url(): from prance.util import url converted, content_type = convert.convert_url(url.absurl('python://tests/specs/petstore.yaml')) # Check correct content type assert 'yaml' in content_type # Parsing can't fail. from prance.util import formats parsed = formats.parse_spec(converted, content_type = content_type) # Assert the correct target version assert 'openapi' in parsed assert parsed['openapi'].startswith('3.')
def iter_entries(parser, backend, version, file_format, path): if version == "v3.0" and backend != "openapi-spec-validator": return for entry in os.listdir(path): full = os.path.join(path, entry) testcase_name = None if os.path.isfile(full): testcase_name = make_name( full, parser, backend, version, file_format, entry ) elif os.path.isdir(full): if parser == "BaseParser": continue # skip separate files for the BaseParser full = os.path.join(full, "spec", "swagger.%s" % (file_format)) if os.path.isfile(full): testcase_name = make_name( full, parser, backend, version, file_format, entry ) if testcase_name: dirname = os.path.dirname(full) dirname = dirname.replace("\\", "\\\\") from prance.util import url absurl = url.absurl(os.path.abspath(full)).geturl() code = """ @pytest.mark.xfail() def %s(): import os cur = os.getcwd() os.chdir('%s') from prance import %s try: parser = %s('%s', backend = '%s') finally: os.chdir(cur) """ % ( testcase_name, dirname, parser, parser, absurl, backend, ) print(code) exec(code, globals())
def _skip_reference(self, ref_url): """Return whether the URL should not be dereferenced.""" if ref_url.scheme.startswith('http'): return (self.__resolve_types & RESOLVE_HTTP) == 0 elif ref_url.scheme == 'file': # Internal references from prance.util.url import absurl parsed_self = absurl(self.url) if parsed_self.path == ref_url.path: return (self.__resolve_types & RESOLVE_INTERNAL) == 0 # Local files return (self.__resolve_types & RESOLVE_FILES) == 0 else: from urllib.parse import urlunparse raise ValueError( 'Scheme "%s" is not recognized in reference URL: %s' % (ref_url.scheme, urlunparse(ref_url)))
def test_fetch_url_http(): exturl = 'http://finkhaeuser.de/projects/prance/petstore.yaml'\ '#/definitions/Pet' content = url.fetch_url(url.absurl(exturl)) assert content['swagger'] == '2.0'
def test_fetch_url_file(): from prance.util import fs content = url.fetch_url(url.absurl( fs.abspath('tests/with_externals.yaml'))) assert content['swagger'] == '2.0'
def test_urlresource(): parsed = url.absurl('http://foo.bar/asdf?some=query#myfrag') res = url.urlresource(parsed) assert res == 'http://foo.bar/asdf'
def test_fetch_url_python(): exturl = 'python://tests/specs/petstore.yaml' content = url.fetch_url(url.absurl(exturl)) assert content['swagger'] == '2.0'
def test_absurl_absfile(): test = 'file:///etc/passwd' res = url.absurl(test) assert res.geturl() == test
def test_absurl_file(): base = 'file:///etc/passwd' test = 'group' res = url.absurl(test, base) assert res.geturl() == 'file:///etc/group'
def test_absurl_absfile_win32(): test = 'file:///c:/windows/notepad.exe' res = url.absurl(test) assert res.geturl() == test
def test_absurl_file_win32(): base = 'file:///c:/windows/notepad.exe' test = "regedit.exe" expect = 'file:///c:/windows/regedit.exe' res = url.absurl(test, base) assert res.geturl() == expect
def test_absurl_http(): test = 'http://foo.bar/asdf/#lala/quux' res = url.absurl(test) assert res.geturl() == test