示例#1
0
def generate(package):
    doc = []
    with mock_import.mock_import([package]):
        for resource_class, parents in packages.iter_resource_classes(package):
            resource_path = common.url_join(
                *([parent.path for parent in parents] + [resource_class.path()]))
            for route in resource_class.iter_route_methods():
                arguments = []
                for name, arg in six.iteritems(route.spec.args_info):
                    argument = {
                        'name': route.keyword_map.get(name, name),
                        'type': arg.type_name,
                        'doc': arg.doc,
                    }
                    if isinstance(arg, (_args.KeywordArg, _args.OptionalArg)):
                        argument['default'] = arg.default
                    arguments.append(argument)

                doc.append({
                    'name': route.__name__,
                    'arguments': arguments,
                    'method': route.method,
                    'path': common.url_join(resource_path, route.path),
                    'success_status': route.success_code,
                    'doc': route.spec.doc,
                    'cli_command': _build_cli_command(parents, resource_class, route)
                })
    return doc
示例#2
0
文件: proxy.py 项目: l-grebe/hammock
def proxy(req, dest, redirection_url=None):
    redirection_url = common.url_join(
        dest, req.relative_uri) if redirection_url is None else redirection_url
    LOG.debug('[Proxy %s] to %s', req.uid, redirection_url)
    inner_request = requests.Request(
        req.method,
        url=redirection_url,
        data=req.content
        if req.method not in common.URL_PARAMS_METHODS else None,
        headers={
            k: v if k.lower() != "host" else
            six.moves.urllib.parse.urlparse(dest).netloc
            for k, v in six.iteritems(req.headers) if v != ""
        },
    )
    session = requests.Session()
    try:
        prepared = session.prepare_request(inner_request)
        if req.headers.get(common.CONTENT_LENGTH):
            prepared.headers[common.CONTENT_LENGTH] = req.headers.get(
                common.CONTENT_LENGTH)
        if prepared.headers.get('TRANSFER-ENCODING'):
            del prepared.headers['TRANSFER-ENCODING']
        inner_response = session.send(prepared, stream=True)
        return response.Response(inner_response.raw, inner_response.headers,
                                 inner_response.status_code)
    finally:
        session.close()
示例#3
0
 def _add_sink_methods(self, resource, base_path):
     """Add sink methods of a resource.
     :param resource: a Resource class
     :param base_path: path of resource mounting
     """
     for sink_path, responder in resource.sinks:
         path = '/' + common.url_join(base_path, sink_path)
         self.add_sink(path, responder)
示例#4
0
 def _add_route_methods(self, resource, base_path):
     """Add route methods of a resource
     :param resource: a Resource class
     :param base_path: path of resource mounting
     """
     for route_path, methods_map in six.iteritems(resource.routes):
         path = '/' + common.url_join(base_path, route_path)
         self.add_route(path, methods_map)
示例#5
0
 def _add_sink_methods(self, resource, base_path):
     """Add sink methods of a resource.
     :param resource: a Resource class
     :param base_path: path of resource mounting
     """
     for sink_path, responder in resource.sinks:
         path = '/' + common.url_join(base_path, sink_path)
         self.add_sink(path, responder)
示例#6
0
 def _add_route_methods(self, resource, base_path):
     """Add route methods of a resource
     :param resource: a Resource class
     :param base_path: path of resource mounting
     """
     for route_path, methods_map in six.iteritems(resource.routes):
         path = '/' + common.url_join(base_path, route_path)
         self.add_route(path, methods_map)
示例#7
0
def generate(package):
    doc = []
    with mock_import.mock_import([package]):
        for resource_class, parents in packages.iter_resource_classes(package):
            resource_path = common.url_join(
                *([parent.path
                   for parent in parents] + [resource_class.path()]))
            for route in resource_class.iter_route_methods():
                arguments = []
                for name, arg in six.iteritems(route.spec.args_info):
                    argument = {
                        'name': route.keyword_map.get(name, name),
                        'type': arg.type_name,
                        'doc': arg.doc,
                    }
                    if isinstance(arg, (_args.KeywordArg, _args.OptionalArg)):
                        argument['default'] = arg.default
                    arguments.append(argument)

                doc.append({
                    'name':
                    route.__name__,
                    'arguments':
                    arguments,
                    'method':
                    route.method,
                    'path':
                    common.url_join(resource_path, route.path),
                    'success_status':
                    route.success_code,
                    'doc':
                    route.spec.doc,
                    'cli_command':
                    _build_cli_command(parents, resource_class, route)
                })
    return doc
