Esempio n. 1
0
 def __init__(self, short_id=None, headless=True):
     self.headless = headless
     self.short_id = None
     self.build_id = None
     self._browser = None
     self._code_build_Jupyter = None
     self._jupyter_cell = None
     self._jupyter_web = None
     self._jupyter_api = None
     self._server_details = None
     self._needs_login = True
     self.jupyter_helper = CodeBuild_Jupyter_Helper()
     self.execute_python_file = 'notebooks/setup/gsbot-invoke.ipynb'
     if short_id:
         self.set_build_from_short_id(short_id)
Esempio n. 2
0
def run(event, context):
    try:
        repo_name = event.get('repo_name')
        channel = event.get('channel')
        team_id = event.get('team_id')
        user = event.get('user')
        server_size = event.get('server_size', 'small')

        slack_message(
            f":point_right: Hi <@{user}>, starting Jupyter server for you with the repo `{repo_name}` with server size `{server_size}`.\n :information_source: This should take between 60 and 150 seconds",
            [], channel, team_id)

        from osbot_jupyter.api.CodeBuild_Jupyter_Helper import CodeBuild_Jupyter_Helper
        login_url = CodeBuild_Jupyter_Helper(
        ).start_build_for_repo_and_wait_for_jupyter_load(
            repo_name=repo_name, user=user, server_size=server_size)
        if login_url:
            slack_message(
                ":point_right: Server started ok, please use this link to open it:\n {0}"
                .format(login_url), [], channel, team_id)
        else:
            slack_message(
                ":red_circle: Could not find server (or it took too long to start). Please check that the repo `{0}` exists."
                .format(repo_name), [], channel, team_id)

    except Exception as error:
        slack_message(
            f":red_circle: Something went wrong when starting the {repo_name} Jupyter notebook: {0}"
            .format(error), [], channel, team_id)
        return "{0}".format(error)
    def servers(team_id=None, channel=None, params=None):
        text         = ":point_right: Here are the running servers:"
        servers_text = ""
        attachments = []
        for build_id,build in CodeBuild_Jupyter_Helper().get_active_builds().items():
            #print(build_id)
            build_info = build.build_info()
            Dev.pprint(build_info)
            variables = {}
            for variable in build_info.get('environment').get('environmentVariables'):
                variables[variable.get('name')] = variable.get('value')

            repo_name  = variables.get('repo_name')
            user       = variables.get('user')
            timeout    = build_info.get('timeoutInMinutes')
            small_id   = build_id[-5:]
            server_url = build.url()

            if server_url is None:
                user_text = "(server booting up)"
            else:
                user_text = "<{0}|open>".format(server_url)
            #    servers_text += "*{0}*: booting up\n".format(repo_name, server_url)
            #else:
            time = "{0}".format(build_info.get('startTime').strftime("%H:%M"))
            servers_text += "*{1}*: {2} (id: `{0}`, user: <@{3}>, started: {4}, timeout: {5})\n".format(
                                small_id, repo_name,user_text,user,time, timeout)

        if servers_text:
            attachments.append({"text":servers_text, 'color': 'good'})
            slack_message(text, attachments, channel, team_id)
        else:
            slack_message(":information_source: there are no servers running! Why don't you start one using the command `jupyter start {repo name}` ", [], channel, team_id)
Esempio n. 4
0
 def test_create(self):
     headless = False
     file = '/tmp/active_jupyter_server.yml'
     api = CodeBuild_Jupyter_Helper()
     #result   = api.start_build_and_wait_for_jupyter_load()
     #build_id = api.get_active_build_id()
     config = api.save_active_server_details(file)
     #Dev.pprint(result.build_status())
     #Dev.pprint(build_id)
     Dev.pprint(config)
     jp_web = Jupyter_Web(token=config.get('token'),
                          server=config.get('server'),
                          headless=headless)
     jp_web.login()
     jp_api = Jupyter_API(token=config.get('token'),
                          server=config.get('server'),
                          headless=headless)
Esempio n. 5
0
 def test_start_new_build(self):
     self.build_id = CodeBuild_Jupyter_Helper().start_build_and_wait_for_jupyter_load().build_id
     print(self.build_id)
     self.api = CodeBuild_Jupyter(build_id=self.build_id)
     self.result = self.api.url()
Esempio n. 6
0
 def setUp(self):
     super().setUp()
     self.api = CodeBuild_Jupyter_Helper()
     self.result = None
