Added executable root launcher for audita
This commit is contained in:
17
README.md
17
README.md
@@ -17,7 +17,22 @@ Set an OpenRouter API key, then process a transcript with a glossary:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
export OPENROUTER_API_KEY=...
|
export OPENROUTER_API_KEY=...
|
||||||
uv run audia process transcript.json --glossary glossary.yaml --output corrected.json
|
uv run audita process transcript.json --glossary glossary.yaml --output corrected.json
|
||||||
|
```
|
||||||
|
|
||||||
|
From a checked-out repository, you can also use the root launcher:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./audita process transcript.json --glossary glossary.yaml --output corrected.json
|
||||||
|
```
|
||||||
|
|
||||||
|
For a system-wide command, install the source tree under `/usr/local/src/audita`, sync dependencies there, and symlink the root launcher into your `PATH`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /usr/local/src/audita
|
||||||
|
uv sync --extra dev
|
||||||
|
ln -s /usr/local/src/audita/audita /usr/local/bin/audita
|
||||||
|
audita process transcript.json --glossary glossary.yaml --output corrected.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Without `--output`, Audita writes the corrected transcript JSON to stdout and progress logs to stderr.
|
Without `--output`, Audita writes the corrected transcript JSON to stdout and progress logs to stderr.
|
||||||
|
|||||||
24
audita
Executable file
24
audita
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
uv = shutil.which("uv")
|
||||||
|
if uv is None:
|
||||||
|
print(
|
||||||
|
"audita: error: uv is required to run this launcher. Install uv and run `uv sync` in the Audita project.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
project_root = Path(__file__).resolve().parent
|
||||||
|
command = [uv, "run", "--project", str(project_root), "python", "-m", "audita", *sys.argv[1:]]
|
||||||
|
os.execv(uv, command)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -20,7 +20,7 @@ dev = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
audia = "audita.cli:main"
|
audita = "audita.cli:main"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
requires = ["hatchling"]
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
|||||||
|
|
||||||
|
|
||||||
def _build_parser() -> argparse.ArgumentParser:
|
def _build_parser() -> argparse.ArgumentParser:
|
||||||
parser = argparse.ArgumentParser(prog="audia")
|
parser = argparse.ArgumentParser(prog="audita")
|
||||||
subparsers = parser.add_subparsers(dest="command", required=True)
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
||||||
|
|
||||||
process = subparsers.add_parser("process", help="correct a transcript using a glossary")
|
process = subparsers.add_parser("process", help="correct a transcript using a glossary")
|
||||||
@@ -65,6 +65,5 @@ def _process(args: argparse.Namespace) -> int:
|
|||||||
sys.stdout.write(transcript_to_json(revised))
|
sys.stdout.write(transcript_to_json(revised))
|
||||||
return 0
|
return 0
|
||||||
except AuditaError as exc:
|
except AuditaError as exc:
|
||||||
print(f"audia: error: {exc}", file=sys.stderr)
|
print(f"audita: error: {exc}", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class InstructorLLMClient:
|
|||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
except ImportError as exc:
|
except ImportError as exc:
|
||||||
raise AuditaLLMError(
|
raise AuditaLLMError(
|
||||||
"The LLM dependencies are not installed. Run `uv sync` before using audia."
|
"The LLM dependencies are not installed. Run `uv sync` before using audita."
|
||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
self._instructor = instructor
|
self._instructor = instructor
|
||||||
@@ -42,4 +42,3 @@ def _normalize_openrouter_model(model: str) -> str:
|
|||||||
if model.startswith(prefix):
|
if model.startswith(prefix):
|
||||||
return model[len(prefix) :]
|
return model[len(prefix) :]
|
||||||
return model
|
return model
|
||||||
|
|
||||||
|
|||||||
12
tests/test_cli.py
Normal file
12
tests/test_cli.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from audita.cli import main
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_help_uses_audita_program_name(capsys):
|
||||||
|
with pytest.raises(SystemExit) as exc:
|
||||||
|
main(["--help"])
|
||||||
|
|
||||||
|
assert exc.value.code == 0
|
||||||
|
assert capsys.readouterr().out.startswith("usage: audita ")
|
||||||
|
|
||||||
31
tests/test_launcher.py
Normal file
31
tests/test_launcher.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
LAUNCHER = ROOT / "audita"
|
||||||
|
|
||||||
|
|
||||||
|
def test_root_launcher_exists_and_is_executable():
|
||||||
|
assert LAUNCHER.is_file()
|
||||||
|
assert os.access(LAUNCHER, os.X_OK)
|
||||||
|
|
||||||
|
|
||||||
|
def test_root_launcher_help_smoke():
|
||||||
|
if shutil.which("uv") is None:
|
||||||
|
pytest.skip("uv is not installed")
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
[str(LAUNCHER), "--help"],
|
||||||
|
cwd=ROOT,
|
||||||
|
text=True,
|
||||||
|
capture_output=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result.returncode == 0
|
||||||
|
assert result.stdout.startswith("usage: audita ")
|
||||||
Reference in New Issue
Block a user