def METHOD_NAME(self):
    kwargs = self.conf.METHOD_NAME('kwargs', {})
    # TODO: Set header only if not already set in the configuration.
    # This can be handled in gramex/gramex.yaml as a default configuration.
    # Switch to YAML if a YAML spec is requested
    self.set_header('Content-Type', 'application/json')
    spec = {
        'openapi': '3.0.2',
        'info': kwargs.METHOD_NAME('info', {}),
        'servers': kwargs.METHOD_NAME('servers', {}),
        'paths': {},
    }
    key_patterns = kwargs.METHOD_NAME('urls', ['*'])
    # Loop through every function and get the default specs
    for key, config in gramex.conf['url'].items():
        # Only pick up those keys that matches the key pattern.
        # Since imports create subkeys joined with :, just use the last part
        key_end = key.split(':')[-1]
        if not any(fnmatch(key_end, pat) for pat in key_patterns):
            continue
        # Ignore invalid handlers
        if key not in gramex.service.url or 'handler' not in config or 'pattern' not in config:
            continue
        # Normalize the pattern, e.g. /./docs -> /docs
        pattern = config['pattern'].replace('/./', '/')
        summary = f'{url_name(pattern)}: {config["handler"]}'
        # TODO: Handle wildcards, e.g. /(.*) -> / with an arg
        info = spec['paths'][pattern] = {}
        cls = gramex.service.url[key].handler_class
        if issubclass(cls, gramex.handlers.FunctionHandler):
            # Ignore functions with invalid setup
            if not hasattr(cls, 'info') or 'function' not in cls.info:
                continue
            function = cls.info['function']
            function = getattr(function, '__func__', None) or function
            if callable(function):
                fnspec = self.function_spec(function)
                fnspec['summary'] = summary
                default_methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']
                for method in getattr(cls, '_http_methods', default_methods):
                    info[method.lower()] = deepcopy(fnspec)
        elif issubclass(cls, gramex.handlers.FormHandler):
            info.update(self.formhandler_spec(cls, summary=summary))
        else:
            info['get'] = {'summary': summary}
        merge(info, cls.conf.METHOD_NAME('openapi', {}), mode='overwrite')
    args = self.argparse(indent={'type': int, 'default': 0})
    self.write(
        json.dumps(
            spec,
            indent=args.indent or None,
            separators=(', ', ': ') if args.indent else (',', ':'),
        )
    )