Example #1
0
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}")
Example #2
0
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}")
Example #3
0
    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)
Example #4
0
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})")
Example #5
0
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})")
Example #6
0
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})")
Example #7
0
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}")