equiaudit 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. equiaudit-0.1.1/PKG-INFO +161 -0
  2. equiaudit-0.1.1/README.md +127 -0
  3. equiaudit-0.1.1/pyproject.toml +56 -0
  4. equiaudit-0.1.1/setup.cfg +4 -0
  5. equiaudit-0.1.1/src/equiaudit/__init__.py +3 -0
  6. equiaudit-0.1.1/src/equiaudit/cli/__init__.py +7 -0
  7. equiaudit-0.1.1/src/equiaudit/cli/__main__.py +204 -0
  8. equiaudit-0.1.1/src/equiaudit/cli/evaluator.py +455 -0
  9. equiaudit-0.1.1/src/equiaudit/data/GermanCredit.csv +1001 -0
  10. equiaudit-0.1.1/src/equiaudit/data/UCI_Credit_Card.csv +30001 -0
  11. equiaudit-0.1.1/src/equiaudit/data/adult-all.csv +48843 -0
  12. equiaudit-0.1.1/src/equiaudit/data/adult-all_discretized.csv +48843 -0
  13. equiaudit-0.1.1/src/equiaudit/data/bank-additional.csv +41189 -0
  14. equiaudit-0.1.1/src/equiaudit/data/german.csv +1001 -0
  15. equiaudit-0.1.1/src/equiaudit/data/german_discretized.csv +1001 -0
  16. equiaudit-0.1.1/src/equiaudit/gui/__init__.py +113 -0
  17. equiaudit-0.1.1/src/equiaudit/gui/app.py +30 -0
  18. equiaudit-0.1.1/src/equiaudit/gui/config.py +89 -0
  19. equiaudit-0.1.1/src/equiaudit/gui/screens/main_page.py +32 -0
  20. equiaudit-0.1.1/src/equiaudit/gui/screens/new_evaluation.py +983 -0
  21. equiaudit-0.1.1/src/equiaudit/gui/screens/view_results.py +704 -0
  22. equiaudit-0.1.1/src/equiaudit/gui/state.py +36 -0
  23. equiaudit-0.1.1/src/equiaudit/gui/styles.py +183 -0
  24. equiaudit-0.1.1/src/equiaudit/gui/utils.py +130 -0
  25. equiaudit-0.1.1/src/equiaudit/gui/widgets/fairness.py +748 -0
  26. equiaudit-0.1.1/src/equiaudit/gui/widgets/results.py +342 -0
  27. equiaudit-0.1.1/src/equiaudit/gui/widgets/stage_display.py +650 -0
  28. equiaudit-0.1.1/src/equiaudit/main.py +161 -0
  29. equiaudit-0.1.1/src/equiaudit/models/__init__.py +32 -0
  30. equiaudit-0.1.1/src/equiaudit/models/agent_manager.py +256 -0
  31. equiaudit-0.1.1/src/equiaudit/models/agents/__init__.py +11 -0
  32. equiaudit-0.1.1/src/equiaudit/models/agents/base_agent.py +242 -0
  33. equiaudit-0.1.1/src/equiaudit/models/agents/conversational_agent.py +21 -0
  34. equiaudit-0.1.1/src/equiaudit/models/agents/data_analyst_agent.py +84 -0
  35. equiaudit-0.1.1/src/equiaudit/models/agents/function_caller_agent.py +86 -0
  36. equiaudit-0.1.1/src/equiaudit/models/agents/humanizer_agent.py +58 -0
  37. equiaudit-0.1.1/src/equiaudit/models/agents/summary_agent.py +69 -0
  38. equiaudit-0.1.1/src/equiaudit/models/clients/__init__.py +13 -0
  39. equiaudit-0.1.1/src/equiaudit/models/clients/base_client.py +89 -0
  40. equiaudit-0.1.1/src/equiaudit/models/clients/client_factory.py +88 -0
  41. equiaudit-0.1.1/src/equiaudit/models/clients/gemini_client.py +113 -0
  42. equiaudit-0.1.1/src/equiaudit/models/clients/ollama_client.py +68 -0
  43. equiaudit-0.1.1/src/equiaudit/models/clients/openrouter_client.py +135 -0
  44. equiaudit-0.1.1/src/equiaudit/models/config.yml +147 -0
  45. equiaudit-0.1.1/src/equiaudit/pipeline/__init__.py +9 -0
  46. equiaudit-0.1.1/src/equiaudit/pipeline/config.py +88 -0
  47. equiaudit-0.1.1/src/equiaudit/pipeline/pipeline.py +642 -0
  48. equiaudit-0.1.1/src/equiaudit/pipeline/pipeline_config.yml +81 -0
  49. equiaudit-0.1.1/src/equiaudit/pipeline/stage.py +102 -0
  50. equiaudit-0.1.1/src/equiaudit/pipeline/stages/__init__.py +25 -0
  51. equiaudit-0.1.1/src/equiaudit/pipeline/stages/base.py +86 -0
  52. equiaudit-0.1.1/src/equiaudit/pipeline/stages/dataset_loading.py +21 -0
  53. equiaudit-0.1.1/src/equiaudit/pipeline/stages/discretization.py +384 -0
  54. equiaudit-0.1.1/src/equiaudit/pipeline/stages/fairness.py +176 -0
  55. equiaudit-0.1.1/src/equiaudit/pipeline/stages/imbalance.py +122 -0
  56. equiaudit-0.1.1/src/equiaudit/pipeline/stages/mitigation.py +332 -0
  57. equiaudit-0.1.1/src/equiaudit/pipeline/stages/objective.py +34 -0
  58. equiaudit-0.1.1/src/equiaudit/pipeline/stages/pair_selection.py +116 -0
  59. equiaudit-0.1.1/src/equiaudit/pipeline/stages/quality.py +28 -0
  60. equiaudit-0.1.1/src/equiaudit/pipeline/stages/recommendations.py +45 -0
  61. equiaudit-0.1.1/src/equiaudit/pipeline/stages/sensitive.py +134 -0
  62. equiaudit-0.1.1/src/equiaudit/pipeline/utils.py +878 -0
  63. equiaudit-0.1.1/src/equiaudit/reporting/__init__.py +0 -0
  64. equiaudit-0.1.1/src/equiaudit/reporting/pdf_generator.py +645 -0
  65. equiaudit-0.1.1/src/equiaudit/tools/__init__.py +0 -0
  66. equiaudit-0.1.1/src/equiaudit/tools/bias_mitigation_tools.py +653 -0
  67. equiaudit-0.1.1/src/equiaudit/tools/discretization_tools.py +259 -0
  68. equiaudit-0.1.1/src/equiaudit/tools/fairness_tools.py +1037 -0
  69. equiaudit-0.1.1/src/equiaudit/tools/tool.py +6 -0
  70. equiaudit-0.1.1/src/equiaudit/tools/tool_manager.py +65 -0
  71. equiaudit-0.1.1/src/equiaudit.egg-info/PKG-INFO +161 -0
  72. equiaudit-0.1.1/src/equiaudit.egg-info/SOURCES.txt +74 -0
  73. equiaudit-0.1.1/src/equiaudit.egg-info/dependency_links.txt +1 -0
  74. equiaudit-0.1.1/src/equiaudit.egg-info/entry_points.txt +2 -0
  75. equiaudit-0.1.1/src/equiaudit.egg-info/requires.txt +16 -0
  76. equiaudit-0.1.1/src/equiaudit.egg-info/top_level.txt +1 -0
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.4
2
+ Name: equiaudit
3
+ Version: 0.1.1
4
+ Summary: An Agentic AI Framework for Fairness Auditing
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/pchmelo/EquiAudit
7
+ Project-URL: Repository, https://github.com/pchmelo/EquiAudit
8
+ Project-URL: Issues, https://github.com/pchmelo/EquiAudit/issues
9
+ Keywords: fairness,bias,auditing,agentic-ai,machine-learning,tabular-data
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ Requires-Dist: aif360==0.6.1
20
+ Requires-Dist: imbalanced-learn==0.14.1
21
+ Requires-Dist: matplotlib>=3.10
22
+ Requires-Dist: numpy>=2.2
23
+ Requires-Dist: pandas>=2.2
24
+ Requires-Dist: python-dotenv>=1.2
25
+ Requires-Dist: pyyaml>=6.0
26
+ Requires-Dist: reportlab>=4.2
27
+ Requires-Dist: requests>=2.32
28
+ Requires-Dist: scikit-learn>=1.8
29
+ Requires-Dist: scipy>=1.14
30
+ Requires-Dist: seaborn>=0.13
31
+ Requires-Dist: google-genai>=1.0
32
+ Provides-Extra: gui
33
+ Requires-Dist: streamlit>=1.52; extra == "gui"
34
+
35
+ # EquiAudit — Dataset Quality & Fairness Evaluation System
36
+
37
+ An AI-agent pipeline for evaluating datasets on data quality and fairness concerns, with an interactive Streamlit GUI, a headless CLI, and a Python API.
38
+
39
+ <div align="center">
40
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/simple_diagram.png" alt="System overview" width="320"/>
41
+
42
+ *A dataset is fed into EquiAudit, which coordinates AI agents under optional user supervision to produce an audit report and a bias-mitigated dataset.*
43
+ </div>
44
+
45
+ ## How It Works
46
+
47
+ <div align="center">
48
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/data_preparation_fairness_analysis.png" alt="Agent-tool-data interaction" width="600"/>
49
+
50
+ *AI agents interact bidirectionally with the analyst, invoke tools to query and compute statistics on the dataset, and synthesise findings into an audit report.*
51
+ </div>
52
+
53
+ <div align="center">
54
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/mitigation.png" alt="Bias mitigation workflow" width="600"/>
55
+
56
+ *Each selected mitigation technique produces a transformed dataset variant; tools recompute fairness statistics on every variant; the AI agent compares them against the original statistics and produces a comparative mitigation report.*
57
+ </div>
58
+
59
+ ## Demo
60
+
61
+ A video demonstration of the full GUI workflow is available on YouTube:
62
+ [https://youtu.be/_USTmBhzDkI](https://youtu.be/_USTmBhzDkI)
63
+
64
+ ## Documentation
65
+
66
+ | Guide | Description |
67
+ |-------|-------------|
68
+ | [USAGE.md](docs/USAGE.md) | Installation, configuration reference, all execution modes (GUI / CLI / Python API), and worked examples |
69
+ | [EXTENDING.md](docs/EXTENDING.md) | How to add new Tools, Agent types, LLM backends, and Pipeline stages |
70
+
71
+ ## Installation
72
+
73
+ **From PyPI (recommended):**
74
+ ```bash
75
+ pip install equiaudit # core pipeline
76
+ pip install "equiaudit[gui]" # optional: Streamlit GUI
77
+ ```
78
+
79
+ **From source:**
80
+ ```bash
81
+ git clone https://github.com/pchmelo/EquiAudit.git
82
+ cd EquiAudit
83
+ pip install -r requirements.txt # core pipeline
84
+ pip install -r requirements-gui.txt # optional: Streamlit GUI
85
+ ```
86
+
87
+ ## Configuration
88
+
89
+ Copy `examples/config.yml` and set your API keys as environment variables or in a `.env` file at the project root:
90
+
91
+ ```bash
92
+ GOOGLE_API_KEY=your-google-gemini-api-key-here
93
+ OPENROUTER_API_KEY=your-openrouter-api-key-here
94
+ ```
95
+
96
+ At least one cloud API key is required unless running a local model via Ollama (`ollama serve`).
97
+
98
+ See [USAGE.md — Configuration File](docs/USAGE.md#configuration-file) for the full annotated config reference.
99
+
100
+ ## Running the Application
101
+
102
+ The recommended entry point is `examples/example_usage.py`. Set `mode: gui` or `mode: quick` in `examples/config.yml`, then run:
103
+
104
+ ```bash
105
+ python examples/example_usage.py
106
+ ```
107
+
108
+ The script dispatches to the GUI or the headless evaluator based on the config:
109
+
110
+ ```python
111
+ # examples/example_usage.py
112
+ import os, yaml
113
+ from dotenv import load_dotenv
114
+ load_dotenv()
115
+
116
+ CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config.yml")
117
+ DATASET_PATH = os.path.join(os.path.dirname(__file__), "adult-all.csv")
118
+
119
+ with open(CONFIG_PATH, encoding="utf-8") as f:
120
+ _mode = (yaml.safe_load(f) or {}).get("mode", "quick")
121
+
122
+ if _mode == "gui":
123
+ from equiaudit.gui import launch
124
+ launch(config_path=CONFIG_PATH, dataset_path=DATASET_PATH)
125
+ else:
126
+ from equiaudit.cli import FairnessEvaluator
127
+ evaluator = FairnessEvaluator(config_path=CONFIG_PATH)
128
+ result = evaluator.evaluate(
129
+ data=DATASET_PATH,
130
+ # target="Income", # overrides target_column in config
131
+ # sensitive_columns=["Sex", "Race", "Age"], # overrides sensitive_attribute_analysis
132
+ # sensitive_pairs=[["Sex", "Race"], ["Age", "Education"]], # overrides pair_evaluation
133
+ # mitigation_techniques=["reweighting", "smote"], # overrides mitigation_techniques
134
+ )
135
+ if result.success:
136
+ print(f"Report: {result.report_dir}")
137
+ else:
138
+ print(f"Error: {result.error}")
139
+ ```
140
+
141
+ See [USAGE.md — Execution Modes](docs/USAGE.md#execution-modes) for the full CLI flag reference and Python API usage.
142
+
143
+ ## Datasets
144
+ Example datasets are provided in `src/equiaudit/data/` for testing. The default example is `adult-all.csv` (UCI Adult Census Income, target column `Income`).
145
+
146
+ ## Reports
147
+ Generated reports are saved under `reports/<dataset>_<timestamp>/` and include a Markdown narrative, a PDF, per-group fairness metrics, and raw JSON stage data. A sample report is available in `reports/`.
148
+
149
+ ## GUI Screenshots
150
+
151
+ ![Framework configuration](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_1.png)
152
+ *Framework configuration (dataset selection, model backend, target column, and pipeline options).*
153
+
154
+ ![Sensitive attribute identification](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_2.png)
155
+ *Sensitive attribute identification (agent-generated candidate list pending analyst confirmation).*
156
+
157
+ ![Proxy model fairness results](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_3.png)
158
+ *Proxy model fairness results (per-group metric bar charts from the outcome disparity stage).*
159
+
160
+ ![Previous results browser](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_4.png)
161
+ *Previous results browser (inspect and compare past audit runs).*
@@ -0,0 +1,127 @@
1
+ # EquiAudit — Dataset Quality & Fairness Evaluation System
2
+
3
+ An AI-agent pipeline for evaluating datasets on data quality and fairness concerns, with an interactive Streamlit GUI, a headless CLI, and a Python API.
4
+
5
+ <div align="center">
6
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/simple_diagram.png" alt="System overview" width="320"/>
7
+
8
+ *A dataset is fed into EquiAudit, which coordinates AI agents under optional user supervision to produce an audit report and a bias-mitigated dataset.*
9
+ </div>
10
+
11
+ ## How It Works
12
+
13
+ <div align="center">
14
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/data_preparation_fairness_analysis.png" alt="Agent-tool-data interaction" width="600"/>
15
+
16
+ *AI agents interact bidirectionally with the analyst, invoke tools to query and compute statistics on the dataset, and synthesise findings into an audit report.*
17
+ </div>
18
+
19
+ <div align="center">
20
+ <img src="https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/mitigation.png" alt="Bias mitigation workflow" width="600"/>
21
+
22
+ *Each selected mitigation technique produces a transformed dataset variant; tools recompute fairness statistics on every variant; the AI agent compares them against the original statistics and produces a comparative mitigation report.*
23
+ </div>
24
+
25
+ ## Demo
26
+
27
+ A video demonstration of the full GUI workflow is available on YouTube:
28
+ [https://youtu.be/_USTmBhzDkI](https://youtu.be/_USTmBhzDkI)
29
+
30
+ ## Documentation
31
+
32
+ | Guide | Description |
33
+ |-------|-------------|
34
+ | [USAGE.md](docs/USAGE.md) | Installation, configuration reference, all execution modes (GUI / CLI / Python API), and worked examples |
35
+ | [EXTENDING.md](docs/EXTENDING.md) | How to add new Tools, Agent types, LLM backends, and Pipeline stages |
36
+
37
+ ## Installation
38
+
39
+ **From PyPI (recommended):**
40
+ ```bash
41
+ pip install equiaudit # core pipeline
42
+ pip install "equiaudit[gui]" # optional: Streamlit GUI
43
+ ```
44
+
45
+ **From source:**
46
+ ```bash
47
+ git clone https://github.com/pchmelo/EquiAudit.git
48
+ cd EquiAudit
49
+ pip install -r requirements.txt # core pipeline
50
+ pip install -r requirements-gui.txt # optional: Streamlit GUI
51
+ ```
52
+
53
+ ## Configuration
54
+
55
+ Copy `examples/config.yml` and set your API keys as environment variables or in a `.env` file at the project root:
56
+
57
+ ```bash
58
+ GOOGLE_API_KEY=your-google-gemini-api-key-here
59
+ OPENROUTER_API_KEY=your-openrouter-api-key-here
60
+ ```
61
+
62
+ At least one cloud API key is required unless running a local model via Ollama (`ollama serve`).
63
+
64
+ See [USAGE.md — Configuration File](docs/USAGE.md#configuration-file) for the full annotated config reference.
65
+
66
+ ## Running the Application
67
+
68
+ The recommended entry point is `examples/example_usage.py`. Set `mode: gui` or `mode: quick` in `examples/config.yml`, then run:
69
+
70
+ ```bash
71
+ python examples/example_usage.py
72
+ ```
73
+
74
+ The script dispatches to the GUI or the headless evaluator based on the config:
75
+
76
+ ```python
77
+ # examples/example_usage.py
78
+ import os, yaml
79
+ from dotenv import load_dotenv
80
+ load_dotenv()
81
+
82
+ CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config.yml")
83
+ DATASET_PATH = os.path.join(os.path.dirname(__file__), "adult-all.csv")
84
+
85
+ with open(CONFIG_PATH, encoding="utf-8") as f:
86
+ _mode = (yaml.safe_load(f) or {}).get("mode", "quick")
87
+
88
+ if _mode == "gui":
89
+ from equiaudit.gui import launch
90
+ launch(config_path=CONFIG_PATH, dataset_path=DATASET_PATH)
91
+ else:
92
+ from equiaudit.cli import FairnessEvaluator
93
+ evaluator = FairnessEvaluator(config_path=CONFIG_PATH)
94
+ result = evaluator.evaluate(
95
+ data=DATASET_PATH,
96
+ # target="Income", # overrides target_column in config
97
+ # sensitive_columns=["Sex", "Race", "Age"], # overrides sensitive_attribute_analysis
98
+ # sensitive_pairs=[["Sex", "Race"], ["Age", "Education"]], # overrides pair_evaluation
99
+ # mitigation_techniques=["reweighting", "smote"], # overrides mitigation_techniques
100
+ )
101
+ if result.success:
102
+ print(f"Report: {result.report_dir}")
103
+ else:
104
+ print(f"Error: {result.error}")
105
+ ```
106
+
107
+ See [USAGE.md — Execution Modes](docs/USAGE.md#execution-modes) for the full CLI flag reference and Python API usage.
108
+
109
+ ## Datasets
110
+ Example datasets are provided in `src/equiaudit/data/` for testing. The default example is `adult-all.csv` (UCI Adult Census Income, target column `Income`).
111
+
112
+ ## Reports
113
+ Generated reports are saved under `reports/<dataset>_<timestamp>/` and include a Markdown narrative, a PDF, per-group fairness metrics, and raw JSON stage data. A sample report is available in `reports/`.
114
+
115
+ ## GUI Screenshots
116
+
117
+ ![Framework configuration](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_1.png)
118
+ *Framework configuration (dataset selection, model backend, target column, and pipeline options).*
119
+
120
+ ![Sensitive attribute identification](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_2.png)
121
+ *Sensitive attribute identification (agent-generated candidate list pending analyst confirmation).*
122
+
123
+ ![Proxy model fairness results](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_3.png)
124
+ *Proxy model fairness results (per-group metric bar charts from the outcome disparity stage).*
125
+
126
+ ![Previous results browser](https://raw.githubusercontent.com/pchmelo/EquiAudit/master/docs/img/new_4.png)
127
+ *Previous results browser (inspect and compare past audit runs).*
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "equiaudit"
7
+ version = "0.1.1"
8
+ description = "An Agentic AI Framework for Fairness Auditing"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ keywords = ["fairness", "bias", "auditing", "agentic-ai", "machine-learning", "tabular-data"]
13
+ classifiers = [
14
+ "Development Status :: 4 - Beta",
15
+ "Intended Audience :: Science/Research",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
21
+ ]
22
+
23
+ dependencies = [
24
+ "aif360==0.6.1",
25
+ "imbalanced-learn==0.14.1",
26
+ "matplotlib>=3.10",
27
+ "numpy>=2.2",
28
+ "pandas>=2.2",
29
+ "python-dotenv>=1.2",
30
+ "pyyaml>=6.0",
31
+ "reportlab>=4.2",
32
+ "requests>=2.32",
33
+ "scikit-learn>=1.8",
34
+ "scipy>=1.14",
35
+ "seaborn>=0.13",
36
+ "google-genai>=1.0",
37
+ ]
38
+
39
+ [project.optional-dependencies]
40
+ gui = ["streamlit>=1.52"]
41
+
42
+ [project.scripts]
43
+ equiaudit = "equiaudit.cli.__main__:main"
44
+
45
+ [project.urls]
46
+ Homepage = "https://github.com/pchmelo/EquiAudit"
47
+ Repository = "https://github.com/pchmelo/EquiAudit"
48
+ Issues = "https://github.com/pchmelo/EquiAudit/issues"
49
+
50
+ [tool.setuptools.packages.find]
51
+ where = ["src"]
52
+
53
+ [tool.setuptools.package-data]
54
+ "equiaudit.models" = ["config.yml"]
55
+ "equiaudit.pipeline" = ["pipeline_config.yml"]
56
+ "equiaudit.data" = ["*.csv"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """EquiAudit: An Agentic AI Framework for Fairness Auditing."""
2
+
3
+ __version__ = "0.1.1"
@@ -0,0 +1,7 @@
1
+ from equiaudit.cli.evaluator import FairnessEvaluator, EvaluationResult, VerificationResult
2
+
3
+ __all__ = [
4
+ "FairnessEvaluator",
5
+ "EvaluationResult",
6
+ "VerificationResult",
7
+ ]
@@ -0,0 +1,204 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import os
5
+ import sys
6
+ from pathlib import Path
7
+
8
+
9
+ def main(args: argparse.Namespace = None) -> int:
10
+ """Main entry point for CLI."""
11
+
12
+ if args is None:
13
+ args = parse_args()
14
+
15
+ # Handle environment variable loading from .env file
16
+ if args.env_file:
17
+ load_env_file(args.env_file)
18
+
19
+ # Import after env loading to ensure API keys are available
20
+ from equiaudit.cli.evaluator import FairnessEvaluator
21
+
22
+ # Create evaluator
23
+ evaluator = FairnessEvaluator(
24
+ config_path=args.config,
25
+ output_dir=args.output,
26
+ model=args.model,
27
+ verbose=not args.quiet,
28
+ )
29
+
30
+ # Verify mode
31
+ if args.verify:
32
+ result = evaluator.verify()
33
+ return 0 if result.success else 1
34
+
35
+ # Evaluate mode - requires data
36
+ if not args.data:
37
+ print("Error: --data is required for evaluation mode")
38
+ print("Use --verify to check configuration only")
39
+ return 1
40
+
41
+ # Run evaluation
42
+ result = evaluator.evaluate(
43
+ data=args.data,
44
+ target=args.target,
45
+ objective=args.objective,
46
+ sensitive_columns=args.sensitive.split(",") if args.sensitive else None,
47
+ generate_pdf=not args.no_pdf,
48
+ )
49
+
50
+ if result.success:
51
+ print("\n" + "=" * 60)
52
+ print("EVALUATION COMPLETE")
53
+ print("=" * 60)
54
+ print(f"Dataset: {result.dataset}")
55
+ print(f"Target: {result.target_column or 'auto-detected'}")
56
+ print(f"Report Dir: {result.report_dir}")
57
+ if result.pdf_path:
58
+ print(f"PDF Report: {result.pdf_path}")
59
+ if result.markdown_path:
60
+ print(f"MD Report: {result.markdown_path}")
61
+ print(f"Stages: {', '.join(result.stages_completed)}")
62
+ if result.warnings:
63
+ print(f"\nWarnings ({len(result.warnings)}):")
64
+ for w in result.warnings:
65
+ print(f" - {w}")
66
+ return 0
67
+ else:
68
+ print("\n" + "=" * 60)
69
+ print("EVALUATION FAILED")
70
+ print("=" * 60)
71
+ print(f"Error: {result.error}")
72
+ return 1
73
+
74
+
75
+ def parse_args() -> argparse.Namespace:
76
+ """Parse command-line arguments."""
77
+
78
+ parser = argparse.ArgumentParser(
79
+ prog="fairness-eval",
80
+ description="Evaluate datasets for fairness and bias issues.",
81
+ formatter_class=argparse.RawDescriptionHelpFormatter,
82
+ epilog="""
83
+ Examples:
84
+ # Basic evaluation
85
+ equiaudit --data adult-all.csv --target Income
86
+
87
+ # Verify configuration
88
+ equiaudit --verify
89
+
90
+ # Custom config and output
91
+ equiaudit --config my_config.yml --data data.csv --output ./reports
92
+
93
+ # Specify model and sensitive columns
94
+ equiaudit --data data.csv --model gemini-flash --sensitive "age,sex,race"
95
+
96
+ Environment Variables:
97
+ OPENROUTER_API_KEY API key for OpenRouter models
98
+ GOOGLE_API_KEY API key for Gemini models
99
+ """,
100
+ )
101
+
102
+ # Data input
103
+ parser.add_argument(
104
+ "--data", "-d",
105
+ type=str,
106
+ help="Path to CSV dataset file",
107
+ )
108
+
109
+ parser.add_argument(
110
+ "--target", "-t",
111
+ type=str,
112
+ default=None,
113
+ help="Target column name for classification (auto-detected if not specified)",
114
+ )
115
+
116
+ parser.add_argument(
117
+ "--objective", "-o",
118
+ type=str,
119
+ default=None,
120
+ help="Custom evaluation objective/prompt",
121
+ )
122
+
123
+ parser.add_argument(
124
+ "--sensitive", "-s",
125
+ type=str,
126
+ default=None,
127
+ help="Comma-separated list of sensitive columns (auto-detected if not specified)",
128
+ )
129
+
130
+ # Configuration
131
+ parser.add_argument(
132
+ "--config", "-c",
133
+ type=str,
134
+ default=None,
135
+ help="Path to YAML configuration file (uses bundled default if omitted)",
136
+ )
137
+
138
+ parser.add_argument(
139
+ "--model", "-m",
140
+ type=str,
141
+ default=None,
142
+ help="Override default model from config",
143
+ )
144
+
145
+ parser.add_argument(
146
+ "--env-file", "-e",
147
+ type=str,
148
+ default=None,
149
+ help="Path to .env file for loading API keys",
150
+ )
151
+
152
+ # Output
153
+ parser.add_argument(
154
+ "--output", "-O",
155
+ type=str,
156
+ default=None,
157
+ help="Output directory for reports (default: reports/)",
158
+ )
159
+
160
+ parser.add_argument(
161
+ "--no-pdf",
162
+ action="store_true",
163
+ help="Skip PDF generation",
164
+ )
165
+
166
+ # Modes
167
+ parser.add_argument(
168
+ "--verify", "-V",
169
+ action="store_true",
170
+ help="Verify configuration only (don't run evaluation)",
171
+ )
172
+
173
+ parser.add_argument(
174
+ "--quiet", "-q",
175
+ action="store_true",
176
+ help="Suppress progress messages",
177
+ )
178
+
179
+ return parser.parse_args()
180
+
181
+
182
+ def load_env_file(env_path: str) -> None:
183
+ """Load environment variables from a .env file."""
184
+ env_path = Path(env_path)
185
+ if not env_path.exists():
186
+ print(f"Warning: .env file not found: {env_path}")
187
+ return
188
+
189
+ print(f"Loading environment from: {env_path}")
190
+
191
+ with open(env_path, "r") as f:
192
+ for line in f:
193
+ line = line.strip()
194
+ if not line or line.startswith("#"):
195
+ continue
196
+ if "=" in line:
197
+ key, value = line.split("=", 1)
198
+ key = key.strip()
199
+ value = value.strip().strip('"').strip("'")
200
+ os.environ[key] = value
201
+
202
+
203
+ if __name__ == "__main__":
204
+ sys.exit(main())