Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ See [QUICKSTART.md](QUICKSTART.md) for the fuller tour.

The command-line client. Runs any VICAR tool in the container, translating host
paths, reusing one warm container, mounting calibration data, and forwarding X11
so GUI tools such as `xvd` display on your desktop.
so GUI tools such as `xvd` display on your desktop. Also a Python API
(`from tig_cli import Tig`) that runs the same tools in the same container and
returns their output and the files they wrote.

📁 `tig-cli/` · 📦 [`pip install tig-cli`](https://pypi.org/project/tig-cli/) · 📖 [README](tig-cli/README.md)

Expand Down
44 changes: 44 additions & 0 deletions tig-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,50 @@ tool untouched:
tig --writable-path /data/results marsmap INP=/data/in.vic OUT=/data/results/out.vic
```

## Python API

The same thing from Python, with the tool's output captured instead of
written to your terminal:

```python
from tig_cli import Tig

with Tig() as tig:
result = tig.run("gen", "test.vic", 64, 64)
result.exit_code # 0
result.stdout # 'Beginning VICAR task GEN\n...'
result.outputs # [PosixPath('/home/you/work/test.vic')]

listing = tig.run("label", "-list", inp="test.vic").check()
tig.run("marsxyz", inp=["left.vic", "right.vic"], out="xyz.vic", check=True)
tig.vicario("test.vic", "test.png") # tig.<tool>(...) is tig.run("<tool>", ...)
```

Positional arguments and `keyword=value` parameters are passed as on the command
line; keyword arguments become parameters, and a list becomes a parenthesized
value list such as `inp=(left.vic,right.vic)`. `Path` objects are accepted
anywhere a path is.

`run()` returns a `Result` with `exit_code`, `stdout`, `stderr`, `ok`, and
`outputs`: the files named in the arguments that the run created or changed,
as host paths. The container writes straight onto the host filesystem, so those
files are in place as soon as `run()` returns - there is nothing to copy back.
Files a tool names itself (a `.mtl` beside an `.obj`) are not listed, but are in
the working directory all the same.

A non-zero exit is reported, not raised, because VICAR programs often exit
non-zero on success; pass `check=True` or call `result.check()` to get a
`VicarError` instead. `stdin=`, `env=`, `timeout=` (raises `VicarTimeout` and
kills the program in the container) and a per-run `workdir=` are also available.

`Tig()` takes the same settings as the command-line options - `image`,
`calibration_path`, `writable_paths`, `config`, `disable_path_translation`,
`selinux_label_disable` - and a `workdir` that relative paths are relative to
(the current directory by default). Anything not given comes from the config
files and environment variables described below, so a script and a shell see the
same setup and share the same container. `tig.tools()` lists the programs the
image provides; `tig.shutdown()` removes the container, as `tig --shutdown` does.

## Configuration

Settings can come from TOML config files, environment variables, or command-line
Expand Down
14 changes: 14 additions & 0 deletions tig-cli/src/tig_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

Configure the tool with layered TOML config files (system, user, project),
the CONTAINER_IMAGE / TIG_* environment variables, or command-line flags.

From Python, ``from tig_cli import Tig`` runs VICAR programs in the same
container; see :mod:`tig_cli.api`.
"""

__version__ = "0.2.0"

__all__ = ["Tig", "Result", "VicarError", "VicarTimeout", "run", "__version__"]


def __getattr__(name: str):
# Imported on demand so the command-line fast path stays light.
if name in __all__:
from . import api

return getattr(api, name)
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
Loading
Loading