コード例 #1
0
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError as err:
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])
            api_server.start(api_host, api_port)

            print(
                'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                'See the Raiden documentation for all available endpoints at\n'
                'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.
                format(
                    api_host,
                    api_port,
                ))

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
        gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

        event.wait()
        print('Signal received. Shutting down ...')
        if api_server:
            api_server.stop()

        return app_
コード例 #2
0
def api_backend(raiden_network, rest_api_port_number):
    raiden_api = RaidenAPI(raiden_network[0].raiden)
    rest_api = RestAPI(raiden_api)
    api_server = APIServer(rest_api)
    api_server.flask_app.config['SERVER_NAME'] = 'localhost:{}'.format(
        rest_api_port_number)
    api_server.start(port=rest_api_port_number)

    # Fixes flaky test, were requests are done prior to the server initializing
    # the listening socket.
    # https://github.com/raiden-network/raiden/issues/389#issuecomment-305551563
    wait_for_listening_port(rest_api_port_number)

    yield api_server, rest_api

    api_server.stop(timeout=10)
コード例 #3
0
def run(ctx, **kwargs):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    if ctx.invoked_subcommand is None:
        print('Welcome to Raiden, version {}!'.format(
            get_system_spec()['raiden']))
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        slogging.configure(kwargs['logging'],
                           log_json=kwargs['log_json'],
                           log_file=kwargs['logfile'])
        if kwargs['logfile']:
            # Disable stream logging
            root = slogging.getLogger()
            for handler in root.handlers:
                if isinstance(handler, slogging.logging.StreamHandler):
                    root.handlers.remove(handler)
                    break

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with SocketFactory(listen_host,
                               listen_port,
                               strategy=kwargs['nat']) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                        eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
                    )
                    (api_host,
                     api_port) = split_endpoint(kwargs['api_address'])
                    api_server.start(api_host, api_port)

                    print(
                        'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                        'See the Raiden documentation for all available endpoints at\n'
                        'http://raiden-network.readthedocs.io/en/stable/rest_api.html'
                        .format(
                            api_host,
                            api_port,
                        ))

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()
                print('Signal received. Shutting down ...')
                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print(
                    'ERROR: Address %s:%s is in use. '
                    'Use --listen-address <host:port> to specify port to listen on.'
                    % (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
コード例 #4
0
def run(ctx, **kwargs):
    if ctx.invoked_subcommand is None:
        from raiden.api.python import RaidenAPI
        from raiden.ui.console import Console

        slogging.configure(
            kwargs['logging'],
            log_json=kwargs['log_json'],
            log_file=kwargs['logfile']
        )

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with socket_factory(listen_host, listen_port) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                    )
                    (api_host, api_port) = split_endpoint(kwargs["api_address"])
                    api_server.start(api_host, api_port)

                    print(
                        "The Raiden API RPC server is now running at http://{}:{}/.\n\n"
                        "See the Raiden documentation for all available endpoints at\n"
                        "https://github.com/raiden-network/raiden/blob/master"
                        "/docs/Rest-Api.rst".format(
                            api_host,
                            api_port,
                        )
                    )

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()

                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print("ERROR: Address %s:%s is in use. "
                      "Use --listen-address <host:port> to specify port to listen on." %
                      (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
コード例 #5
0
    def _run_app(self):
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = run_app(**self._options)
        except EthNodeCommunicationError:
            print(
                '\n'
                'Could not contact the ethereum node through JSON-RPC.\n'
                'Please make sure that JSON-RPC is enabled for these interfaces:\n'
                '\n'
                '    eth_*, net_*, web3_*\n'
                '\n'
                'geth: https://github.com/ethereum/go-ethereum/wiki/Management-APIs\n',
            )
            sys.exit(1)

        domain_list = []
        if self._options['rpccorsdomain']:
            if ',' in self._options['rpccorsdomain']:
                for domain in self._options['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(self._options['rpccorsdomain']))

        self._raiden_api = RaidenAPI(app_.raiden)

        api_server = None
        if self._options['rpc']:
            rest_api = RestAPI(self._raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=self._options['web_ui'],
                eth_rpc_endpoint=self._options['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(self._options['api_address'])

            try:
                api_server.start(api_host, api_port)
            except APIServerPortInUseError:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.'
                    % (api_host, api_port), )
                sys.exit(1)

            print(
                'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                'See the Raiden documentation for all available endpoints at\n'
                'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.
                format(
                    api_host,
                    api_port,
                ), )

        if self._options['console']:
            console = Console(app_)
            console.start()

        # spawn a greenlet to handle the version checking
        gevent.spawn(check_version)
        # spawn a greenlet to handle the gas reserve check
        gevent.spawn(check_gas_reserve, app_.raiden)

        self._startup_hook()

        # wait for interrupt
        event = RaidenGreenletEvent()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
        except Exception as ex:
            with NamedTemporaryFile(
                    'w',
                    prefix=
                    f'raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}',
                    suffix='.txt',
                    delete=False,
            ) as traceback_file:
                traceback.print_exc(file=traceback_file)
                click.secho(
                    f'FATAL: An unexpected exception occured. '
                    f'A traceback has been written to {traceback_file.name}\n'
                    f'{ex}',
                    fg='red',
                )
        finally:
            self._shutdown_hook()
            if api_server:
                api_server.stop()

        return app_
コード例 #6
0
ファイル: cli.py プロジェクト: AlphaX-IBS/raiden
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError:
            print(
                '\n'
                'Could not contact the ethereum node through JSON-RPC.\n'
                'Please make sure that JSON-RPC is enabled for these interfaces:\n'
                '\n'
                '    eth_*, net_*, web3_*\n'
                '\n'
                'geth: https://github.com/ethereum/go-ethereum/wiki/Management-APIs\n',
            )
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])

            try:
                api_server.start(api_host, api_port)
            except APIServerPortInUseError:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.' %
                    (api_host, api_port),
                )
                sys.exit(1)

            print(
                'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                'See the Raiden documentation for all available endpoints at\n'
                'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.format(
                    api_host,
                    api_port,
                ),
            )

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # spawning a thread to handle the version checking
        gevent.spawn(check_version)

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
        except Exception as ex:
            with NamedTemporaryFile(
                'w',
                prefix='raiden-exception',
                suffix='.txt',
                delete=False,
            ) as traceback_file:
                traceback.print_exc(file=traceback_file)
                click.secho(
                    f'FATAL: An unexpected exception occured.'
                    f'A traceback has been written to {traceback_file.name}\n'
                    f'{ex}',
                    fg='red',
                )

        if api_server:
            api_server.stop()

        return app_
コード例 #7
0
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError:
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])

            try:
                api_server.start(api_host, api_port)
            except APIServerPortInUseError:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.' %
                    (api_host, api_port),
                )
                sys.exit(1)

            print(
                'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                'See the Raiden documentation for all available endpoints at\n'
                'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.format(
                    api_host,
                    api_port,
                ),
            )

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # spawning a thread to handle the version checking
        gevent.spawn(check_version)

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
        except Exception as ex:
            with NamedTemporaryFile(
                'w',
                prefix='raiden-exception',
                suffix='.txt',
                delete=False,
            ) as traceback_file:
                traceback.print_exc(file=traceback_file)
                click.secho(
                    f'FATAL: An unexpected exception occured.'
                    f'A traceback has been written to {traceback_file.name}\n'
                    f'{ex}',
                    fg='red',
                )

        if api_server:
            api_server.stop()

        return app_
