def view_exec_file(team_id=None, channel=None, params=None): #event = Misc.array_pop(params) # original slack event object if not params or len(params) < 2: build_id = 'gscs' # for now default to this one #return send_message(':red_circle: You must provide the following params: `Server Id`', channel, team_id) else: build_id = str(Misc.array_pop(params, 0)) notebook = Live_Notebook() if notebook.set_build_from_short_id(build_id) is None: return ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers'.format( build_id) (target_notebook, created) = notebook.get_python_invoke_file() send_message( ":point_right: Today's python execution file in server `{0}` is `{1}`, here is what it looks like:" .format(build_id, target_notebook), channel, team_id) width = 1200 height = 1200 delay = 2 png_data = notebook.screenshot(path=target_notebook, width=width, height=height, delay=delay, apply_ui_fixes=False) return send_png_to_slack(png_data, channel, team_id)
def stop(team_id=None, channel=None, params=None): short_id = params.pop(0) notebook = Live_Notebook().set_build_from_short_id(short_id) if notebook: notebook.stop() return ':point_right: stopped server with id: `{0}`'.format(short_id) return ':red_circle: error: could not find server with id: `{0}`'.format(short_id)
def files(team_id=None, channel=None, params=None): event = params.pop() # needed due to injection of event param short_id = Misc.array_pop(params,0) target = " ".join(params) if short_id is None: return send_message(":red_circle: missing `short id`. The syntax for this method is `contents {short_id} [{path}]`", channel, team_id) notebook = Live_Notebook(short_id=short_id) text_title, text_body = notebook.files(target) attachments = [{'text':text_body, 'color':'good'}] slack_message(text_title, attachments,channel,team_id)
def exec(team_id=None, channel=None, params=None): try: event = Misc.array_pop(params) # original slack event object if not params or len(params) < 2: return send_message( ':red_circle: You must provide the following params: `Server Id` and `code` (to execute)', channel, team_id) short_id = str(Misc.array_pop(params, 0)) code = ' '.join(params).replace('“', '"').replace('”', '"').replace( '‘', "'").replace('’', "'") notebook = Live_Notebook() if notebook.set_build_from_short_id(short_id) is None: return ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers'.format( short_id) (target_notebook, created) = notebook.get_python_invoke_file() if created: send_message( ':point_right: Created temp file for dynamic execution: `{0}`' .format(target_notebook), channel, team_id) send_message( ':point_right: Running code with size `{0}` on server `{1}` (on file `{2}`)' .format(len(code), short_id, target_notebook), channel, team_id) result = notebook.execute_python_in_notebook( target_notebook, code, event) if channel: return send_message( ':point_right: Code executed, here is the output:\n ```{0}```' .format(result), channel, team_id) else: return result except Exception as error: return send_message(':red_circle: Error: {0}'.format(error), channel, team_id)
def screenshot(team_id=None, channel=None, params=None, headless=True): event = Misc.array_pop( params ) # original slack event object (don't think this is needed anymore) if not params or len(params) == 0: return send_message( ':red_circle: You must provide an Server Id. Please use `jupyter servers` to see the current list of live servers', channel, team_id) from osbot_jupyter.api.Live_Notebook import Live_Notebook short_id = Misc.array_pop(params, 0) path = Misc.array_pop(params, 0) width = Misc.to_int(Misc.array_pop(params, 0)) height = Misc.to_int(Misc.array_pop(params, 0)) delay = Misc.to_int(Misc.array_pop(params, 0)) if not path: path = '/' if not width: width = 1200 if not height: height = 500 if delay is None: delay = 1 # add one second delay if no value is provided notebook = Live_Notebook(headless=headless) if notebook.set_build_from_short_id(short_id) is None: return ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers'.format( short_id) send_message( ':point_right: taking screenshot of `{0}` with width `{1}`, (min) height `{2}` and delay `{3}`' .format(path, width, height, delay), channel, team_id) png_data = notebook.screenshot( path=path, width=width, height=height, delay=delay, apply_ui_fixes=False ) # when calling the sceenshot via the web command, don't apply the UI fixes return send_png_to_slack(png_data, channel, team_id)
def create_file(team_id=None, channel=None, params=None): event = Misc.array_pop(params) # original slack event object if not params or len(params) < 2: return send_message( ':red_circle: You must provide the following params: `Server Id` and `notebook path`', channel, team_id) build_id = str(Misc.array_pop(params, 0)) file_path = Misc.array_pop(params, 0) file_contents = ' '.join(params) notebook = Live_Notebook() file_type = 'notebook' if '.ipynb' in file_path else 'file' if notebook.set_build_from_short_id(build_id) is None: return ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers'.format( build_id) send_message( ':point_right: Creating `{0}` on server `{1}` at location `{2}` with content of size `{3}`' .format(file_type, build_id, file_path, len(file_contents)), channel, team_id) jupyter_api = notebook.jupyter_api() if file_type == 'notebook': result = jupyter_api.notebook_create(file_path, file_contents) else: result = jupyter_api.file_create(file_path, file_contents) if result.get('status') == 'ok': if file_type == 'notebook': url = "{0}/notebooks/{1}".format(jupyter_api.server, file_path) else: url = "{0}/edit/{1}".format(jupyter_api.server, file_path) return send_message( ':white_check_mark: `{0}` created ok, you can see it here: {1}' .format(file_type, url), channel, team_id) else: return send_message( ':red_circle: Error creating notebook ```{0}```'.format( result.get('data')), channel, team_id)
def preview(team_id=None, channel=None, params=None, headless=True): event = Misc.array_pop(params) # original slack event object if not params or len(params) < 2: return send_message( ':red_circle: You must provide an Server Id and file to process. Please use `jupyter servers` to see the current list of live servers', channel, team_id) short_id = Misc.array_pop(params, 0) path = Misc.array_pop(params, 0) width = Misc.to_int(Misc.array_pop(params, 0, 1200)) height = Misc.to_int(Misc.array_pop(params, 0, 800)) delay = Misc.to_int(Misc.array_pop(params, 0, 0)) if width is None: width = 1200 if height is None: height = 800 if delay is None: delay = 0 notebook = Live_Notebook(headless=headless) if notebook.set_build_from_short_id(short_id) is None: return ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers'.format( short_id) if '?show-code' in path: path = f'nbconvert/html/{path}' else: path = f'nbconvert/html/{path}?download=false&osbot-no-code' send_message( ':point_right: taking screenshot of `{0}` with width `{1}`, (min) height `{2}` and delay `{3}`' .format(path, width, height, delay), channel, team_id) png_data = notebook.screenshot(path=path, width=width, height=height, delay=delay, apply_ui_fixes=True) return send_png_to_slack(png_data, channel, team_id)
def run(event, context): load_dependency('requests') from osbot_jupyter.api.Live_Notebook import Live_Notebook short_id = event.get('short_id') code = event.get('code') target = event.get('target') keep_contents = event.get('keep_contents') notebook = Live_Notebook(short_id) notebook.login() return notebook.execute_python(python_code=code, target=target, keep_contents=keep_contents) return notebook.jupyter_web().screenshot_base64()
class test_Live_Notebook(TestCase): def setUp(self): self.short_id = '12d62' self.notebook = Live_Notebook(short_id=self.short_id, headless=True) self.test_notebook ='notebooks/users/gsbot/gsbot-invoke.ipynb' self.result = None self.png_data = None def tearDown(self): if self.result is not None: Dev.pprint(self.result) if self.png_data: png_file = '/tmp/lambda_png_file.png' with open(png_file, "wb") as fh: fh.write(base64.decodebytes(self.png_data.encode())) Dev.pprint("Png data with size {0} saved to {1}".format(len(self.png_data), png_file)) # config methods def test_set_build_from_short_id(self): assert self.notebook.set_build_from_short_id(self.short_id) is self.notebook assert self.notebook.set_build_from_short_id('aaaa' ) is None assert self.notebook.set_build_from_short_id('gscs' ) is self.notebook # will need this server to be running assert self.notebook.set_build_from_short_id('aaaa' ) is None def test_jupyter_api(self): assert self.notebook.jupyter_api().version() == {'version': '5.7.8'} assert set(self.notebook.jupyter_api().status()) == {'connections', 'kernels', 'last_activity', 'started'} def test_stop(self): self.result = self.notebook.set_build_from_short_id(self.short_id).stop() # api methods def test_files(self): self.result = self.notebook.files('users') #contents def test_execute_command(self): jp_web = self.notebook.jupyter_web() jp_cell = self.notebook.jupyter_cell() #jp_web.login() if (self.test_notebook in jp_web.url()) is False: jp_web.open(self.test_notebook) jp_cell.clear() jp_cell.execute(""" answer=40+2 print('this was executed from an unit test') answer """) self.result = jp_cell.output_wait_for_data() def test_execute_python(self): self.result = self.notebook.execute_python(""" a=40+2 print(123) a """, keep_contents=None) def test_screenshot(self): self.notebook.set_build_from_short_id(self.short_id) self.png_data = self.notebook.screenshot(self.test_notebook,800) def test_bug_screenshot_duplicates_first_page(self): target_notebook = 'nbconvert/html/users/dinis/rdf/part-1-loading-the-rdf-file.ipynb?download=false' #jp_web = self.notebook.jupyter_web() #jp_web.open(self.notebook) self.png_data = self.notebook.screenshot(target_notebook, 2000,10000)
def setUp(self): self.short_id = '12d62' self.notebook = Live_Notebook(short_id=self.short_id, headless=True) self.test_notebook ='notebooks/users/gsbot/gsbot-invoke.ipynb' self.result = None self.png_data = None
def update_notebook(team_id=None, channel=None, params=None): event = Misc.array_pop(params) # original slack event object if not params or len(params) < 2: return send_message( ':red_circle: You must provide the following params: `Server Id` and `notebook path` (to update)', channel, team_id) short_id = str(Misc.array_pop(params, 0)) target_notebook = Misc.array_pop(params, 0) if '.ipynb' not in target_notebook: target_notebook += '.ipynb' notebook = Live_Notebook() if notebook.set_build_from_short_id(short_id) is None: return send_message( ':red_circle: Could not find Jupyter server with id `{0}`. Please use `jupyter servers` to see the current list of live servers' .format(short_id), channel, team_id) if notebook.jupyter_api().contents(target_notebook) is None: return send_message( ":red_circle: Could not find notebook `{0}` in server `{1}`". format(target_notebook, short_id), channel, team_id) send_message( ":point_right: Updating notebook `{0}` on server `{1}`".format( target_notebook, short_id), channel, team_id) target_notebook_fixed = "notebooks/{0}".format(target_notebook) code = '!cd ../../..; jupyter nbconvert --to notebook --inplace --execute {0}'.format( target_notebook_fixed) #note for longer executions the save is not working ok (invoke_notebook, created) = notebook.get_python_invoke_file() send_message( ':point_right: Running code with size `{0}` on server `{1}` (on file `{2}`)' .format(len(code), short_id, invoke_notebook), channel, team_id) result = notebook.execute_python_in_notebook(invoke_notebook, code, event) #send_message("result: ```{0}``` ".format(result),channel, team_id) if result and ('[NbConvertApp] Writing' not in result): #or ('[js eval error]' in result): if 'matched no files' in result: send_message( ":red_circle: Update failed, could not find notebook \n ```{0}```" .format(target_notebook_fixed), channel, team_id) send_message( "Here is the execution code: ```{0}````".format(code), channel, team_id) return else: return send_message( ":red_circle: Update failed: \n ```{0}```".format(result), channel, team_id) send_message(":point_right: Notebook updated ok", channel, team_id) # need to double check params = [short_id, target_notebook, event] return Jupyter_Web_Commands.preview(team_id, channel, params)