def register_once(api, add_resource_func, api_version, swagger_version, base_path, resource_path, produces, endpoint_path, description): def registering_blueprint(setup_state): reg = registry[setup_state.blueprint.name] reg['x-api-prefix'] = setup_state.url_prefix def register_action(name, is_blueprint=True): resource_listing_endpoint = StorageSingleton( ).resource_listing_endpoint registry[name] = { 'apiVersion': api_version, 'swaggerVersion': swagger_version, 'basePath': base_path, 'spec_endpoint_path': endpoint_path, 'resourcePath': resource_path, 'produces': produces, 'description': description, } if is_blueprint: registry[name].update({ 'x-api-prefix': '', 'apis': [], }) api.blueprint.record(registering_blueprint) add_resource_func( SwaggerRegistry, endpoint_path, endpoint_path + '.json', endpoint_path + '.html', endpoint='app/registry' if not is_blueprint else None, ) resource_listing_endpoint = endpoint_path + '/_/resource_list.json' add_resource_func( ResourceLister, resource_listing_endpoint, endpoint='app/resourcelister' if not is_blueprint else None, ) st = StorageSingleton() st.api_spec_static = endpoint_path + '/_/static/' add_resource_func( # TODO: why static path is like this? StaticFiles, st.api_spec_static + '<string:dir1>/<string:dir2>/<string:dir3>', st.api_spec_static + '<string:dir1>/<string:dir2>', st.api_spec_static + '<string:dir1>', endpoint='app/staticfiles' if not is_blueprint else None, ) registry = StorageSingleton().registry if api.blueprint and not registry.get(api.blueprint.name): # Most of all this can be taken from the blueprint/app register_action(api.blueprint.name, True) elif 'app' not in registry: # review: reuse previous code? register_action('app', False)
def get_current_registry(api=None): registry = StorageSingleton().registry overrides = {} if api: app_name = api.blueprint.name if api.blueprint else None else: app_name = request.blueprint urlparts = urlparse.urlparse(request.url_root.rstrip('/')) proto = request.headers.get("x-forwarded-proto") or urlparts[0] overrides = { 'basePath': urlparse.urlunparse([proto] + list(urlparts[1:])) } if not app_name: app_name = 'app' overrides['models'] = registry.get('models', {}) reg = registry.setdefault(app_name, {}) reg.update(overrides) reg['basePath'] = reg['basePath'] + (reg.get('x-api-prefix', '') or '') return reg
def render_page(page, info): from flask_restful_swagger.registry import get_current_registry req_registry = get_current_registry() url = req_registry['basePath'] if url.endswith('/'): url = url.rstrip('/') st = StorageSingleton() templates = st.templates conf = { 'base_url': url + st.api_spec_static, 'full_base_url': url + st.api_spec_static } if info is not None: conf.update(info) if page in templates: template = templates[page] else: with open(os.path.join(root_path, 'static', page), 'r') as fs: template = Template(fs.read()) templates[page] = template mime = mimetypes.guess_type(page)[0] return Response(template.render(conf), mimetype=mime)
def register_action(name, is_blueprint=True): resource_listing_endpoint = StorageSingleton( ).resource_listing_endpoint registry[name] = { 'apiVersion': api_version, 'swaggerVersion': swagger_version, 'basePath': base_path, 'spec_endpoint_path': endpoint_path, 'resourcePath': resource_path, 'produces': produces, 'description': description, } if is_blueprint: registry[name].update({ 'x-api-prefix': '', 'apis': [], }) api.blueprint.record(registering_blueprint) add_resource_func( SwaggerRegistry, endpoint_path, endpoint_path + '.json', endpoint_path + '.html', endpoint='app/registry' if not is_blueprint else None, ) resource_listing_endpoint = endpoint_path + '/_/resource_list.json' add_resource_func( ResourceLister, resource_listing_endpoint, endpoint='app/resourcelister' if not is_blueprint else None, ) st = StorageSingleton() st.api_spec_static = endpoint_path + '/_/static/' add_resource_func( # TODO: why static path is like this? StaticFiles, st.api_spec_static + '<string:dir1>/<string:dir2>/<string:dir3>', st.api_spec_static + '<string:dir1>/<string:dir2>', st.api_spec_static + '<string:dir1>', endpoint='app/staticfiles' if not is_blueprint else None, )
def register_action(name, is_blueprint=True): resource_listing_endpoint = StorageSingleton().resource_listing_endpoint registry[name] = { 'apiVersion': api_version, 'swaggerVersion': swagger_version, 'basePath': base_path, 'spec_endpoint_path': endpoint_path, 'resourcePath': resource_path, 'produces': produces, 'description': description, } if is_blueprint: registry[name].update({ 'x-api-prefix': '', 'apis': [], }) api.blueprint.record(registering_blueprint) add_resource_func( SwaggerRegistry, endpoint_path, endpoint_path + '.json', endpoint_path + '.html', endpoint='app/registry' if not is_blueprint else None, ) resource_listing_endpoint = endpoint_path + '/_/resource_list.json' add_resource_func( ResourceLister, resource_listing_endpoint, endpoint='app/resourcelister' if not is_blueprint else None, ) st = StorageSingleton() st.api_spec_static = endpoint_path + '/_/static/' add_resource_func( # TODO: why static path is like this? StaticFiles, st.api_spec_static + '<string:dir1>/<string:dir2>/<string:dir3>', st.api_spec_static + '<string:dir1>/<string:dir2>', st.api_spec_static + '<string:dir1>', endpoint='app/staticfiles' if not is_blueprint else None, )
def get_current_registry(api=None): registry = StorageSingleton().registry overrides = {} if api: app_name = api.blueprint.name if api.blueprint else None else: app_name = request.blueprint urlparts = urlparse.urlparse(request.url_root.rstrip('/')) proto = request.headers.get("x-forwarded-proto") or urlparts[0] overrides = {'basePath': urlparse.urlunparse([proto] + list(urlparts[1:]))} if not app_name: app_name = 'app' overrides['models'] = registry.get('models', {}) reg = registry.setdefault(app_name, {}) reg.update(overrides) reg['basePath'] = reg['basePath'] + (reg.get('x-api-prefix', '') or '') return reg
def register_once(api, add_resource_func, api_version, swagger_version, base_path, resource_path, produces, endpoint_path, description): def registering_blueprint(setup_state): reg = registry[setup_state.blueprint.name] reg['x-api-prefix'] = setup_state.url_prefix def register_action(name, is_blueprint=True): resource_listing_endpoint = StorageSingleton().resource_listing_endpoint registry[name] = { 'apiVersion': api_version, 'swaggerVersion': swagger_version, 'basePath': base_path, 'spec_endpoint_path': endpoint_path, 'resourcePath': resource_path, 'produces': produces, 'description': description, } if is_blueprint: registry[name].update({ 'x-api-prefix': '', 'apis': [], }) api.blueprint.record(registering_blueprint) add_resource_func( SwaggerRegistry, endpoint_path, endpoint_path + '.json', endpoint_path + '.html', endpoint='app/registry' if not is_blueprint else None, ) resource_listing_endpoint = endpoint_path + '/_/resource_list.json' add_resource_func( ResourceLister, resource_listing_endpoint, endpoint='app/resourcelister' if not is_blueprint else None, ) st = StorageSingleton() st.api_spec_static = endpoint_path + '/_/static/' add_resource_func( # TODO: why static path is like this? StaticFiles, st.api_spec_static + '<string:dir1>/<string:dir2>/<string:dir3>', st.api_spec_static + '<string:dir1>/<string:dir2>', st.api_spec_static + '<string:dir1>', endpoint='app/staticfiles' if not is_blueprint else None, ) registry = StorageSingleton().registry if api.blueprint and not registry.get(api.blueprint.name): # Most of all this can be taken from the blueprint/app register_action(api.blueprint.name, True) elif 'app' not in registry: # review: reuse previous code? register_action('app', False)
def add_model(model_class): models = StorageSingleton().registry['models'] name = model_class.__name__ model = models[name] = {'id': name} model['description'], model['notes'] = _parse_doc(model_class) if 'resource_fields' in dir(model_class): # We take special care when the model class # has a field resource_fields. # By convention this field specifies what flask-restful # would return when this model is used as a return # value from an HTTP endpoint. # We look at the class and search for an attribute named # resource_fields. # If that attribute exists then we deduce the swagger model # by the content of this attribute if hasattr(model_class, 'required'): model['required'] = model_class.required properties = model['properties'] = {} is_nested = isinstance(model_class, _Nested) nested = model_class.nested() if is_nested else {} for name, _type in six.iteritems(model_class.resource_fields): nested_type = nested[name] if name in nested else None properties[name] = deduce_swagger_type(_type, nested_type) elif '__init__' in dir(model_class): # Alternatively, if a resource_fields does not exist, # we deduce the model # fields from the parameters sent to its __init__ method # Credits for this snippet go to Robin Walsh # https://github.com/hobbeswalsh/flask-sillywalk argspec = inspect.getargspec(model_class.__init__) argspec.args.remove('self') defaults = {} required = model['required'] = [] if argspec.defaults: defaults = list( zip(argspec.args[-len(argspec.defaults):], argspec.defaults)) properties = model['properties'] = {} required_args_count = len(argspec.args) - len(defaults) for arg in argspec.args[:required_args_count]: required.append(arg) # type: string for lack of better knowledge, # until we add more metadata properties[arg] = {'type': 'string'} for k, v in defaults: properties[k] = {'type': 'string', 'default': v} if 'swagger_metadata' in dir(model_class): for field_name, field_metadata in model_class.swagger_metadata.items(): # does not work for Python 3.x; see: SO # how-can-i-merge-two-python-dictionaries-in-a-single-expression # properties[field_name] = dict( # properties[field_name].items() + field_metadata.items() # ) if field_name in properties: properties[field_name].update(field_metadata)