示例#8
0
 def routes(self):
     """
     :return: A dict representing routes in a resource: { url: {method: responder} }
     """
     routes = collections.defaultdict(dict)
     errors = []
     for route_method in self.iter_route_methods():
         try:
             route_method.set_resource(self)
             routes[common.url_join(self.path(), route_method.path)][route_method.method] = route_method.call
         except exceptions.BadResourceDefinition as exc:
             errors.append(exc)
     if errors:
         for error in errors:
             logging.error(error)
         raise exceptions.BadResourceDefinition('Bad definition of resource, see log for errors.')
     return routes
示例#9
0
 def routes(self):
     """
     :return: A dict representing routes in a resource: { url: {method: responder} }
     """
     routes = collections.defaultdict(dict)
     errors = []
     for route_method in self.iter_route_methods():
         try:
             route_method.set_resource(self)
             routes[common.url_join(self.path(), route_method.path)][route_method.method] = route_method.call
         except exceptions.BadResourceDefinition as exc:
             errors.append(exc)
     if errors:
         for error in errors:
             logging.error(error)
         raise exceptions.BadResourceDefinition('Bad definition of resource, see log for errors.')
     return routes
示例#10
0
 def sinks(self):
     """
     :return: A list representing sinks in a resource: ( url, responder )
         The list is sorted by url size, largest first.
     """
     sinks = []
     errors = []
     for sink_method in self.iter_sink_methods():
         try:
             sink_method.set_resource(self)
             sinks.append((common.url_join(self.path(), sink_method.path), sink_method.call))
         except exceptions.BadResourceDefinition as exc:
             errors.append(exc)
     if errors:
         for error in errors:
             logging.error(error)
         raise exceptions.BadResourceDefinition('Bad definition of resource, see log for errors.')
     return sinks
示例#11
0
 def sinks(self):
     """
     :return: A list representing sinks in a resource: ( url, responder )
         The list is sorted by url size, largest first.
     """
     sinks = []
     errors = []
     for sink_method in self.iter_sink_methods():
         try:
             sink_method.set_resource(self)
             sinks.append((common.url_join(self.path(), sink_method.path), sink_method.call))
         except exceptions.BadResourceDefinition as exc:
             errors.append(exc)
     if errors:
         for error in errors:
             logging.error(error)
         raise exceptions.BadResourceDefinition('Bad definition of resource, see log for errors.')
     return sinks
示例#12
0
def generate_swagger(package):
    doc = OrderedDict(
        swagger='2.0',
        info={
            'title': package,
            'version': '1.0.0',
        }
    )
    paths = defaultdict(dict)
    definitions = {}
    with mock_import.mock_import([package]):
        for resource_class, parents in packages.iter_resource_classes(package):
            resource_path = common.url_join(*([parent.path for parent in parents] + [resource_class.path()]))
            for route in resource_class.iter_route_methods():
                path = '/' + common.url_join(resource_path, route.path)
                path_vars = PATH_VARIABLE.findall(path)
                method = route.method.lower()

                # classify params by source: path, query or body
                params = defaultdict(dict)
                for name, arg in six.iteritems(route.spec.args_info):
                    if name.startswith('_'):
                        continue
                    if name in path_vars:
                        params['path'][name] = arg
                    elif method in ['get']:
                        params['query'][name] = arg
                    elif method in ['post', 'put', 'patch']:
                        params['body'][name] = arg

                parameters = []
                # add all path params
                for name, arg in six.iteritems(params['path']):
                    parameters.append(_generate_param_dict(route, name, arg, 'path', True))

                # add all query params
                for name, arg in six.iteritems(params['query']):
                    required = not isinstance(arg, (_args.KeywordArg, _args.OptionalArg))
                    parameters.append(_generate_param_dict(route, name, arg, 'query', required))

                # add body param if needed
                properties = {}
                required = []
                for name, arg in six.iteritems(params['body']):
                    prop_name = route.keyword_map.get(name, name)
                    properties[prop_name] = {
                        'type': SWAGGER_TYPES.get(arg.type_name, "string"),
                        'description': arg.doc or "",
                    }
                    if not isinstance(arg, (_args.KeywordArg, _args.OptionalArg)):
                        required.append(prop_name)

                operation_id = _build_operation_id(parents, resource_class, route)
                if len(properties) > 0:
                    param_name = operation_id + '_object'
                    param = {
                        'name': param_name,
                        'in': 'body',
                        'schema': {
                            '$ref': '#/definitions/' + param_name,
                        }
                    }
                    parameters.append(param)
                    definitions[param_name] = dict(type='object', properties=properties)
                    if len(required) > 1:
                        definitions[param_name]['required'] = required

                operation = {
                    'description': route.spec.doc or '',
                    'parameters': parameters,
                    'responses': {
                        route.success_code: {
                            'description': 'default response'
                        }
                    }
                }
                paths[path][method] = operation
    doc['paths'] = paths
    doc['definitions'] = definitions
    return doc