Esempio n. 1
0
def download_file(
    filename: str,
    save_path: str,
    remote_connection: 'environ.RemoteConnection' = None
) -> 'environ.Response':
    """ """

    url = assemble_url('/download/{}'.format(filename),
                       remote_connection=remote_connection)

    try:
        http_response = requests.get(url, stream=True)
    except Exception as error:
        return environ.Response().fail(
            code='CONNECTION_ERROR',
            error=error,
            message='Unable to communicate with the remote download connection'
        ).console(whitespace=1).response

    try:
        with open(save_path, 'wb') as f:
            for chunk in http_response.iter_content(2048):
                if chunk:
                    f.write(chunk)
    except Exception as error:
        return environ.Response().fail(
            code='WRITE_ERROR',
            error=error,
            message='Unable to write data to "{}"'.format(save_path)).console(
                whitespace=1).response

    return environ.Response()
Esempio n. 2
0
    def test_run_in_parts(self):
        """ """

        support.open_project(self, '@examples:hello_cauldron')

        r = environ.Response()
        commander.execute('run', 'S01-create-data.py', r)
        r.thread.join()
        self.assertFalse(r.failed)

        r = environ.Response()
        commander.execute('run', 'S02-plot-data.py', r)
        r.thread.join()
        self.assertFalse(r.failed)
Esempio n. 3
0
def open_project(tester: scaffolds.ResultsTest,
                 path: str) -> 'environ.Response':
    """..."""
    r = environ.Response()
    commander.execute('open', '{} --forget'.format(path), r)
    r.thread.join()
    return r
Esempio n. 4
0
    def open_project(self) -> 'exposed.ExposedProject':
        """
        Returns the Response object populated by the open project command
        """

        project_path = self.make_project_path()
        res = environ.Response()
        commander.execute('open', '{} --forget'.format(project_path), res)
        res.thread.join()

        # Prevent threading race conditions
        check_count = 0
        while res.success and not cd.project.internal_project:
            if check_count > 100:
                break

            check_count += 1
            time.sleep(0.25)

        if res.failed or not cd.project.internal_project:
            self.fail(
                'Unable to open project at path "{}"'.format(project_path))

        os.chdir(cd.project.internal_project.source_directory)

        return cd.project
Esempio n. 5
0
def parse_http_response(http_response: HttpResponse) -> 'environ.Response':
    """
    Returns a Cauldron response object parsed from the serialized JSON data
    specified in the http_response argument. If the response doesn't contain
    valid Cauldron response data, an error Cauldron response object is
    returned instead.

    :param http_response:
        The response object from an http request that contains a JSON
        serialized Cauldron response object as its body
    :return:
        The Cauldron response object for the given http response
    """

    try:
        response = environ.Response.deserialize(http_response.json())
    except Exception as error:
        response = environ.Response().fail(
            code='INVALID_REMOTE_RESPONSE',
            error=error,
            message='Invalid HTTP response from remote connection').console(
                whitespace=1).response

    response.http_response = http_response
    return response
Esempio n. 6
0
    def default(self, line: str):
        """

        :param line:
        :return:
        """

        line = line.strip()
        if len(line) < 1:
            return

        self.history.append(line)
        name, raw_args = parse.split_line(line)

        if name == 'help':
            return commander.show_help().ended

        result = commander.execute(name, raw_args)
        result = (result.response if hasattr(result, 'response') else
                  environ.Response(failed=result))

        if result.thread:
            result.thread.join()

        p = cauldron.project
        if not p or not p.internal_project or not p.internal_project.id:
            name = ''
        else:
            name = cauldron.project.internal_project.id[:20]

        self.prompt = '<{}>: '.format(name)
        self.last_response = result
        return result.ended
Esempio n. 7
0
def open_project(project_path: str) -> 'exposed.ExposedProject':
    """
    Opens the project located at the specified path and returns the public
    (exposed) project after it has been loaded. If the project cannot be
    opened a `RuntimeError` will be raised instead.

    :param project_path:
        The path to the Cauldron project to open. It should be either a
        directory that contains a `cauldron.json` file or a file path to the
        `cauldron.json` file for the project to load.
    """
    res = commander.execute(
        name='open',
        raw_args='{} --forget'.format(project_path),
        response=environ.Response()
    )
    res.thread.join()

    # Prevent threading race conditions
    project = (
        cd.project.get_internal_project()
        if res.success else
        None
    )

    if res.failed or not project:
        raise RuntimeError(
            'Unable to open project at path "{}"'.format(project_path)
        )

    os.chdir(project.source_directory)
    return cd.project
Esempio n. 8
0
    def test_run_no_project(self):
        """ should abort if no project is open """

        r = environ.Response()
        run.execute(
            context=cli.make_command_context(name=run.NAME, response=r))

        self.assert_has_error_code(r, 'NO_OPEN_PROJECT')
Esempio n. 9
0
    def test_long_remote_command(self, send_request: MagicMock):
        """ should successfully handle running longer commands """

        running_response = environ.Response().update(run_status='running')
        done_response = environ.Response().update(run_status='complete')

        send_request.return_value = running_response
        thread = threads.send_remote_command('fake_command_name')
        thread.join(1)
        send_request.return_value = done_response
        thread.join()

        self.assertGreater(len(thread.responses), 1)
        last_response = thread.responses[-1]
        self.assertEqual(last_response.data['run_status'], 'complete')
        first_response = thread.responses[0]
        self.assertEqual(first_response.data['run_status'], 'running')
