コード例 #1
0
def debug(ctx: click.Context, hash: str, output: Optional[str]) -> None:
    """Extract all data related to a given hash value."""
    logger.info(f"extracting {hash}")
    if output is None:
        output = hash
        output2 = ""
    else:
        output2 = output + "_"

    with funsies._context.Fun(ctx.obj):
        things = funsies.get(hash)
        if len(things) == 0:
            logger.error(f"{hash} does not correspond to anything!")
        elif len(things) == 1:
            logger.info(f"got {type(things[0])}")
            funsies.debug.anything(things[0], output)
            logger.success(f"saved to {output}")

        else:
            logger.warning(f"got {len(things)} objects")
            funsies.debug.anything(things[0], output)
            logger.success(f"{type(things[0])} -> {output}")
            for el in things[1:]:
                funsies.debug.anything(el, output2 + el.hash)
                logger.success(f"{type(el)} -> {output2 + el.hash}")
コード例 #2
0
def wait(  # noqa:C901
        ctx: click.Context, hashes: tuple[str, ...],
        timeout: Optional[float]) -> None:
    """Wait until redis database or certain hashes are ready."""
    if timeout is not None:
        tmax = time.time() + timeout

    while True:
        try:
            db, _ = ctx.obj.new_connection(try_fail=True)
            db.ping()
            break
        except Exception:
            time.sleep(1.0)

        if timeout is not None:
            t1 = time.time()
            if t1 > tmax:
                logger.error("timeout exceeded")
                raise SystemExit(2)

    with funsies._context.Fun(ctx.obj):
        db = funsies._context.get_redis()
        h = []
        for hash in hashes:
            things = funsies.get(hash)
            if len(things) == 0:
                logger.warning(f"no object with hash {hash}")
            for t in things:
                if isinstance(t, types.Artefact):
                    h += [t.hash]
                    logger.info(f"waiting on artefact at {hash}")
                elif isinstance(t, types.Operation):
                    h += [next(iter(t.out.values()))]
                    logger.info(f"waiting on operation at {hash}")
                else:
                    logger.warning(f"ignoring {type(t)} at {t.hash}")

        while len(h) > 0:
            stat = get_status(db, h[0], resolve_links=True)
            if stat > 0:
                h.pop(0)
                logger.success(f"{len(h)} things left to wait for.")
            time.sleep(0.5)

            if timeout is not None:
                t1 = time.time()
                if t1 > tmax:
                    logger.error("timeout exceeded")
                    raise SystemExit(2)
コード例 #3
0
def execute(ctx: click.Context, hashes: tuple[str, ...]) -> None:
    """Enqueue execution of hashes."""
    with funsies._context.Fun(ctx.obj):
        exec_list = []
        for hash in hashes:
            things = funsies.get(hash)
            if len(things) == 0:
                logger.warning(f"no object with hash {hash}")
            for t in things:
                if isinstance(t, types.Operation) or isinstance(
                        t, types.Artefact):
                    exec_list += [t]
                else:
                    logger.warning(
                        f"object with hash {hash} of type {type(t)} skipped")

        funsies.execute(*exec_list)
コード例 #4
0
def cat(ctx: click.Context, hashes: tuple[str, ...]) -> None:
    """Print artefacts to stdout."""
    with funsies._context.Fun(ctx.obj):
        for hash in hashes:
            logger.info(f"extracting {hash}")
            things = funsies.get(hash)
            if len(things) == 0:
                logger.error("hash does not correspond to anything!")
                raise SystemExit(2)

            if len(things) > 1:
                logger.error(f"hash resolves to {len(things)} things.")

            art = things[0]
            if isinstance(art, types.Artefact):
                res = funsies.take(art, strict=False)
                if isinstance(res, types.Error):
                    logger.warning(f"error at {hash}: {res.kind}")
                    if res.details is not None:
                        sys.stderr.buffer.write((res.details + "\n").encode())
                    logger.warning(f"error source: {res.source}")
                elif isinstance(res, bytes):
                    sys.stdout.buffer.write(res)
                    logger.success(f"{hash} output to stdout")
                elif isinstance(res, str):
                    sys.stdout.buffer.write(res.encode())
                    logger.success(f"{hash} output to stdout")
                else:
                    sys.stdout.buffer.write(json.dumps(res).encode())
                    logger.success(f"{hash} output to stdout")

            elif isinstance(art, types.Operation):
                logger.error("not an artefact")
                logger.info("did you mean...")
                sys.stderr.write("      INPUTS:\n")
                for key, val in art.inp.items():
                    sys.stderr.write(f"      {key:<30} -> {val[:8]}\n")
                sys.stderr.write("      OUTPUTS:\n")
                for key, val in art.out.items():
                    sys.stderr.write(f"      {key:<30} -> {val[:8]}\n")
            else:
                logger.error("not an artefact:")
                logger.error(f"{art}")
コード例 #5
0
def graph(ctx: click.Context, hashes: tuple[str, ...], inputs: bool) -> None:
    """Print to stdout a DOT-formatted graph to visualize DAGs."""
    # funsies
    import funsies._graphviz

    with funsies._context.Fun(ctx.obj):
        db = funsies._context.get_redis()
        if len(hashes) == 0:
            # If no hashes are passed, we graph all the DAGs on index
            hashes = tuple([
                dag.decode()
                for dag in db.smembers(funsies._constants.DAG_INDEX)
            ])

        all_data: list[hash_t] = []
        for hash in hashes:
            things = funsies.get(hash.split("/")[-1])
            if len(things) == 0:
                logger.warning(f"no object with hash {hash}")
            for t in things:
                if isinstance(t, types.Operation) or isinstance(
                        t, types.Artefact):
                    all_data += [hash_t(t.hash)]

        if len(all_data):
            logger.info(f"writing graph for {len(all_data)} objects")
            out = funsies._graphviz.format_dot(
                *funsies._graphviz.export(db, all_data),
                targets=all_data,
                show_inputs=inputs,
            )
            sys.stdout.write(out)
            logger.success("done")
        else:
            logger.error("No data points")
            raise SystemExit(2)
コード例 #6
0
def reset(ctx: click.Context, hashes: tuple[str, ...]) -> None:
    """Reset operations and their dependents."""
    with funsies._context.Fun(ctx.obj):
        for hash in hashes:
            things = funsies.get(hash)
            if len(things) == 0:
                logger.warning(f"no object with hash {hash}")
            if len(things) > 1:
                logger.error(
                    f"more than one object with hash starting with {hash}")
                logger.info("which one do you mean of :")
                for t in things:
                    logger.info(f"\t{t.hash}")
                logger.info("none were reset")
            else:
                if isinstance(things[0], types.Artefact) or isinstance(
                        things[0], types.Operation):
                    funsies.ui.reset(things[0])
                    logger.success(f"{hash} was reset")
                else:
                    logger.error(
                        f"object {hash} is neither an operation or an artefact"
                    )
                    logger.info(f"{hash} was not reset")