def test_jr_split_on_unix(self): """ test jr_split on unix-like os """ self.assertEqual(utils.jr_split( '/user/tmp/local/ttt'), ( 'file:///user/tmp/local/ttt', '#')) self.assertEqual(utils.jr_split( '/user/tmp/local/ttt/'), ( 'file:///user/tmp/local/ttt', '#'))
def test_jr_split_on_windows(self): """ test jr_split on windows """ target = 'file:///C:/user/tmp/local/ttt' if is_py2() else 'file:///c:/user/tmp/local/ttt' self.assertEqual(utils.jr_split(r'C:\user\tmp\local\ttt'), (target, '#')) self.assertEqual(utils.jr_split( # check here for adding backslach at the end of raw string # https://pythonconquerstheuniverse.wordpress.com/2008/06/04/gotcha-%E2%80%94-backslashes-in-windows-filenames/ os.path.normpath('C:/user/tmp/local/ttt/') ), (target, '#'))
def test_jr_split_on_windows(self): """ test jr_split on windows """ target = 'file:///C:/user/tmp/local/ttt' if is_py2( ) else 'file:///c:/user/tmp/local/ttt' self.assertEqual(utils.jr_split(r'C:\user\tmp\local\ttt'), (target, '#')) self.assertEqual( utils.jr_split( # check here for adding backslach at the end of raw string # https://pythonconquerstheuniverse.wordpress.com/2008/06/04/gotcha-%E2%80%94-backslashes-in-windows-filenames/ os.path.normpath('C:/user/tmp/local/ttt/')), (target, '#'))
def test_jr_split(self): """ test jr_split """ self.assertEqual(utils.jr_split( 'http://test.com/api/swagger.json#/definitions/s1'), ( 'http://test.com/api/swagger.json', '#/definitions/s1')) self.assertEqual(utils.jr_split( 'http://test/com/api/'), ( 'http://test/com/api/', '#')) self.assertEqual(utils.jr_split( '#/definitions/s1'), ( '', '#/definitions/s1')) self.assertEqual(utils.jr_split( '/user/tmp/local/ttt'), ( 'file:///user/tmp/local/ttt', '#')) self.assertEqual(utils.jr_split( '/user/tmp/local/ttt/'), ( 'file:///user/tmp/local/ttt', '#')) # relative path should be converted to absolute one self.assertEqual(utils.jr_split( 'user'), ( utils.normalize_url('user'), '#')) self.assertEqual(utils.jr_split( '#'), ( '', '#')) self.assertEqual(utils.jr_split( '//'), ( '', '#'))
def resolve(self, jref, parser=None): """ JSON reference resolver :param str jref: a JSON Reference, refer to http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 for details. :param parser: the parser corresponding to target object. :type parser: pyswagger.base.Context :return: the referenced object, wrapped by weakref.ProxyType :rtype: weakref.ProxyType :raises ValueError: if path is not valid """ logger.info('resolving: [{0}]'.format(jref)) if jref == None or len(jref) == 0: raise ValueError('Empty Path is not allowed') obj = None url, jp = utils.jr_split(jref) # check cacahed object against json reference by # comparing url first, and find those object prefixed with # the JSON pointer. o = self.__objs.get(url, None) if o: if isinstance(o, BaseObj): obj = o.resolve(utils.jp_split(jp)[1:]) elif isinstance(o, dict): for k, v in six.iteritems(o): if jp.startswith(k): obj = v.resolve(utils.jp_split(jp[len(k):])[1:]) break else: raise Exception('Unknown Cached Object: {0}'.format( str(type(o)))) # this object is not found in cache if obj == None: if url: obj, _ = self.load_obj(jref, parser=parser) if obj: obj = self.prepare_obj(obj, jref) else: # a local reference, 'jref' is just a json-pointer if not jp.startswith('#'): raise ValueError( 'Invalid Path, root element should be \'#\', but [{0}]' .format(jref)) obj = self.root.resolve(utils.jp_split( jp)[1:]) # heading element is #, mapping to self.root if obj == None: raise ValueError('Unable to resolve path, [{0}]'.format(jref)) if isinstance(obj, (six.string_types, six.integer_types, list, dict)): return obj return weakref.proxy(obj)
def resolve(self, jref, parser=None): """ JSON reference resolver :param str jref: a JSON Reference, refer to http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 for details. :param parser: the parser corresponding to target object. :type parser: pyswagger.base.Context :return: the referenced object, wrapped by weakref.ProxyType :rtype: weakref.ProxyType :raises ValueError: if path is not valid """ logger.info('resolving: [{0}]'.format(jref)) if jref == None or len(jref) == 0: raise ValueError('Empty Path is not allowed') obj = None url, jp = utils.jr_split(jref) if url: # check cacahed object against json reference by # comparing url first, and find those object prefixed with # the JSON pointer. o = self.__objs.get(url, None) if o: if isinstance(o, BaseObj): obj = o.resolve(utils.jp_split(jp)[1:]) elif isinstance(o, dict): for k, v in six.iteritems(o): if jp.startswith(k): obj = v.resolve(utils.jp_split(jp[len(k):])[1:]) break else: raise Exception('Unknown Cached Object: {0}'.format(str(type(o)))) # this object is not loaded yet, load it if obj == None: obj, _ = self.load_obj(jref, parser=parser) if obj: obj = self.prepare_obj(obj, jref) else: # a local reference, 'jref' is just a json-pointer if not jp.startswith('#'): raise ValueError('Invalid Path, root element should be \'#\', but [{0}]'.format(jref)) obj = self.root.resolve(utils.jp_split(jp)[1:]) # heading element is #, mapping to self.root if obj == None: raise ValueError('Unable to resolve path, [{0}]'.format(jref)) if isinstance(obj, (six.string_types, six.integer_types, list, dict)): return obj return weakref.proxy(obj)
def resolve(self, jref, parser=None): """ JSON reference resolver :param str jref: a JSON Reference, refer to http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 for details. :param parser: the parser corresponding to target object. :type parser: pyswagger.base.Context :return: the referenced object, wrapped by weakref.ProxyType :rtype: weakref.ProxyType :raises ValueError: if path is not valid """ logger.info('resolving: [{0}]'.format(jref)) if jref == None or len(jref) == 0: raise ValueError('Empty Path is not allowed') url, jp = utils.jr_split(jref) if url: if url not in self.__app_cache: # This loaded SwaggerApp would be kept in app_cache. app = SwaggerApp.load(url, parser=parser, app_cache=self.__app_cache, url_load_hook=self.__url_load_hook) app.prepare() # nothing but only keeping a strong reference of # loaded SwaggerApp. self.__strong_refs.append(app) return self.__app_cache[url].resolve(jp) if not jp.startswith('#'): raise ValueError( 'Invalid Path, root element should be \'#\', but [{0}]'.format( jref)) obj = self.root.resolve(utils.jp_split( jp)[1:]) # heading element is #, mapping to self.root if obj == None: raise ValueError('Unable to resolve path, [{0}]'.format(jref)) if isinstance(obj, (six.string_types, int, list, dict)): return obj return weakref.proxy(obj)
def prepare_obj(self, obj, jref): """ basic preparation of an object(those in sepc._version_.objects), and cache the 'prepared' object. """ if not obj: raise Exception('unexpected, passing {0}:{1} to prepare'.format( obj, jref)) s = Scanner(self) if self.version == '1.2': # upgrade from 1.2 to 2.0 converter = Upgrade(self.__sep) s.scan(root=obj, route=[converter]) obj = converter.swagger if not obj: raise Exception('unable to upgrade from 1.2: {0}'.format(jref)) s.scan(root=obj, route=[AssignParent()]) # normalize $ref url, jp = utils.jr_split(jref) s.scan(root=obj, route=[NormalizeRef(url)]) # fix for yaml that treat response code as number s.scan(root=obj, route=[YamlFixer()], leaves=[Operation]) # cache this object if url not in self.__objs: if jp == '#': self.__objs[url] = obj else: self.__objs[url] = {jp: obj} else: if not isinstance(self.__objs[url], dict): raise Exception('it should be able to resolve with BaseObj') self.__objs[url].update({jp: obj}) # pre resolve Schema Object # note: make sure this object is cached before using 'Resolve' scanner s.scan(root=obj, route=[Resolve()]) return obj
def prepare_obj(self, obj, jref): """ basic preparation of an object(those in sepc._version_.objects), and cache the 'prepared' object. """ if not obj: raise Exception('unexpected, passing {0}:{1} to prepare'.format(obj, jref)) s = Scanner(self) if self.version == '1.2': # upgrade from 1.2 to 2.0 converter = Upgrade(self.__sep) s.scan(root=obj, route=[converter]) obj = converter.swagger if not obj: raise Exception('unable to upgrade from 1.2: {0}'.format(jref)) s.scan(root=obj, route=[AssignParent()]) # normalize $ref url, jp = utils.jr_split(jref) s.scan(root=obj, route=[NormalizeRef(url)]) # fix for yaml that treat response code as number s.scan(root=obj, route=[YamlFixer()], leaves=[Operation]) # cache this object if url not in self.__objs: if jp == '#': self.__objs[url] = obj else: self.__objs[url] = {jp: obj} else: if not isinstance(self.__objs[url], dict): raise Exception('it should be able to resolve with BaseObj') self.__objs[url].update({jp: obj}) # pre resolve Schema Object # note: make sure this object is cached before using 'Resolve' scanner s.scan(root=obj, route=[Resolve()]) return obj
def test_jr_split_on_unix(self): """ test jr_split on unix-like os """ self.assertEqual(utils.jr_split('/user/tmp/local/ttt'), ('file:///user/tmp/local/ttt', '#')) self.assertEqual(utils.jr_split('/user/tmp/local/ttt/'), ('file:///user/tmp/local/ttt', '#'))