Esempio n. 10
0
    def test_send_request_valid(self, request: MagicMock,
                                parse_http_response: MagicMock):
        """Should successfully send request"""
        request.return_value = HttpResponse()
        parse_http_response.return_value = environ.Response('test')

        response = comm.send_request(endpoint='/fake',
                                     method='post',
                                     data=dict(a=1, b=2))
        self.assertEqual(response.identifier, 'test')
Esempio n. 11
0
    def test_remote_command(self, send_request: MagicMock):
        """ should execute the command and finish the thread """

        response = environ.Response().update(run_status='complete')
        send_request.return_value = response

        thread = threads.send_remote_command('fake_command_name')
        thread.join()

        self.assertEqual(thread.responses[0], response)
Esempio n. 12
0
    def test_run_bokeh(self):
        """ """

        support.open_project(self, '@examples:bokeh')

        r = environ.Response()
        commander.execute('run', '', r)
        r.thread.join()

        self.assertFalse(r.failed)
Esempio n. 13
0
def send_request(endpoint: str,
                 data: dict = None,
                 remote_connection: 'environ.RemoteConnection' = None,
                 method: str = None,
                 timeout: int = 10,
                 max_retries: int = 10,
                 **kwargs) -> 'environ.Response':
    """
    Sends a request to the remote kernel specified by the RemoteConnection
    object and processes the result. If the request fails or times out it
    will be retried until the max retries is reached. After that a failed
    response will be returned instead.

    :param endpoint:
        Remote endpoint where the request will be directed.
    :param data:
        An optional JSON-serializable dictionary containing the request
        body data.
    :param remote_connection:
        Defines the connection to the remote server where the request will
        be sent.
    :param method:
        The HTTP method type for the request, e.g. GET, POST.
    :param timeout:
        Number of seconds before the request aborts when trying to either
        connect to the target endpoint or receive data from the server.
    :param max_retries:
        Number of retry attempts to make before giving up if a non-HTTP
        error is encountered during communication.
    """
    if max_retries < 0:
        return environ.Response().fail(
            code='COMMUNICATION_ERROR',
            error=None,
            message='Unable to communicate with the remote kernel.').console(
                whitespace=1).response

    url = assemble_url(endpoint, remote_connection)

    try:
        http_response = requests.request(method=method,
                                         url=url,
                                         json=data,
                                         timeout=10,
                                         **kwargs)
    except (requests.ConnectionError, requests.HTTPError, requests.Timeout):
        return send_request(endpoint=endpoint,
                            data=data,
                            remote_connection=remote_connection,
                            method=method,
                            timeout=timeout,
                            max_retries=max_retries - 1,
                            **kwargs)

    return parse_http_response(http_response)
Esempio n. 14
0
    def test_run_step_example(self):
        """
        """

        support.open_project(self, '@examples:hello_cauldron')

        r = environ.Response()
        commander.execute('run', '.', r)
        r.thread.join()

        self.assertFalse(r.failed)
Esempio n. 15
0
    def test_run_example(self):
        """
        """

        support.open_project(self, '@examples:hello_text')

        r = environ.Response()
        commander.execute('run', '', r)
        r.thread.join()

        self.assertFalse(r.failed)
        support.run_command('close')
Esempio n. 16
0
    def test_remote(self, sync_open: MagicMock):
        """ should successfully open project remotely """

        sync_open.return_value = environ.Response()

        response = support.create_project(
            self,
            'tester',
            confirm=False,
            remote_connection=environ.RemoteConnection(True, 'something.url'))

        self.assertTrue(response.success)
        self.assertGreater(sync_open.call_count, 0)
Esempio n. 17
0
    def test_parse_valid_http_response(self):
        """Should fail to send request"""
        source_response = environ.Response().update(test='hello_world')

        def json_mock(*args, **kwargs):
            return source_response.serialize()

        http_response = HttpResponse()
        http_response.json = json_mock

        response = comm.parse_http_response(http_response)

        self.assertEqual(source_response.data['test'], response.data['test'])
Esempio n. 18
0
def deserialize_flask_response(
        flask_response: FlaskResponse) -> 'environ.Response':
    """ """

    try:
        data = json.loads(flask_response.data.decode('utf-8', 'ignore'))
        response = environ.Response.deserialize(data)
    except Exception as error:
        response = environ.Response().fail(
            code='DESERIALIZE_FLASK_RESPONSE',
            message='Failed to deserialize flask response',
            error=error)

    return response
Esempio n. 19
0
def send_request(endpoint: str,
                 data: dict = None,
                 remote_connection: 'environ.RemoteConnection' = None,
                 method: str = None,
                 **kwargs) -> 'environ.Response':
    """ """

    url = assemble_url(endpoint, remote_connection)
    func = get_request_function(data, method)

    try:
        http_response = func(url, json=data, **kwargs)
    except Exception as error:
        return environ.Response().fail(
            code='CONNECTION_ERROR',
            error=error,
            message='Unable to communicate with the remote connection'
        ).console(whitespace=1).response

    return parse_http_response(http_response)