コード例 #8
0
ファイル: smoketest.py プロジェクト: christianbrb/raiden
def run_smoketest(
    print_step: Callable,
    args: Dict[str, Any],
    contract_addresses: Dict[str, Address],
    token: ContractProxy,
):
    print_step("Starting Raiden")

    app = None
    api_server = None
    try:
        app = run_app(**args)
        raiden_api = RaidenAPI(app.raiden)
        rest_api = RestAPI(raiden_api)
        (api_host, api_port) = split_endpoint(args["api_address"])
        api_server = APIServer(rest_api, config={"host": api_host, "port": api_port})
        api_server.start()

        block = BlockNumber(app.raiden.get_block_number() + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)
        # Proxies now use the confirmed block hash to query the chain for
        # prerequisite checks. Wait a bit here to make sure that the confirmed
        # block hash contains the deployed token network or else things break
        wait_for_block(raiden=app.raiden, block_number=block, retry_timeout=1.0)

        raiden_api.channel_open(
            registry_address=TokenNetworkRegistryAddress(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY]
            ),
            token_address=TokenAddress(to_canonical_address(token.contract.address)),
            partner_address=ConnectionManager.BOOTSTRAP_ADDR,
        )
        raiden_api.set_total_channel_deposit(
            registry_address=TokenNetworkRegistryAddress(
                contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY]
            ),
            token_address=TokenAddress(to_canonical_address(token.contract.address)),
            partner_address=ConnectionManager.BOOTSTRAP_ADDR,
            total_deposit=TEST_DEPOSIT_AMOUNT,
        )
        token_addresses = [to_checksum_address(token.contract.address)]

        print_step("Running smoketest")

        raiden_service = app.raiden
        token_network_added_events = raiden_service.default_registry.filter_token_added_events()
        events_token_addresses = [
            event["args"]["token_address"] for event in token_network_added_events
        ]

        assert events_token_addresses == token_addresses

        token_networks = views.get_token_identifiers(
            views.state_from_raiden(raiden_service), raiden_service.default_registry.address
        )
        assert len(token_networks) == 1

        channel_state = views.get_channelstate_for(
            chain_state=views.state_from_raiden(raiden_service),
            token_network_registry_address=raiden_service.default_registry.address,
            token_address=token_networks[0],
            partner_address=ConnectionManager.BOOTSTRAP_ADDR,
        )
        assert channel_state

        distributable = channel.get_distributable(
            channel_state.our_state, channel_state.partner_state
        )
        assert distributable == TEST_DEPOSIT_AMOUNT
        assert distributable == channel_state.our_state.contract_balance
        assert channel.get_status(channel_state) == ChannelState.STATE_OPENED

        port_number = raiden_service.config.api_port
        response = requests.get(f"http://localhost:{port_number}/api/v1/channels")

        assert response.status_code == HTTPStatus.OK

        response_json = json.loads(response.content)
        assert response_json[0]["partner_address"] == to_checksum_address(
            ConnectionManager.BOOTSTRAP_ADDR
        )
        assert response_json[0]["state"] == "opened"
        assert int(response_json[0]["balance"]) > 0
    finally:
        if api_server is not None:
            api_server.stop()
            api_server.greenlet.get()

        if app is not None:
            app.stop()
            app.raiden.greenlet.get()
