def get_controllers(name): '''get all the controllers associated with a path returns a dictionary of controllers indexed by their names. ''' c = _hierarchy[name] return {k: p_u._cfg(v) for k, v in c.__dict__.items() if p_u.iscontroller(v)}
def get_controllers(name): """ get all the controllers associated with a path returns a dictionary of controllers indexed by their names. """ c = _hierarchy[name] controllers = {k: p_u._cfg(v) for k, v in c.__dict__.items() if p_u.iscontroller(v)} cacts = {k: v for k, v in c.__dict__.items() if k == '_custom_actions'} if len(cacts): controllers.update(cacts) return controllers
def methods_get(name): """get all the methods for a named controller.""" c = _hierarchy[name] mlist = [] if hasattr(c, 'index') and p_u.iscontroller(c.index): cfg = p_u._cfg(c.index) if cfg.get('generic_handlers').get('DEFAULT'): mlist.append('get') mlist += cfg.get('allowed_methods') for i in c.__dict__: ii = getattr(c, i) if hasattr(ii, '__swag'): m = ii.__swag.get('method') if m is not None: mlist.append(m) return mlist
def get_wsme_defs(name): def datatype_to_type_and_format(datatype): tf = {} if datatype == 'uuid' or datatype == 'ipv4address' \ or datatype == 'ipv6address' or datatype == 'date' \ or datatype == 'time': tf['type'] = 'string' tf['format'] = datatype elif datatype == 'datetime': tf['type'] = 'string' tf['format'] = 'date-time' elif datatype == 'binary' or datatype == 'bytes': # base64 encoded characters tf['type'] = 'string' tf['format'] = 'byte' elif datatype == 'array' or datatype == 'boolean' \ or datatype == 'integer' or datatype == 'string': # no format tf['type'] = datatype elif datatype == 'float': # number tf['type'] = 'number' tf['format'] = datatype elif datatype == 'unicode' or datatype == 'str' \ or datatype == 'text': # primitive, no format tf['type'] = 'string' elif datatype == 'int' or datatype == 'decimal': # primitive, no format tf['type'] = 'integer' elif datatype == 'bool': # primitive, no format tf['type'] = 'boolean' elif datatype == 'enum': tf['type'] = 'enum' elif datatype == 'unset' or datatype == 'none': tf['type'] = None elif datatype == 'dict': tf['type'] = 'object' else: tf['type'] = 'object' return tf def class_to_name_str(c): return (('%s' % c).replace('<', '').replace('>', '') .replace('class ', '').replace('\'', '') .split(' ', 1)[0].rsplit('.', 1)[-1]) def conv_class_name_to_type_str(cn): type_str = '' if cn.endswith('Type'): type_str = cn[:-4] elif cn == 'str': type_str = 'string' else: type_str = cn type_str = type_str.lower() return type_str def get_type_str(obj, src_dict=None): type_str = '' if hasattr(obj, '__name__'): type_str = obj.__name__ else: type_str = obj.__class__.__name__ type_str = conv_class_name_to_type_str(type_str) tf = datatype_to_type_and_format(type_str) if hasattr(obj, 'basetype') and \ (obj.__class__ not in _all_wsme_types or type_str == 'enum'): # UserType or Enum tf['type'] = get_type_str(obj.basetype) if isinstance(src_dict, dict): # if dict is in args, set 'type' and 'format' into the dict and # return src_dict.update({'type': tf['type']}) if 'format' in tf: src_dict.update({'format': tf['format']}) # get datatype options. ex.) min_length, minimum, .. for k, v in inspect.getmembers(obj): if ((k == 'minimum' or k == 'maxmum' or k == 'min_length' or k == 'max_length') and v is not None): src_dict[to_swag_key(k)] = v elif k == 'pattern' and v is not None: src_dict[to_swag_key(k)] = v.pattern # TODO(shu-mutou): this should be removed for production. # else: # src_dict[to_swag_key(k)] = v if type_str == 'enum': # EnumType use 'set' that doesn't have sequence. # So use 'sorted' for keeping static output. src_dict['enum'] = sorted([v for v in obj.values]) # return 'type' only return tf['type'] def to_swag_key(key): keys = { 'doc': 'description', 'arguments': 'parameters', 'return_type': 'schema', 'datatype': 'type', 'mandatory': 'required', 'sample': 'examples', 'readonly': 'readOnly', 'min_length': 'minLength', 'max_length': 'maxLength', } if key in keys: return keys[key] else: return key def get_wm_item_prop(item, isparams=False): # Add prop into 'properties' and 'required' in 'Items Object' # 'Items Object' can be part of 'Schema Object' or 'Items Object', # and can use recursively prop_dict = {} # TODO(shu-mutou): this should be removed for production. # prop_dict['obj'] = inspect.getmembers(item) _item = item if wtypes.iscomplex(item): _item = weakref.ref(item) for a, i in inspect.getmembers(_item): if a == 'datatype': datatype = get_type_str(i, prop_dict) if datatype == 'array': # if array, do recursively prop_dict['items'] = inspect_wm_schema(i.item_type) elif datatype == 'object': # if obuject, do recursively prop_dict['items'] = inspect_wm_schema(i) elif a == 'default' and i: prop_dict[to_swag_key(a)] = i elif a == 'name' and isparams: prop_dict[to_swag_key(a)] = i elif a == 'mandatory' and i: prop_dict[to_swag_key(a)] = i elif a == 'readonly' and i: prop_dict[to_swag_key(a)] = i elif a == 'doc' and i is not None: prop_dict[to_swag_key(a)] = i if isparams and prop_dict['type'] in ['object', 'array']: prop_dict['schema'] = {'items': prop_dict['items'], 'type': prop_dict['type']} del prop_dict['type'] del prop_dict['items'] return prop_dict def get_wsattr_and_wsproperty(obj): ws_dict = {} for key, value in inspect.getmembers(obj): if (key[0] != '_' and (value.__class__.__name__ == 'wsattr' or value.__class__.__name__ == 'wsproperty')): ws_dict[key] = value return ws_dict def inspect_wm_schema(schema_obj, isparams=False): schema_dict = {} # TODO(shu-mutou): this should be removed for production. # schema_dict['obj'] = get_wsattr_and_wsproperty(schema_obj) ws_len = len(get_wsattr_and_wsproperty(schema_obj)) for key, obj in inspect.getmembers(schema_obj): if (key[0] != '_' and (obj.__class__.__name__ == 'wsattr' or obj.__class__.__name__ == 'wsproperty')): # TODO(shu-mutou): this should be removed for production. # schema_dict[to_swag_key(key)] = \ # {'obj': inspect.getmembers(obj)} if ws_len == 1: # single schema schema_dict = get_wm_item_prop(obj, isparams) else: # multi property schema schema_dict.update({'type': 'object'}) # properties if 'items' not in schema_dict: schema_dict['items'] = {'properties': {}} prop = {key: get_wm_item_prop(obj, isparams)} # required as array of string if 'required' in prop[key] and prop[key]['required'] \ and isinstance(prop[key]['required'], bool): if 'required' not in schema_dict: schema_dict['required'] = [] schema_dict['required'].append(key) del prop[key]['required'] schema_dict['items']['properties'].update(prop) return schema_dict def get_wm_def(o): wsme = {'description': ''} for w, d in inspect.getmembers(o): if w == 'arguments': wsme[to_swag_key(w)] = [] for arg in d: # set each 'Parameter Object', it can include # 'Items Object' recursively item_dict = get_wm_item_prop(arg, True) # TODO: MUST be set one of # 'body|query|path|header|formData' item_dict['in'] = 'query' wsme[to_swag_key(w)].append(item_dict) # 'body' should be set due to existing 'body' option # in WSME expose if o.body_type is not None: # if body is set, last arg is it. wsme[to_swag_key(w)][-1]['in'] = 'body' elif w == 'doc' and d: wsme[to_swag_key(w)] = d elif w == 'return_type': wsme['responses'] = {'status': {'description': ''}} if d: if d in _all_wsme_types: # d is set single WSME type class or implicit type wsme['responses']['status'][to_swag_key(w)] = ( datatype_to_type_and_format( conv_class_name_to_type_str( class_to_name_str(d)))) else: # d is model class wsme['responses']['status'][to_swag_key(w)] = ( inspect_wm_schema(d, False)) doc = inspect.getdoc(d) if doc is not None: wsme['responses']['status']['description'] = doc elif w == 'status_code': wsme['responses'][d] = \ copy.deepcopy(wsme['responses']['status']) del wsme['responses']['status'] # TODO(shu-mutou): this should be removed for production. # elif w == 'body_type': # wsme[to_swag_key(w)] = get_type_str(d) # elif w == 'extra_options' or w == 'ignore_extra_args' \ # or w == 'name' or w == 'pass_request': # wsme[to_swag_key(w)] = d # else: # wsme[to_swag_key(w)] = d return wsme c = _hierarchy[name] wsme_defs = {} for k, v in inspect.getmembers(c): if p_u.iscontroller(v): for m, o in inspect.getmembers(v): if m == "_wsme_definition": wsme_defs[k] = get_wm_def(o) # TODO(shu-mutou): this should be removed for production. # output wsme info into files by each controller for dev # import pprint # with open(name + '.txt', 'w') as fout: # pprint.pprint(wsme_defs, stream=fout, indent=2) return wsme_defs
def get_wsme_defs(name): def datatype_to_type_and_format(datatype): tf = {} if datatype == 'uuid' or datatype == 'ipv4address' \ or datatype == 'ipv6address' or datatype == 'date' \ or datatype == 'time': tf['type'] = 'string' tf['format'] = datatype elif datatype == 'datetime': tf['type'] = 'string' tf['format'] = 'date-time' elif datatype == 'binary' or datatype == 'bytes': # base64 encoded characters tf['type'] = 'string' tf['format'] = 'byte' elif datatype == 'array' or datatype == 'boolean' \ or datatype == 'integer' or datatype == 'string': # no format tf['type'] = datatype elif datatype == 'float': # number tf['type'] = 'number' tf['format'] = datatype elif datatype == 'unicode' or datatype == 'str' \ or datatype == 'text': # primitive, no format tf['type'] = 'string' elif datatype == 'int' or datatype == 'decimal': # primitive, no format tf['type'] = 'integer' elif datatype == 'bool': # primitive, no format tf['type'] = 'boolean' elif datatype == 'enum': tf['type'] = 'enum' elif datatype == 'unset' or datatype == 'none': tf['type'] = None elif datatype == 'dict': tf['type'] = 'object' else: tf['type'] = 'object' return tf def class_to_name_str(c): return (('%s' % c).replace('<', '').replace('>', '') .replace('class ', '').replace('\'', '') .split(' ', 1)[0].rsplit('.', 1)[-1]) def conv_class_name_to_type_str(cn): type_str = '' if cn.endswith('Type'): type_str = cn[:-4] elif cn == 'str': type_str = 'string' else: type_str = cn type_str = type_str.lower() return type_str def get_type_str(obj, src_dict=None): type_str = '' if hasattr(obj, '__name__'): type_str = obj.__name__ else: type_str = obj.__class__.__name__ type_str = conv_class_name_to_type_str(type_str) tf = datatype_to_type_and_format(type_str) if hasattr(obj, 'basetype') and \ (obj.__class__ not in _all_wsme_types or type_str == 'enum'): # UserType or Enum tf['type'] = get_type_str(obj.basetype) if isinstance(src_dict, dict): # if dict is in args, set 'type' and 'format' into the dict and # return src_dict.update({'type': tf['type']}) if 'format' in tf: src_dict.update({'format': tf['format']}) # get datatype options. ex.) min_length, minimum, .. for k, v in inspect.getmembers(obj): if ((k == 'minimum' or k == 'maxmum' or k == 'min_length' or k == 'max_length') and v is not None): src_dict[to_swag_key(k)] = v elif k == 'pattern' and v is not None: src_dict[to_swag_key(k)] = v.pattern # TODO(shu-mutou): this should be removed for production. # else: # src_dict[to_swag_key(k)] = v if type_str == 'enum': # EnumType use 'set' that doesn't have sequence. # So use 'sorted' for keeping static output. src_dict['enum'] = sorted([v for v in obj.values]) # return 'type' only return tf['type'] def to_swag_key(key): keys = { 'doc': 'description', 'arguments': 'parameters', 'return_type': 'schema', 'datatype': 'type', 'mandatory': 'required', 'sample': 'examples', 'readonly': 'readOnly', 'min_length': 'minLength', 'max_length': 'maxLength', } if key in keys: return keys[key] else: return key def get_wm_item_prop(item, isparams=False): # Add prop into 'properties' and 'required' in 'Items Object' # 'Items Object' can be part of 'Schema Object' or 'Items Object', # and can use recursively prop_dict = {} # TODO(shu-mutou): this should be removed for production. # prop_dict['obj'] = inspect.getmembers(item) _item = item if wtypes.iscomplex(item): _item = weakref.ref(item) for a, i in inspect.getmembers(_item): if a == 'datatype': datatype = get_type_str(i, prop_dict) if datatype == 'array': # if array, do recursively prop_dict['items'] = inspect_wm_schema(i.item_type) elif datatype == 'object': # if obuject, do recursively prop_dict['items'] = inspect_wm_schema(i) elif a == 'default' and i: prop_dict[to_swag_key(a)] = i elif a == 'name' and isparams: prop_dict[to_swag_key(a)] = i elif a == 'mandatory' and i: prop_dict[to_swag_key(a)] = i elif a == 'readonly' and i: prop_dict[to_swag_key(a)] = i elif a == 'doc' and i is not None: prop_dict[to_swag_key(a)] = i if isparams and prop_dict['type'] in ['object', 'array']: prop_dict['schema'] = {'items': prop_dict['items'], 'type': prop_dict['type']} del prop_dict['type'] del prop_dict['items'] return prop_dict def get_wsattr_and_wsproperty(obj): ws_dict = {} for key, value in inspect.getmembers(obj): if (key[0] != '_' and (value.__class__.__name__ == 'wsattr' or value.__class__.__name__ == 'wsproperty')): ws_dict[key] = value return ws_dict def inspect_wm_schema(schema_obj, isparams=False): schema_dict = {} # TODO(shu-mutou): this should be removed for production. # schema_dict['obj'] = get_wsattr_and_wsproperty(schema_obj) ws_len = len(get_wsattr_and_wsproperty(schema_obj)) model_name = class_to_name_str(schema_obj) for key, obj in inspect.getmembers(schema_obj): if (key[0] != '_' and (obj.__class__.__name__ == 'wsattr' or obj.__class__.__name__ == 'wsproperty')): # TODO(shu-mutou): this should be removed for production. # _definitions[model_name][to_swag_key(key)] = \ # {'obj': inspect.getmembers(obj)} if ws_len == 1: # single schema schema_dict = get_wm_item_prop(obj, isparams) else: # multi property schema schema_dict.update({'type': 'object'}) # properties if 'items' not in schema_dict: schema_dict['items'] = {'properties': {}} prop = {key: get_wm_item_prop(obj, isparams)} # required as array of string if 'required' in prop[key] and prop[key]['required'] \ and isinstance(prop[key]['required'], bool): if 'required' not in schema_dict: schema_dict['required'] = [] schema_dict['required'].append(key) del prop[key]['required'] schema_dict['items']['properties'].update(prop) if schema_obj not in _all_wsme_types: if model_name not in _definitions: _definitions[model_name] = schema_dict schema_dict = {'$ref': "#/definitions/%s" % model_name} return schema_dict def get_wm_def(o): wsme = {'description': ''} for w, d in inspect.getmembers(o): if w == 'arguments': wsme[to_swag_key(w)] = [] for arg in d: # set each 'Parameter Object', it can include # 'Items Object' recursively item_dict = get_wm_item_prop(arg, True) # TODO: MUST be set one of # 'body|query|path|header|formData' item_dict['in'] = 'query' wsme[to_swag_key(w)].append(item_dict) # 'body' should be set due to existing 'body' option # in WSME expose if o.body_type is not None: # if body is set, last arg is it. wsme[to_swag_key(w)][-1]['in'] = 'body' elif w == 'doc' and d: wsme[to_swag_key(w)] = d elif w == 'return_type': wsme['responses'] = {'status': {'description': ''}} if d: if d in _all_wsme_types: # d is set single WSME type class or implicit type wsme['responses']['status'][to_swag_key(w)] = ( datatype_to_type_and_format( conv_class_name_to_type_str( class_to_name_str(d)))) else: # d is model class wsme['responses']['status'][to_swag_key(w)] = ( inspect_wm_schema(d, False)) doc = inspect.getdoc(d) if doc is not None: wsme['responses']['status']['description'] = doc elif w == 'status_code': wsme['responses'][d] = wsme['responses']['status'] del wsme['responses']['status'] # TODO(shu-mutou): this should be removed for production. # elif w == 'body_type': # wsme[to_swag_key(w)] = get_type_str(d) # elif w == 'extra_options' or w == 'ignore_extra_args' \ # or w == 'name' or w == 'pass_request': # wsme[to_swag_key(w)] = d # else: # wsme[to_swag_key(w)] = d return wsme c = _hierarchy[name] wsme_defs = {} for k, v in inspect.getmembers(c): if p_u.iscontroller(v): for m, o in inspect.getmembers(v): if m == "_wsme_definition": wsme_defs[k] = get_wm_def(o) # TODO(shu-mutou): this should be removed for production. # output wsme info into files by each controller for dev # import pprint # with open(name + '.txt', 'w') as fout: # pprint.pprint(wsme_defs, stream=fout, indent=2) return wsme_defs