def run( name: str, parameter: Tuple[str], cache: bool, wait: bool, owner: str, show_output: bool, ): """Run a report""" params = process_cmd_param_vals(parameter) log.info(f"Running script with parameters {params}") script = api.Script.get(name, owner=owner) with api_error_handler("Error running script"): r = script.run(parameters=params, cache=cache) if wait: with click_spinner.spinner(): while not r.is_complete(): time.sleep(2) r.refresh() log.debug(f"Run completed with status {r.status}") if show_output: click.echo(r.output) if r.status == "SUCCESS": if r.result: success_msg(f"Script result - '{r.result}'") if r.report: report = api.Report.by_id(r.report) success_msg(f"Report generated at {report.web_url}") else: failure_msg( f"Script run failed/cancelled\n{r.error_msg}: {r.error_detail}" ) else: success_msg(f"Script run started, view at {script.web_url}")
def setup_script(s: api.Script, env_dir: Path): """Setup the script - unpack & install deps""" # TODO - add local cache check here if env_dir.exists(): log.debug("Package already exists, not redownloading") return None # download and unpack bundle locally into env_dir sdist = s.download_pkg() assert tarfile.is_tarfile(sdist), "Invalid sdist file" shutil.unpack_archive(sdist, extract_dir=env_dir, format="gztar") sdist.unlink() comp_r = compileall.compile_dir(env_dir, force=True, workers=1, quiet=1) if not comp_r: log.warning("Compiling script bundle failed - errors may occur") # install deps if s.requirements: pip_args = [sys.executable, "-m", "pip", "install"] if os.getuid() != 0 and not in_venv(): # we're a normal/non-root user outside a venv pip_args.append("--user") pip_args.extend(s.requirements) log.debug(f"Calling pip as '{pip_args}'") subprocess.run(args=pip_args, check=True) importlib.invalidate_caches() # ensure new packages are detected log.info(f"Successfully installed bundle for script {s.id}")
def _gen_report(self, embedded: bool, title: str, headline: str) -> t.Tuple[str, t.List[Path]]: """Build XML report document""" # convert Blocks to XML s = BuilderState(embedded) _s = self.top_block.to_xml(s) assert len(_s.elements) == 1 # add main structure and Meta report_doc: Element = E.Report( E.Meta( E.Author("Anonymous"), # TODO - get username from config? E.CreatedOn(timestamp()), E.Title(title), E.Headline(headline), ), E.Main(*_s.elements), version="1", ) report_doc.set("{http://www.w3.org/XML/1998/namespace}id", f"_{uuid.uuid4().hex}") # post_process and validate processed_report_doc = local_post_transform( report_doc, embedded="true()" if embedded else "false()") validate_report_doc(xml_doc=processed_report_doc) # convert to string report_str = etree.tounicode(processed_report_doc, pretty_print=True) log.debug("Built Report") log.info(report_str) return (report_str, _s.attachments)
def create(script: str, cron: str, parameter: Tuple[str]): """ Create a schedule SCRIPT: ID/URL of the Script to run CRON: crontab representing the schedule interval PARAMETERS: key/value list of parameters to use when running the script on schedule """ params = process_cmd_param_vals(parameter) log.info(f"Adding schedule with parameters {params}") script_obj = api.Script.by_id(script) schedule_obj = api.Schedule.create(script_obj, cron, params) success_msg(f"Created schedule: {schedule_obj.id} ({schedule_obj.url})")
def create(name: str, cron: str, parameter: Tuple[str], owner: str): """ Create a schedule NAME: Name of the Script to run CRON: crontab representing the schedule interval PARAMETERS: key/value list of parameters to use when running the script on schedule [OWNER]: Script owner """ params = process_cmd_param_vals(parameter) log.info(f"Adding schedule with parameters {params}") script_obj = api.Script.get(name, owner=owner) schedule_obj = api.Schedule.create(script_obj, cron, params) success_msg(f"Created schedule: {schedule_obj.id} ({schedule_obj.url})")
def update(id: str, cron: str, parameter: Tuple[str]): """ Add a schedule ID: ID/URL of the Schedule CRON: crontab representing the schedule interval PARAMETERS: key/value list of parameters to use when running the script on schedule """ params = process_cmd_param_vals(parameter) assert cron or parameter, "Must update either cron or parameters" log.info(f"Updating schedule with parameters {params}") schedule_obj = api.Schedule.by_id(id) schedule_obj.update(cron, params) success_msg(f"Updated schedule: {schedule_obj.id} ({schedule_obj.url})")
def upload(file: str, name: str, visibility: str): """Upload a csv or Excel file as a Datapane Blob""" log.info(f"Uploading {file}") r = api.Blob.upload_file(file, name=name, visibility=visibility) success_msg(f"Uploaded {click.format_filename(file)} to {r.url}")