Esempio n. 7
0
class test_CodeBuild_Jupyter_Helper(Test_Helper):
    def setUp(self):
        super().setUp()
        self.api = CodeBuild_Jupyter_Helper()
        self.result = None

    def tearDown(self):
        if self.result:
            Dev.pprint(self.result)

    def test_get_active_build_id(self):
        self.result = self.api.get_active_build_id()

    def test_get_active_builds(self):
        builds = self.api.get_active_builds()
        print()
        for id, build in builds.items():
            #assert build.build_status() == 'IN_PROGRESS'
            #assert build.build_phase() == 'BUILD'             # need to improve the resilience of this test
            print(id, build.build_status(), build.build_phase())

    def test_start_build(self):
        result = self.api.start_build()
        Dev.pprint(result.build_info())

    def test_start_build_and_wait_for_jupyter_load(self):
        result = self.api.start_build_and_wait_for_jupyter_load()
        Dev.pprint(result.build_status())

    def test_start_build_for_repo__server_size(self):
        repo = 'gs-notebook-gscs'
        self.api.start_build_for_repo(repo, server_size='small')
        self.api.start_build_for_repo(repo, server_size='medium')
        self.api.start_build_for_repo(repo, server_size='large')

    def test_start_build_for_repo_and_wait_for_jupyter_load(self):
        repo = 'gwbot-jupyter-notebooks'
        self.result = self.api.start_build_for_repo_and_wait_for_jupyter_load(
            repo)

    def test_stop_all_active(self):
        result = CodeBuild_Jupyter_Helper().stop_all_active()
        Dev.pprint("stopped builds {0}".format(result))

    def test_save_active_server_details(self):
        tmp_file = '/tmp/active_jupyter_server.yml'
        self.result = self.api.save_active_server_details(tmp_file)

    def test_gw_repo_start_build_for_repo__server_size(self):
        repo_name = 'gwbot-jupyter-notebooks'
        self.result = self.api.start_build_for_repo(repo_name,
                                                    server_size='medium')
Esempio n. 8
0
 def test_stop_all_active(self):
     result = CodeBuild_Jupyter_Helper().stop_all_active()
     Dev.pprint("stopped builds {0}".format(result))
