adri 0.1.0__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.
adri-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Think Evolve Solve
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
adri-0.1.0/MANIFEST.in ADDED
@@ -0,0 +1,6 @@
1
+ <![CDATA[
2
+ include LICENSE
3
+ include README.md
4
+ include pyproject.toml
5
+ recursive-include adri/templates *.html
6
+ ]]>
adri-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: adri
3
+ Version: 0.1.0
4
+ Summary: Agent Data Readiness Index - A framework for evaluating data quality for agentic AI systems
5
+ Author-email: Verodat <info@verodat.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/verodat/agent-data-readiness-index
8
+ Project-URL: Bug Tracker, https://github.com/verodat/agent-data-readiness-index/issues
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: pandas>=1.0.0
22
+ Requires-Dist: matplotlib>=3.3.0
23
+ Requires-Dist: jinja2>=3.0.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=2.12.0; extra == "dev"
28
+ Requires-Dist: black>=22.0.0; extra == "dev"
29
+ Requires-Dist: isort>=5.10.0; extra == "dev"
30
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
31
+ Requires-Dist: mypy>=0.9.0; extra == "dev"
32
+ Provides-Extra: database
33
+ Requires-Dist: sqlalchemy>=1.4.0; extra == "database"
34
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == "database"
35
+ Provides-Extra: api
36
+ Requires-Dist: requests>=2.25.0; extra == "api"
37
+ Provides-Extra: full
38
+ Requires-Dist: adri[api,database,dev]; extra == "full"
39
+ Dynamic: license-file
40
+
41
+ <![CDATA[
42
+ # Agent Data Readiness Index (ADRI)
43
+
44
+ ADRI is the industry’s first open standard for evaluating data quality for agentic AI systems. It provides a comprehensive, five-dimensional assessment of data sources by measuring Validity, Completeness, Freshness, Consistency, and Plausibility.
45
+
46
+ ## Installation
47
+
48
+ Install ADRI from PyPI:
49
+
50
+ ```bash
51
+ pip install adri
52
+ ```
53
+
54
+ > Note: If "adri" is already taken on PyPI, consider using an alternative package name (e.g., `agent-data-readiness-index`).
55
+
56
+ ## Quick Start
57
+
58
+ Run an assessment on your data source with:
59
+
60
+ ```bash
61
+ adri assess --source your_data.csv --output report
62
+ ```
63
+
64
+ Then, view the generated report with:
65
+
66
+ ```bash
67
+ adri report view report.json
68
+ ```
69
+
70
+ ## Features
71
+
72
+ - **Five-Dimensional Assessment:** Evaluates data sources across Validity, Completeness, Freshness, Consistency, and Plausibility.
73
+ - **Agent-Centric Evaluation:** Clearly communicates data quality attributes to AI agents.
74
+ - **Benchmarking:** Compare your scores against industry assessments.
75
+ - **Rich Reporting:** Generates outputs in both JSON and HTML formats.
76
+ - **Extensibility:** Designed to integrate with multiple data sources and environments.
77
+
78
+ ## Documentation
79
+
80
+ For detailed information, please refer to our [GitHub Wiki](https://github.com/verodat/agent-data-readiness-index/wiki) and additional documentation in the repository.
81
+
82
+ ## Contributing
83
+
84
+ We welcome contributions! To contribute:
85
+ 1. Fork the repository on GitHub.
86
+ 2. Run your assessments using ADRI.
87
+ 3. Submit your HTML report to the `docs/reports/` directory.
88
+ 4. Update the repository index and create a pull request.
89
+
90
+ For more details, see the [Contributing Guide](https://github.com/verodat/agent-data-readiness-index#contributing-to-the-benchmark).
91
+
92
+ ## License
93
+
94
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
95
+ ]]>
adri-0.1.0/README.md ADDED
@@ -0,0 +1,55 @@
1
+ <![CDATA[
2
+ # Agent Data Readiness Index (ADRI)
3
+
4
+ ADRI is the industry’s first open standard for evaluating data quality for agentic AI systems. It provides a comprehensive, five-dimensional assessment of data sources by measuring Validity, Completeness, Freshness, Consistency, and Plausibility.
5
+
6
+ ## Installation
7
+
8
+ Install ADRI from PyPI:
9
+
10
+ ```bash
11
+ pip install adri
12
+ ```
13
+
14
+ > Note: If "adri" is already taken on PyPI, consider using an alternative package name (e.g., `agent-data-readiness-index`).
15
+
16
+ ## Quick Start
17
+
18
+ Run an assessment on your data source with:
19
+
20
+ ```bash
21
+ adri assess --source your_data.csv --output report
22
+ ```
23
+
24
+ Then, view the generated report with:
25
+
26
+ ```bash
27
+ adri report view report.json
28
+ ```
29
+
30
+ ## Features
31
+
32
+ - **Five-Dimensional Assessment:** Evaluates data sources across Validity, Completeness, Freshness, Consistency, and Plausibility.
33
+ - **Agent-Centric Evaluation:** Clearly communicates data quality attributes to AI agents.
34
+ - **Benchmarking:** Compare your scores against industry assessments.
35
+ - **Rich Reporting:** Generates outputs in both JSON and HTML formats.
36
+ - **Extensibility:** Designed to integrate with multiple data sources and environments.
37
+
38
+ ## Documentation
39
+
40
+ For detailed information, please refer to our [GitHub Wiki](https://github.com/verodat/agent-data-readiness-index/wiki) and additional documentation in the repository.
41
+
42
+ ## Contributing
43
+
44
+ We welcome contributions! To contribute:
45
+ 1. Fork the repository on GitHub.
46
+ 2. Run your assessments using ADRI.
47
+ 3. Submit your HTML report to the `docs/reports/` directory.
48
+ 4. Update the repository index and create a pull request.
49
+
50
+ For more details, see the [Contributing Guide](https://github.com/verodat/agent-data-readiness-index#contributing-to-the-benchmark).
51
+
52
+ ## License
53
+
54
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
55
+ ]]>
@@ -0,0 +1,21 @@
1
+ """
2
+ Agent Data Readiness Index (ADRI)
3
+
4
+ A framework for evaluating how well data sources communicate their quality to AI agents.
5
+ """
6
+
7
+ import logging
8
+
9
+ from .assessor import DataSourceAssessor
10
+ from .report import AssessmentReport
11
+
12
+ __version__ = "0.1.0"
13
+ __author__ = "Verodat"
14
+
15
+ # Set up a null handler to avoid "No handler found" warnings
16
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
17
+
18
+ __all__ = [
19
+ "DataSourceAssessor",
20
+ "AssessmentReport",
21
+ ]
@@ -0,0 +1,188 @@
1
+ """
2
+ Core assessment logic for the Agent Data Readiness Index.
3
+
4
+ This module provides the main DataSourceAssessor class that coordinates
5
+ the assessment of data sources across all dimensions.
6
+ """
7
+
8
+ import logging
9
+ from pathlib import Path
10
+ from typing import Dict, List, Optional, Union, Any
11
+
12
+ from .dimensions import (
13
+ ValidityAssessor,
14
+ CompletenessAssessor,
15
+ FreshnessAssessor,
16
+ ConsistencyAssessor,
17
+ PlausibilityAssessor,
18
+ )
19
+ from .connectors import (
20
+ BaseConnector,
21
+ FileConnector,
22
+ DatabaseConnector,
23
+ APIConnector,
24
+ )
25
+ from .report import AssessmentReport
26
+ from .utils.validators import validate_config
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class DataSourceAssessor:
32
+ """
33
+ Main assessor class for evaluating data sources against the
34
+ Agent Data Readiness Index criteria.
35
+ """
36
+
37
+ def __init__(self, config: Optional[Dict[str, Any]] = None):
38
+ """
39
+ Initialize the assessor with optional custom configuration.
40
+
41
+ Args:
42
+ config: Optional configuration dictionary that can customize
43
+ dimension weights, thresholds, etc.
44
+ """
45
+ self.config = config or {}
46
+ validate_config(self.config)
47
+
48
+ # Initialize dimension assessors
49
+ self.dimensions = {
50
+ "validity": ValidityAssessor(self.config.get("validity", {})),
51
+ "completeness": CompletenessAssessor(self.config.get("completeness", {})),
52
+ "freshness": FreshnessAssessor(self.config.get("freshness", {})),
53
+ "consistency": ConsistencyAssessor(self.config.get("consistency", {})),
54
+ "plausibility": PlausibilityAssessor(self.config.get("plausibility", {})),
55
+ }
56
+
57
+ def assess_file(
58
+ self, file_path: Union[str, Path], file_type: Optional[str] = None
59
+ ) -> AssessmentReport:
60
+ """
61
+ Assess a file-based data source.
62
+
63
+ Args:
64
+ file_path: Path to the file to assess
65
+ file_type: Optional file type override (csv, json, etc.)
66
+
67
+ Returns:
68
+ AssessmentReport: The assessment results
69
+ """
70
+ connector = FileConnector(file_path, file_type)
71
+ return self.assess_source(connector)
72
+
73
+ def assess_database(
74
+ self, connection_string: str, table_name: str
75
+ ) -> AssessmentReport:
76
+ """
77
+ Assess a database table.
78
+
79
+ Args:
80
+ connection_string: Database connection string
81
+ table_name: Name of the table to assess
82
+
83
+ Returns:
84
+ AssessmentReport: The assessment results
85
+ """
86
+ connector = DatabaseConnector(connection_string, table_name)
87
+ return self.assess_source(connector)
88
+
89
+ def assess_api(self, endpoint: str, auth: Optional[Dict[str, Any]] = None) -> AssessmentReport:
90
+ """
91
+ Assess an API endpoint.
92
+
93
+ Args:
94
+ endpoint: API endpoint URL
95
+ auth: Optional authentication details
96
+
97
+ Returns:
98
+ AssessmentReport: The assessment results
99
+ """
100
+ connector = APIConnector(endpoint, auth)
101
+ return self.assess_source(connector)
102
+
103
+ def assess_source(self, connector: BaseConnector) -> AssessmentReport:
104
+ """
105
+ Assess any data source using a connector.
106
+
107
+ Args:
108
+ connector: Data source connector instance
109
+
110
+ Returns:
111
+ AssessmentReport: The assessment results
112
+ """
113
+ logger.info(f"Starting assessment of {connector}")
114
+
115
+ # Initialize report
116
+ report = AssessmentReport(
117
+ source_name=connector.get_name(),
118
+ source_type=connector.get_type(),
119
+ source_metadata=connector.get_metadata(),
120
+ )
121
+
122
+ # Assess each dimension
123
+ dimension_results = {}
124
+ for dim_name, assessor in self.dimensions.items():
125
+ logger.debug(f"Assessing {dim_name} dimension")
126
+ score, findings, recommendations = assessor.assess(connector)
127
+ dimension_results[dim_name] = {
128
+ "score": score,
129
+ "findings": findings,
130
+ "recommendations": recommendations,
131
+ }
132
+ logger.debug(f"{dim_name} score: {score}")
133
+
134
+ # Calculate overall score and populate report
135
+ report.populate_from_dimension_results(dimension_results)
136
+
137
+ logger.info(f"Assessment complete. Overall score: {report.overall_score}")
138
+ return report
139
+
140
+ def assess_from_config(self, config_path: Union[str, Path]) -> Dict[str, AssessmentReport]:
141
+ """
142
+ Assess multiple data sources specified in a configuration file.
143
+
144
+ Args:
145
+ config_path: Path to the configuration file
146
+
147
+ Returns:
148
+ Dict[str, AssessmentReport]: Dictionary of assessment reports
149
+ keyed by source name
150
+ """
151
+ import yaml
152
+
153
+ with open(config_path, 'r') as f:
154
+ config = yaml.safe_load(f)
155
+
156
+ reports = {}
157
+ for source_config in config.get('sources', []):
158
+ source_name = source_config.get('name', 'Unknown')
159
+ source_type = source_config.get('type')
160
+
161
+ logger.info(f"Assessing {source_name} ({source_type})")
162
+
163
+ try:
164
+ if source_type == 'file':
165
+ report = self.assess_file(
166
+ source_config['path'],
167
+ source_config.get('file_type')
168
+ )
169
+ elif source_type == 'database':
170
+ report = self.assess_database(
171
+ source_config['connection'],
172
+ source_config['table']
173
+ )
174
+ elif source_type == 'api':
175
+ report = self.assess_api(
176
+ source_config['endpoint'],
177
+ source_config.get('auth')
178
+ )
179
+ else:
180
+ logger.error(f"Unknown source type: {source_type}")
181
+ continue
182
+
183
+ reports[source_name] = report
184
+
185
+ except Exception as e:
186
+ logger.error(f"Error assessing {source_name}: {e}")
187
+
188
+ return reports
adri-0.1.0/adri/cli.py ADDED
@@ -0,0 +1,179 @@
1
+ """
2
+ Command-line interface for the Agent Data Readiness Index.
3
+
4
+ This module provides a command-line interface for running ADRI assessments
5
+ and generating reports.
6
+ """
7
+
8
+ import argparse
9
+ import logging
10
+ import sys
11
+ from pathlib import Path
12
+ from typing import List, Optional
13
+
14
+ from .assessor import DataSourceAssessor
15
+ from .report import AssessmentReport
16
+
17
+
18
+ def setup_logging(verbose: bool = False):
19
+ """Set up logging with appropriate level based on verbosity."""
20
+ level = logging.DEBUG if verbose else logging.INFO
21
+ logging.basicConfig(
22
+ level=level,
23
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
24
+ handlers=[logging.StreamHandler()],
25
+ )
26
+
27
+
28
+ def parse_args(args: Optional[List[str]] = None):
29
+ """Parse command-line arguments."""
30
+ parser = argparse.ArgumentParser(
31
+ description="Agent Data Readiness Index - Evaluate data sources for agent readiness"
32
+ )
33
+
34
+ subparsers = parser.add_subparsers(dest="command", help="Command to run")
35
+
36
+ # assess command
37
+ assess_parser = subparsers.add_parser("assess", help="Assess a data source")
38
+ source_group = assess_parser.add_mutually_exclusive_group(required=True)
39
+ source_group.add_argument("--source", help="Path to data source or connection string")
40
+ source_group.add_argument("--config", help="Path to configuration file for multiple sources")
41
+ assess_parser.add_argument("--output", required=True, help="Output path for the report")
42
+ assess_parser.add_argument(
43
+ "--format",
44
+ choices=["json", "html", "both"],
45
+ default="both",
46
+ help="Output format(s) for the report"
47
+ )
48
+ assess_parser.add_argument(
49
+ "--source-type",
50
+ choices=["file", "database", "api"],
51
+ help="Type of the data source (auto-detected if not specified)"
52
+ )
53
+ assess_parser.add_argument("--table", help="Table name for database sources")
54
+ assess_parser.add_argument("--custom-config", help="Path to custom assessment configuration")
55
+
56
+ # report command
57
+ report_parser = subparsers.add_parser("report", help="Work with assessment reports")
58
+ report_subparsers = report_parser.add_subparsers(dest="report_command", help="Report command")
59
+
60
+ # report view command
61
+ view_parser = report_subparsers.add_parser("view", help="View an assessment report")
62
+ view_parser.add_argument("report_path", help="Path to the report file")
63
+
64
+ # Common arguments
65
+ parser.add_argument("--verbose", "-v", action="store_true", help="Enable verbose logging")
66
+
67
+ return parser.parse_args(args)
68
+
69
+
70
+ def run_assessment(args):
71
+ """Run an assessment based on command-line arguments."""
72
+ assessor = DataSourceAssessor()
73
+
74
+ if args.config:
75
+ # Assess multiple sources from config file
76
+ reports = assessor.assess_from_config(args.config)
77
+
78
+ # Save all reports
79
+ for source_name, report in reports.items():
80
+ base_path = Path(args.output)
81
+ output_dir = base_path if base_path.is_dir() else base_path.parent
82
+ file_prefix = f"{source_name.replace(' ', '_').lower()}_"
83
+
84
+ if args.format in ("json", "both"):
85
+ report.save_json(output_dir / f"{file_prefix}report.json")
86
+
87
+ if args.format in ("html", "both"):
88
+ report.save_html(output_dir / f"{file_prefix}report.html")
89
+
90
+ # Print summary to console
91
+ report.print_summary()
92
+
93
+ else:
94
+ # Assess a single source
95
+ source = args.source
96
+
97
+ if args.source_type == "file" or (not args.source_type and Path(source).is_file()):
98
+ report = assessor.assess_file(source)
99
+ elif args.source_type == "database" or (not args.source_type and "://" in source):
100
+ if not args.table:
101
+ raise ValueError("Table name is required for database sources")
102
+ report = assessor.assess_database(source, args.table)
103
+ elif args.source_type == "api":
104
+ report = assessor.assess_api(source)
105
+ else:
106
+ raise ValueError(f"Could not determine source type for: {source}")
107
+
108
+ # Save the report
109
+ if args.format in ("json", "both"):
110
+ report.save_json(f"{args.output}.json" if not args.output.endswith(".json") else args.output)
111
+
112
+ if args.format in ("html", "both"):
113
+ report.save_html(f"{args.output}.html" if not args.output.endswith(".html") else args.output)
114
+
115
+ # Print summary to console
116
+ report.print_summary()
117
+
118
+
119
+ def view_report(args):
120
+ """View a report."""
121
+ report = AssessmentReport.load_json(args.report_path)
122
+ report.print_summary()
123
+
124
+ def submit_benchmark(args):
125
+ """Submit a report to the benchmark."""
126
+ from datetime import datetime
127
+ import uuid
128
+ report = AssessmentReport.load_json(args.report_path)
129
+
130
+ # This would typically upload to a benchmark service
131
+ # For GitHub-based solution, we'll save to the benchmark directory
132
+ benchmark_dir = Path(__file__).parent.parent / "benchmark" / "data"
133
+ benchmark_dir.mkdir(parents=True, exist_ok=True)
134
+
135
+ # Anonymize if requested
136
+ if hasattr(args, "anonymize") and args.anonymize:
137
+ # Keep only necessary data for benchmarking
138
+ report.source_name = f"Anonymous {args.industry} Source"
139
+ report.source_metadata = {
140
+ "industry": args.industry,
141
+ "anonymized": True,
142
+ "submission_date": datetime.now().isoformat(),
143
+ }
144
+
145
+ # Generate a unique ID for the submission
146
+ benchmark_id = str(uuid.uuid4())[:8]
147
+ benchmark_file = benchmark_dir / f"{args.industry.lower().replace(' ', '_')}_{benchmark_id}.json"
148
+ report.save_json(benchmark_file)
149
+
150
+ print(f"Report submitted to benchmark as {benchmark_file.name}")
151
+ print("The benchmark will be updated automatically within 24 hours.")
152
+ print("You can view the updated benchmark at https://username.github.io/agent-data-readiness-index/")
153
+
154
+ def main(args=None):
155
+ """Main entry point for the CLI."""
156
+ parsed_args = parse_args(args)
157
+ setup_logging(parsed_args.verbose)
158
+
159
+ try:
160
+ if parsed_args.command == "assess":
161
+ run_assessment(parsed_args)
162
+ elif parsed_args.command == "report":
163
+ if parsed_args.report_command == "view":
164
+ view_report(parsed_args)
165
+ else:
166
+ print("No command specified. Use --help for usage information.")
167
+ return 1
168
+ except Exception as e:
169
+ logging.error(f"Error: {e}")
170
+ if parsed_args.verbose:
171
+ import traceback
172
+ traceback.print_exc()
173
+ return 1
174
+
175
+ return 0
176
+
177
+
178
+ if __name__ == "__main__":
179
+ sys.exit(main())