async def test_gateway_request_timeout_pad_option( jp_configurable_serverapp, monkeypatch, request_timeout, kernel_launch_timeout, expected_request_timeout, expected_kernel_launch_timeout, ): argv = [ f"--GatewayClient.request_timeout={request_timeout}", "--GatewayClient.launch_timeout_pad=5", ] GatewayClient.clear_instance() app = jp_configurable_serverapp(argv=argv) monkeypatch.setattr(GatewayClient, "KERNEL_LAUNCH_TIMEOUT", kernel_launch_timeout) GatewayClient.instance().init_static_args() assert app.gateway_config.request_timeout == expected_request_timeout assert GatewayClient.instance( ).KERNEL_LAUNCH_TIMEOUT == expected_kernel_launch_timeout GatewayClient.clear_instance()
async def test_gateway_env_options(init_gateway, jp_serverapp): assert jp_serverapp.gateway_config.gateway_enabled is True assert jp_serverapp.gateway_config.url == mock_gateway_url assert jp_serverapp.gateway_config.http_user == mock_http_user assert jp_serverapp.gateway_config.connect_timeout == jp_serverapp.gateway_config.request_timeout assert jp_serverapp.gateway_config.connect_timeout == 44.4 GatewayClient.instance().init_static_args() assert GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == int(jp_serverapp.gateway_config.request_timeout)
async def start_kernel(self, **kwargs): """Starts a kernel via HTTP in an asynchronous manner. Parameters ---------- `**kwargs` : optional keyword arguments that are passed down to build the kernel_cmd and launching the kernel (e.g. Popen kwargs). """ kernel_id = kwargs.get('kernel_id') if kernel_id is None: kernel_name = kwargs.get('kernel_name', 'python3') kernel_url = self._get_kernel_endpoint_url() self.log.debug("Request new kernel at: %s" % kernel_url) # Let KERNEL_USERNAME take precedent over http_user config option. if os.environ.get('KERNEL_USERNAME' ) is None and GatewayClient.instance().http_user: os.environ['KERNEL_USERNAME'] = GatewayClient.instance( ).http_user kernel_env = { k: v for (k, v) in dict(os.environ).items() if k.startswith('KERNEL_') or k in GatewayClient.instance().env_whitelist.split(",") } # Add any env entries in this request kernel_env.update(kwargs.get('env')) # Convey the full path to where this notebook file is located. if kwargs.get('cwd') is not None and kernel_env.get( 'KERNEL_WORKING_DIR') is None: kernel_env['KERNEL_WORKING_DIR'] = kwargs['cwd'] json_body = json_encode({'name': kernel_name, 'env': kernel_env}) response = await gateway_request(kernel_url, method='POST', body=json_body) self.kernel = json_decode(response.body) self.kernel_id = self.kernel['id'] self.log.info( "HTTPKernelManager started kernel: {}, args: {}".format( self.kernel_id, kwargs)) else: self.kernel = await self.get_kernel(kernel_id) self.kernel_id = self.kernel['id'] self.log.info("HTTPKernelManager using existing kernel: {}".format( self.kernel_id))
async def test_gateway_cli_options(jp_configurable_serverapp): argv = [ '--gateway-url=' + mock_gateway_url, '--GatewayClient.http_user='******'--GatewayClient.connect_timeout=44.4', '--GatewayClient.request_timeout=96.0' ] GatewayClient.clear_instance() app = jp_configurable_serverapp(argv=argv) assert app.gateway_config.gateway_enabled is True assert app.gateway_config.url == mock_gateway_url assert app.gateway_config.http_user == mock_http_user assert app.gateway_config.connect_timeout == 44.4 assert app.gateway_config.request_timeout == 96.0 GatewayClient.instance().init_static_args() assert GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == 96 # Ensure KLT gets set from request-timeout GatewayClient.clear_instance()
async def start_channels(self, shell=True, iopub=True, stdin=True, hb=True, control=True): """Starts the channels for this kernel. For this class, we establish a websocket connection to the destination and setup the channel-based queues on which applicable messages will be posted. """ ws_url = url_path_join(GatewayClient.instance().ws_url, GatewayClient.instance().kernels_endpoint, url_escape(self.kernel_id), 'channels') # Gather cert info in case where ssl is desired... ssl_options = dict() ssl_options['ca_certs'] = GatewayClient.instance().ca_certs ssl_options['certfile'] = GatewayClient.instance().client_cert ssl_options['keyfile'] = GatewayClient.instance().client_key self.channel_socket = websocket.create_connection( ws_url, timeout=GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT, enable_multithread=True, sslopt=ssl_options) self.response_router = Thread(target=self._route_responses) self.response_router.start() await ensure_async(super().start_channels(shell=shell, iopub=iopub, stdin=stdin, hb=hb, control=control))
async def test_gateway_cli_options(jp_configurable_serverapp): argv = [ "--gateway-url=" + mock_gateway_url, "--GatewayClient.http_user="******"--GatewayClient.connect_timeout=44.4", "--GatewayClient.request_timeout=96.0", "--GatewayClient.launch_timeout_pad=5.1", ] GatewayClient.clear_instance() app = jp_configurable_serverapp(argv=argv) assert app.gateway_config.gateway_enabled is True assert app.gateway_config.url == mock_gateway_url assert app.gateway_config.http_user == mock_http_user assert app.gateway_config.connect_timeout == 44.4 assert app.gateway_config.request_timeout == 96.0 assert app.gateway_config.launch_timeout_pad == 5.1 GatewayClient.instance().init_static_args() assert (GatewayClient.instance().KERNEL_LAUNCH_TIMEOUT == 90 ) # Ensure KLT gets set from request-timeout - launch_timeout_pad GatewayClient.clear_instance()
def process(self, operation: Operation): filepath = self.get_valid_filepath(operation.filename) file_dir = os.path.dirname(filepath) file_name = os.path.basename(filepath) self.log.debug(f'Processing notebook: {filepath}') # We'll always use the ElyraEngine. This engine is essentially the default Papermill engine # but allows for environment variables to be passed to the kernel process (via 'kernel_env'). # If the current notebook server is running with Enterprise Gateway configured, we will also # point the 'kernel_manager_class' to our HTTPKernelManager so that notebooks run as they # would outside of Elyra. Current working directory (cwd) is specified both for where papermill # runs the notebook (cwd) and where the directory of the kernel process (kernel_cwd). The latter # of which is important when EG is configured. additional_kwargs = dict() additional_kwargs['engine_name'] = "ElyraEngine" additional_kwargs[ 'cwd'] = file_dir # For local operations, papermill runs from this dir additional_kwargs['kernel_cwd'] = file_dir envs = os.environ.copy( ) # Make sure this process's env is "available" in the kernel subprocess envs.update(operation.env_vars_as_dict()) additional_kwargs['kernel_env'] = envs if GatewayClient.instance().gateway_enabled: additional_kwargs[ 'kernel_manager_class'] = 'elyra.pipeline.http_kernel_manager.HTTPKernelManager' t0 = time.time() try: papermill.execute_notebook(filepath, filepath, **additional_kwargs) except papermill.PapermillExecutionError as pmee: self.log.error( f'Error executing {file_name} in cell {pmee.exec_count}: ' + f'{str(pmee.ename)} {str(pmee.evalue)}') raise RuntimeError( f'({file_name}) in cell {pmee.exec_count}: ' + f'{str(pmee.ename)} {str(pmee.evalue)}') from pmee except Exception as ex: self.log.error(f'Error executing {file_name}: {str(ex)}') raise RuntimeError(f'({file_name})') from ex t1 = time.time() duration = (t1 - t0) self.log.debug(f'Execution of {file_name} took {duration:.3f} secs.')
def process(self, operation: GenericOperation, elyra_run_name: str): filepath = self.get_valid_filepath(operation.filename) file_dir = os.path.dirname(filepath) file_name = os.path.basename(filepath) self.log.debug(f"Processing notebook: {filepath}") # We'll always use the ElyraEngine. This engine is essentially the default Papermill engine # but allows for environment variables to be passed to the kernel process (via 'kernel_env'). # If the current notebook server is running with Enterprise Gateway configured, we will also # point the 'kernel_manager_class' to GatewayKernelManager so that notebooks run as they # would outside of Elyra. Current working directory (cwd) is specified both for where papermill # runs the notebook (cwd) and where the directory of the kernel process (kernel_cwd). The latter # of which is important when EG is configured. additional_kwargs = dict() additional_kwargs["engine_name"] = "ElyraEngine" additional_kwargs[ "cwd"] = file_dir # For local operations, papermill runs from this dir additional_kwargs["kernel_cwd"] = file_dir additional_kwargs["kernel_env"] = OperationProcessor._collect_envs( operation, elyra_run_name) if GatewayClient.instance().gateway_enabled: additional_kwargs[ "kernel_manager_class"] = "jupyter_server.gateway.managers.GatewayKernelManager" t0 = time.time() try: papermill.execute_notebook(filepath, filepath, **additional_kwargs) except papermill.PapermillExecutionError as pmee: self.log.error( f"Error executing {file_name} in cell {pmee.exec_count}: " + f"{str(pmee.ename)} {str(pmee.evalue)}") raise RuntimeError( f"({file_name}) in cell {pmee.exec_count}: " + f"{str(pmee.ename)} {str(pmee.evalue)}") from pmee except Exception as ex: self.log_and_raise(file_name, ex) t1 = time.time() duration = t1 - t0 self.log.debug(f"Execution of {file_name} took {duration:.3f} secs.")
def __init__(self, **kwargs): super().__init__(**kwargs) self.base_endpoint = url_path_join( GatewayClient.instance().url, GatewayClient.instance().kernels_endpoint) self.kernel = None