Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
24 changes: 18 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ See the [standards and best practices for creating custom test scenarios](https:
| RAGAS | ⭐⭐ Medium | Several | Free | Metrics only |
| Custom | ⭐⭐⭐ Complex | Varies | Varies | Build from scratch |

<img alt="image" src="https://github.com/user-attachments/assets/f9bbb891-a847-48d4-85d6-6d6d99c9e017" />


## Installation

**Install from PyPI (recommended):**
Expand Down Expand Up @@ -79,8 +76,23 @@ results = await auditor.run_async("safety", max_turns=5, max_workers=10) # Jupy
# View results
results.summary()
results.plot()
results.save("audit_results.json")
results.save("./my_audit_results/audit_results.json")
```

**💡 View results interactively:**
```bash
# Option 1: Run directly with uvx (no installation needed, requires uv)
uvx simpleaudit[visualize] serve --results_dir ./my_audit_results

# Option 2: Install and run locally
pip install simpleaudit[visualize]
simpleaudit serve --results_dir ./my_audit_results
```
Spin up a local web interface to explore results with scenario details. See [visualization/README.md](simpleaudit/visualization/README.md) for more options and features.

> **Note:** Option 1 requires [`uv`](https://pypi.org/project/uv/) to be installed ([install guide](https://docs.astral.sh/uv/getting-started/installation/)).

[![simpleaudit-visualization-ui](https://github.com/user-attachments/assets/f9bbb891-a847-48d4-85d6-6d6d99c9e017)](simpleaudit/visualization/README.md)

### Running Experiments

Expand Down Expand Up @@ -340,8 +352,8 @@ for result in results:
print(f" Summary: {result.summary}")

# Export
results.save("audit_results.json")
results.plot(save_path="audit_chart.png")
results.save("./my_audit_results/audit_results.json")
results.plot(save_path="./my_audit_results/audit_chart.png")
```

### Severity Levels
Expand Down
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,23 @@ dependencies = [
"tqdm>=4.66.0",
]

[project.scripts]
simpleaudit = "simpleaudit.cli:main"

[project.optional-dependencies]
plot = ["matplotlib>=3.5.0"]
visualize = [
"fastapi>=0.104.0",
"uvicorn[standard]>=0.24.0",
]
dev = [
"pytest>=7.0.0",
"pytest-asyncio>=0.21.0",
"pytest-cov>=4.0.0",
"black>=23.0.0",
"ruff>=0.1.0",
]
all = ["simpleaudit[plot,dev]"]
all = ["simpleaudit[plot,visualize,dev]"]

[project.urls]
Homepage = "https://github.com/kelkalot/simpleaudit"
Expand Down
60 changes: 60 additions & 0 deletions simpleaudit/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
CLI interface for SimpleAudit tools.
"""
import argparse
import sys


def main():
"""Main entry point for simpleaudit CLI."""
parser = argparse.ArgumentParser(
prog="simpleaudit",
description="SimpleAudit CLI - AI Safety Auditing Tools"
)

subparsers = parser.add_subparsers(dest="command", help="Available commands")

# Serve command
serve_parser = subparsers.add_parser(
"serve",
help="Start a web server to visualize audit results"
)
serve_parser.add_argument(
"--results_dir",
type=str,
default=None,
help="Directory containing JSON result files to visualize (default: current directory)"
)
serve_parser.add_argument(
"--port",
type=int,
default=8000,
help="Port to run the server on (default: 8000)"
)
serve_parser.add_argument(
"--host",
type=str,
default="127.0.0.1",
help="Host to bind the server to (default: 127.0.0.1)"
)

args = parser.parse_args()

if args.command == "serve":
from .visualization.server import start_server

# Default to current directory if not specified
results_dir = args.results_dir
if results_dir is None:
results_dir = "."
print("⚠️ Warning: --results_dir not specified, using current directory '.'")
print(" Recommended: explicitly set --results_dir to avoid confusion\n")

Comment on lines +44 to +52
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simpleaudit serve will import the visualization server unconditionally; if users installed the base package without the visualize extra, this will raise ImportError for fastapi/uvicorn. Catch that import error and print a clear message telling the user to install simpleaudit[visualize].

Suggested change
from .visualization.server import start_server
# Default to current directory if not specified
results_dir = args.results_dir
if results_dir is None:
results_dir = "."
print("⚠️ Warning: --results_dir not specified, using current directory '.'")
print(" Recommended: explicitly set --results_dir to avoid confusion\n")
try:
from .visualization.server import start_server
except ImportError:
print(
"Error: Visualization server dependencies are not installed.\n"
"Please install the visualize extra, e.g.:\n"
" pip install 'simpleaudit[visualize]'",
file=sys.stderr,
)
sys.exit(1)
# Default to current directory if not specified
results_dir = args.results_dir
if results_dir is None:
results_dir = "."
print("⚠️ Warning: --results_dir not specified, using current directory '.'")
print(" Recommended: explicitly set --results_dir to avoid confusion\n")

Copilot uses AI. Check for mistakes.
start_server(results_dir, args.host, args.port)
else:
parser.print_help()
sys.exit(1)
Comment on lines +8 to +56
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New CLI entrypoint behavior is introduced (arg parsing + serve command), but there are no tests covering basic CLI invocation/error cases. Since the repo has an existing pytest suite, add a small test module that exercises simpleaudit.cli:main (e.g., help output, unknown command exit code, serve import failure messaging).

Copilot uses AI. Check for mistakes.


if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions simpleaudit/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from dataclasses import dataclass, asdict
from typing import List, Dict, Optional
from datetime import datetime
from pathlib import Path

@dataclass
class AuditResult:
Expand Down Expand Up @@ -160,6 +161,8 @@ def to_dict(self) -> Dict:

def save(self, filepath: str):
"""Save results to JSON file."""
path = Path(filepath)
path.parent.mkdir(parents=True, exist_ok=True)
with open(filepath, "w", encoding="utf-8") as f:
json.dump(self.to_dict(), f, indent=2, ensure_ascii=False)
print(f"✓ Results saved to {filepath}")
Expand Down Expand Up @@ -256,6 +259,8 @@ def plot(self, save_path: Optional[str] = None):
plt.tight_layout()

if save_path:
path = Path(save_path)
path.parent.mkdir(parents=True, exist_ok=True)
plt.savefig(save_path, dpi=150, bbox_inches="tight")
print(f"✓ Chart saved to {save_path}")

Expand Down
Loading