Esempio n. 9
0
class Live_Notebook:
    def __init__(self, short_id=None, headless=True):
        self.headless = headless
        self.short_id = None
        self.build_id = None
        self._browser = None
        self._code_build_Jupyter = None
        self._jupyter_cell = None
        self._jupyter_web = None
        self._jupyter_api = None
        self._server_details = None
        self._needs_login = True
        self.jupyter_helper = CodeBuild_Jupyter_Helper()
        self.execute_python_file = 'notebooks/setup/gsbot-invoke.ipynb'
        if short_id:
            self.set_build_from_short_id(short_id)

    # global objects
    def browser(
        self
    ):  # we have make sure there is only one instance of browser created
        if self._browser is None:
            from osbot_browser.browser.Browser_Lamdba_Helper import Browser_Lamdba_Helper
            browser_helper = Browser_Lamdba_Helper(
                headless=self.headless).setup()
            self._browser = browser_helper.api_browser
        return self._browser

    def jupyter_cell(self):
        if self._jupyter_cell is None:
            server, token = self.server_details()
            self._jupyter_cell = Jupyter_Web_Cell(server=server,
                                                  token=token,
                                                  headless=self.headless,
                                                  browser=self.browser())
        return self._jupyter_cell

    def jupyter_web(self):
        if self._jupyter_web is None:
            server, token = self.server_details()
            self._jupyter_web = Jupyter_Web(server=server,
                                            token=token,
                                            headless=self.headless,
                                            browser=self.browser())
        return self._jupyter_web

    def jupyter_api(self):
        if self._jupyter_api is None:
            server, token = self.server_details()
            self._jupyter_api = Jupyter_API(server=server, token=token)
        return self._jupyter_api

    # config methods
    def set_build_id(self, build_id):
        self.build_id = build_id
        return self

    def set_build_from_short_id(self, short_id):
        if short_id and type(short_id) is str:
            active_builds = self.jupyter_helper.get_active_builds()
            if active_builds:
                for build_id, build in active_builds.items():
                    if short_id in build_id:  # search on build_id
                        self.build_id = build_id
                        self.short_id = short_id
                        return self
                    repo_name = build.build_environment_variables().get(
                        'repo_name')  # search on repo_name
                    if short_id in repo_name:
                        self.build_id = build_id
                        self.short_id = build_id  # in this case use the actual build id as the short id
                        return self
        return None

    def code_build_Jupyter(self):
        if self._code_build_Jupyter is None and self.build_id:
            self._code_build_Jupyter = CodeBuild_Jupyter(self.build_id)
        return self._code_build_Jupyter

    # # NOT WORKING IN LAMBDA (I think it is because the Javascript is not being executed ok)
    # def execute_python(self, python_code,keep_contents=True, target=None):
    #     jp_web  = self.jupyter_web()
    #     jp_cell = self.jupyter_cell()           # the prob is the browser object is being created twice
    #     if target is None:
    #         target = self.execute_python_file
    #     if (target in jp_web.url()) is False:
    #         jp_web.open(target)
    #     if not keep_contents:
    #         jp_cell.clear()
    #     jp_cell.execute(python_code)
    #     #jp_cell.new()
    #     #jp_cell.text('some content')
    #     return jp_cell.output_wait_for_data()

    def server_details(self):
        if self._server_details is None:
            if self.code_build_Jupyter():
                self._server_details = self.code_build_Jupyter(
                ).get_server_details_from_logs()
        return self._server_details

    # api Methods

    def files(self, path=''):
        text_body = ""
        data = self.jupyter_api().contents(path)
        if data is None:
            text_title = ":red_circle: Folder `{0}` not found in server `{1}`".format(
                path, self.short_id)
        else:
            if path == '': path = '/'
            files = []
            folders = []
            text_title = ":point_right: Here are the files and folders for `{0}` in the server `{1}`".format(
                path, data.get('type'), self.short_id)
            for item in data.get('content'):
                url = "{0}/tree/{1}".format(self.jupyter_api().server,
                                            item.get('path'))
                url_preview = "{0}/{1}".format(
                    self.jupyter_web().server,
                    self.jupyter_web().resolve_url_notebook_preview(
                        item.get('path')))
                if item.get('type') == 'directory':
                    #folders.append("<{0}|{1}> (<{2}|preview>)".format(url,item.get('name'), url_preview))
                    folders.append("<{0}|{1}>".format(url, item.get('name')))
                else:
                    files.append(
                        " - {0} (<{1}|edit> , <{2}|preview>)\n".format(
                            item.get('name'), url, url_preview))
                    #files.append("<{0}|{1}>".format(url,item.get('name')))

            if files:
                text_body += '*Files:* \n{0}\n\n'.format(''.join(files))
            if folders:
                text_body += '*Folders:* {0}'.format(' , '.join(folders))

        return text_title, text_body

    def screenshot(self,
                   path=None,
                   width=None,
                   height=None,
                   delay=None,
                   apply_ui_fixes=True):
        jupyter_web = self.login()
        (jupyter_web.open(path).browser_size(width,
                                             height).wait_seconds(delay))
        jupyter_web.ui_add_jquery()

        if apply_ui_fixes:
            jupyter_web.ui_css_fixes(width)

        if path and 'osbot-no-code' in path:
            jupyter_web.ui_hide_input_boxes()

        return jupyter_web.screenshot_base64()

    def login(self):
        if self._needs_login is True:
            self.jupyter_web().login()
            self._needs_login = False
        return self.jupyter_web()

    def stop(self):
        return self.code_build_Jupyter().code_build.codebuild.stop_build(
            id=self.build_id).get('build')

    def execute_python_in_notebook(self, target_notebook, code, source_event):
        self.login()
        self.jupyter_web().open(target_notebook)

        self.jupyter_cell().wait_seconds(1)  # refactor with better method

        self.jupyter_cell().new_top()                                                              \
                           .to_markdown()                                                          \
                           .text("### Code above requested by: \n ```{0}```".format(source_event)) \
                           .execute()
        result = self.jupyter_cell().execute_python(
            code).output_wait_for_data()

        self.jupyter_cell().save_notebook()
        return result

    def get_python_invoke_file(self):
        today = '{0}'.format(datetime.date.today().strftime('%d-%b-%y'))
        target_notebook = 'users/gsbot/invoke-{0}.ipynb'.format(today)
        created = False
        if self.jupyter_api().contents(
                target_notebook) is None:  # we need to create the file
            self.jupyter_api().notebook_create(target_notebook)
            created = True
        target_notebook = "notebooks/{0}".format(target_notebook)

        return target_notebook, created
Esempio n. 10
0
 def stop_all(*params):
     return CodeBuild_Jupyter_Helper().stop_all_active()
Esempio n. 11
0
 def codebuild(self):
     server, token = CodeBuild_Jupyter_Helper().get_active_server_details()
     self.server = server
     self.token = token
     return self
Esempio n. 12
0
 def test_stop_build(self):
     code_build_helper = CodeBuild_Jupyter_Helper()
     self.result = code_build_helper.stop_all_active()