def get(self): """ The Swagger view get method outputs to /apispecs_1.json """ data = { "swagger": self.config.get('swagger') or self.config.get('swagger_version', "2.0"), # try to get from config['SWAGGER']['info'] # then config['SWAGGER']['specs'][x] # then config['SWAGGER'] # then default "info": self.config.get('info') or { "version": self.spec.get('version', self.config.get('version', "0.0.1")), "title": self.spec.get('title', self.config.get('title', "A swagger API 2")), "description": self.spec.get( 'description', self.config.get('description', "powered by Flasgger")), "termsOfService": self.spec.get('termsOfService', self.config.get('termsOfService', "/tos")), }, "paths": self.config.get('paths') or defaultdict(dict), "definitions": self.config.get('definitions') or defaultdict(dict) } # Support extension properties in the top level config top_level_extension_options = get_vendor_extension_fields(self.config) if top_level_extension_options: data.update(top_level_extension_options) # if True schemaa ids will be prefized by function_method_{id} # for backwards compatibility with <= 0.5.14 prefix_ids = self.config.get('prefix_ids') if self.config.get('host'): data['host'] = self.config.get('host') if self.config.get("basePath"): data["basePath"] = self.config.get('basePath') if self.config.get("securityDefinitions"): data["securityDefinitions"] = self.config.get( 'securityDefinitions') # set defaults from template if self.template is not None: data.update(self.template) paths = data['paths'] definitions = data['definitions'] ignore_verbs = set(self.config.get('ignore_verbs', ("HEAD", "OPTIONS"))) # technically only responses is non-optional optional_fields = self.config.get('optional_fields') or OPTIONAL_FIELDS for name, def_model in self.get_def_models( self.spec.get('definition_filter')).items(): description, swag = parse_definition_docstring( def_model, self.process_doc) if name and swag: if description: swag.update({'description': description}) definitions[name].update(swag) for rule in self.get_url_mappings(self.spec.get('rule_filter')): endpoint = current_app.view_functions[rule.endpoint] methods = dict() is_mv = is_valid_method_view(endpoint) for verb in rule.methods.difference(ignore_verbs): if not is_mv and has_valid_dispatch_view_docs(endpoint): endpoint.methods = endpoint.methods or ['GET'] if verb in endpoint.methods: methods[verb.lower()] = endpoint elif getattr(endpoint, 'methods', None) is not None: if verb in endpoint.methods: verb = verb.lower() methods[verb] = getattr(endpoint.view_class, verb) else: methods[verb.lower()] = endpoint operations = dict() for verb, method in methods.items(): klass = method.__dict__.get('view_class', None) if not is_mv and klass and hasattr(klass, 'verb'): method = klass.__dict__.get('verb') elif klass and hasattr(klass, 'dispatch_request'): method = klass.__dict__.get('dispatch_request') if method is None: # for MethodView method = klass.__dict__.get(verb) if method is None: if is_mv: # #76 Empty MethodViews continue raise RuntimeError( 'Cannot detect view_func for rule {0}'.format(rule)) swag = {} swagged = False view_class = getattr(endpoint, 'view_class', None) if view_class and issubclass(view_class, SwaggerView): apispec_swag = {} apispec_attrs = optional_fields + [ 'parameters', 'definitions', 'responses', 'summary', 'description' ] for attr in apispec_attrs: value = getattr(view_class, attr) if value: apispec_swag[attr] = value apispec_definitions = apispec_swag.get('definitions', {}) swag.update( convert_schemas(apispec_swag, apispec_definitions)) swagged = True if getattr(method, 'specs_dict', None): swag.update(deepcopy(method.specs_dict)) swagged = True doc_summary, doc_description, doc_swag = parse_docstring( method, self.process_doc, endpoint=rule.endpoint, verb=verb) if doc_swag: swag.update(doc_swag or {}) swagged = True # we only add swagged endpoints if swagged: if doc_summary: swag['summary'] = doc_summary if doc_description: swag['description'] = doc_description definitions.update(swag.get('definitions', {})) defs = [] # swag.get('definitions', []) defs += extract_definitions(defs, endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) params = swag.get('parameters', []) defs += extract_definitions(params, endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) responses = None if 'responses' in swag: responses = swag.get('responses', {}) responses = { str(key): value for key, value in responses.items() } if responses is not None: defs = defs + extract_definitions( responses.values(), endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) for definition in defs: if 'id' not in definition: definitions.update(definition) continue def_id = definition.pop('id') if def_id is not None: definitions[def_id].update(definition) operation = {} if swag.get('summary'): operation['summary'] = swag.get('summary') if swag.get('description'): operation['description'] = swag.get('description') if responses: operation['responses'] = responses # parameters - swagger ui dislikes empty parameter lists if len(params) > 0: operation['parameters'] = params # other optionals for key in optional_fields: if key in swag: value = swag.get(key) if key in ('produces', 'consumes'): if not isinstance(value, (list, tuple)): value = [value] operation[key] = value operations[verb] = operation if len(operations): srule = str(rule) # old regex '(<(.*?\:)?(.*?)>)' for arg in re.findall('(<([^<>]*:)?([^<>]*)>)', srule): srule = srule.replace(arg[0], '{%s}' % arg[2]) for key, val in operations.items(): if key in paths[srule]: paths[srule][key].update(val) else: paths[srule][key] = val return jsonify(data)
def get(self): """ The Swagger view get method outputs to /apispecs_1.json """ data = { "swagger": self.config.get('swagger') or self.config.get('swagger_version', "2.0"), # try to get from config['SWAGGER']['info'] # then config['SWAGGER']['specs'][x] # then config['SWAGGER'] # then default "info": self.config.get('info') or { "version": self.spec.get('version', self.config.get('version', "0.0.1")), "title": self.spec.get('title', self.config.get('title', "A swagger API 2")), "description": self.spec.get( 'description', self.config.get('description', "powered by Flasgger")), "termsOfService": self.spec.get('termsOfService', self.config.get('termsOfService', "/tos")), }, "paths": self.config.get('paths') or defaultdict(dict), "definitions": self.config.get('definitions') or defaultdict(dict) } # Support extension properties in the top level config top_level_extension_options = get_vendor_extension_fields(self.config) if top_level_extension_options: data.update(top_level_extension_options) # if True schemaa ids will be prefized by function_method_{id} # for backwards compatibility with <= 0.5.14 prefix_ids = self.config.get('prefix_ids') if self.config.get('host'): data['host'] = self.config.get('host') if self.config.get("basePath"): data["basePath"] = self.config.get('basePath') if self.config.get("securityDefinitions"): data["securityDefinitions"] = self.config.get( 'securityDefinitions') # set defaults from template if self.template is not None: data.update(self.template) paths = data['paths'] definitions = data['definitions'] ignore_verbs = set(self.config.get('ignore_verbs', ("HEAD", "OPTIONS"))) # technically only responses is non-optional optional_fields = self.config.get('optional_fields') or OPTIONAL_FIELDS for name, def_model in self.get_def_models( self.spec.get('definition_filter')).items(): description, swag = parse_definition_docstring( def_model, self.process_doc) if name and swag: if description: swag.update({'description': description}) definitions[name].update(swag) specs = get_specs(self.get_url_mappings(self.spec.get('rule_filter')), ignore_verbs, optional_fields, self.process_doc) for rule, verbs in specs: operations = dict() for verb, swag in verbs: definitions.update(swag.get('definitions', {})) defs = [] # swag.get('definitions', []) defs += extract_definitions(defs, endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) params = swag.get('parameters', []) defs += extract_definitions(params, endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) responses = None if 'responses' in swag: responses = swag.get('responses', {}) responses = { str(key): value for key, value in responses.items() } if responses is not None: defs = defs + extract_definitions( responses.values(), endpoint=rule.endpoint, verb=verb, prefix_ids=prefix_ids) for definition in defs: if 'id' not in definition: definitions.update(definition) continue def_id = definition.pop('id') if def_id is not None: definitions[def_id].update(definition) operation = {} if swag.get('summary'): operation['summary'] = swag.get('summary') if swag.get('description'): operation['description'] = swag.get('description') if responses: operation['responses'] = responses # parameters - swagger ui dislikes empty parameter lists if len(params) > 0: operation['parameters'] = params # other optionals for key in optional_fields: if key in swag: value = swag.get(key) if key in ('produces', 'consumes'): if not isinstance(value, (list, tuple)): value = [value] operation[key] = value operations[verb] = operation if len(operations): srule = str(rule) # old regex '(<(.*?\:)?(.*?)>)' for arg in re.findall('(<([^<>]*:)?([^<>]*)>)', srule): srule = srule.replace(arg[0], '{%s}' % arg[2]) for key, val in operations.items(): if key in paths[srule]: paths[srule][key].update(val) else: paths[srule][key] = val return jsonify(data)