コード例 #9
0
def run(ctx, **kwargs):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    if ctx.invoked_subcommand is None:
        print('Welcome to Raiden, version {}!'.format(get_system_spec()['raiden']))
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        slogging.configure(
            kwargs['logging'],
            log_json=kwargs['log_json'],
            log_file=kwargs['logfile']
        )
        if kwargs['logfile']:
            # Disable stream logging
            root = slogging.getLogger()
            for handler in root.handlers:
                if isinstance(handler, slogging.logging.StreamHandler):
                    root.handlers.remove(handler)
                    break

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with SocketFactory(listen_host, listen_port, strategy=kwargs['nat']) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                        eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
                    )
                    (api_host, api_port) = split_endpoint(kwargs['api_address'])
                    api_server.start(api_host, api_port)

                    print(
                        'The Raiden API RPC server is now running at http://{}:{}/.\n\n'
                        'See the Raiden documentation for all available endpoints at\n'
                        'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.format(
                            api_host,
                            api_port,
                        )
                    )

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()
                print('Signal received. Shutting down ...')
                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print('ERROR: Address %s:%s is in use. '
                      'Use --listen-address <host:port> to specify port to listen on.' %
                      (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
コード例 #10
0
ファイル: cli.py プロジェクト: abstractpoint/raiden
def run(ctx, **kwargs):
    if ctx.invoked_subcommand is None:
        from raiden.api.python import RaidenAPI
        from raiden.ui.console import Console

        slogging.configure(kwargs['logging'], log_file=kwargs['logfile'])

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        with socket_factory(listen_host, listen_port) as mapped_socket:
            kwargs['mapped_socket'] = mapped_socket

            app_ = ctx.invoke(app, **kwargs)

            domain_list = []
            if kwargs['rpccorsdomain']:
                if ',' in kwargs['rpccorsdomain']:
                    for domain in kwargs['rpccorsdomain'].split(','):
                        domain_list.append(str(domain))
                else:
                    domain_list.append(str(kwargs['rpccorsdomain']))

            if ctx.params['rpc']:
                raiden_api = RaidenAPI(app_.raiden)
                rest_api = RestAPI(raiden_api)
                api_server = APIServer(
                    rest_api,
                    cors_domain_list=domain_list,
                    web_ui=ctx.params['web_ui'],
                    eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
                )
                (api_host, api_port) = split_endpoint(kwargs["api_address"])
                api_server.start(api_host, api_port)

                print(
                    "The Raiden API RPC server is now running at http://{}:{}/.\n\n"
                    "See the Raiden documentation for all available endpoints at\n"
                    "https://github.com/raiden-network/raiden/blob/master"
                    "/docs/Rest-Api.rst".format(
                        api_host,
                        api_port,
                    ))

            if ctx.params['console']:
                console = Console(app_)
                console.start()

            # wait for interrupt
            event = gevent.event.Event()
            gevent.signal(signal.SIGQUIT, event.set)
            gevent.signal(signal.SIGTERM, event.set)
            gevent.signal(signal.SIGINT, event.set)
            event.wait()

            try:
                api_server.stop()
            except NameError:
                pass
        app_.stop(leave_channels=False)