precisionai-agrieval 0.1.0.dev0__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 (62) hide show
  1. precisionai_agrieval-0.1.0.dev0/.gitattributes +12 -0
  2. precisionai_agrieval-0.1.0.dev0/.gitignore +203 -0
  3. precisionai_agrieval-0.1.0.dev0/.pre-commit-config.yaml +46 -0
  4. precisionai_agrieval-0.1.0.dev0/CHANGELOG.md +18 -0
  5. precisionai_agrieval-0.1.0.dev0/CLAUDE.md +218 -0
  6. precisionai_agrieval-0.1.0.dev0/CODE_OF_CONDUCT.md +67 -0
  7. precisionai_agrieval-0.1.0.dev0/CONTRIBUTING.md +75 -0
  8. precisionai_agrieval-0.1.0.dev0/LICENSE.md +201 -0
  9. precisionai_agrieval-0.1.0.dev0/MANIFEST.in +11 -0
  10. precisionai_agrieval-0.1.0.dev0/PKG-INFO +441 -0
  11. precisionai_agrieval-0.1.0.dev0/README.md +184 -0
  12. precisionai_agrieval-0.1.0.dev0/SECURITY.md +63 -0
  13. precisionai_agrieval-0.1.0.dev0/precisionai/__init__.py +2 -0
  14. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/__init__.py +2 -0
  15. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/api/__init__.py +2 -0
  16. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/api/app.py +103 -0
  17. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/api/config.py +31 -0
  18. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/__init__.py +28 -0
  19. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/api/__init__.py +2 -0
  20. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/api/app.py +114 -0
  21. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/api/config.py +8 -0
  22. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/api/routes/__init__.py +2 -0
  23. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/api/routes/evaluate.py +126 -0
  24. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/__init__.py +115 -0
  25. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/_utils.py +240 -0
  26. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/analysis.py +202 -0
  27. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/cross_model.py +235 -0
  28. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/duplicates.py +190 -0
  29. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/geometry.py +282 -0
  30. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/label_aware.py +805 -0
  31. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/neighbors.py +195 -0
  32. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/ranking.py +258 -0
  33. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/metrics/similarity.py +212 -0
  34. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/schemas/__init__.py +14 -0
  35. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/schemas/evaluate.py +471 -0
  36. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/services/__init__.py +2 -0
  37. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/services/evaluate.py +1117 -0
  38. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/emb/services/reporting.py +754 -0
  39. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/__init__.py +9 -0
  40. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/api/__init__.py +2 -0
  41. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/api/config.py +8 -0
  42. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/api/routes/__init__.py +2 -0
  43. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/api/routes/evaluate.py +75 -0
  44. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/cli.py +73 -0
  45. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/metrics/__init__.py +22 -0
  46. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/metrics/segmentation.py +165 -0
  47. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/schemas/__init__.py +2 -0
  48. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/schemas/evaluate.py +129 -0
  49. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/services/__init__.py +2 -0
  50. precisionai_agrieval-0.1.0.dev0/precisionai/agrieval/seg/services/evaluate.py +573 -0
  51. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/PKG-INFO +441 -0
  52. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/SOURCES.txt +60 -0
  53. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/dependency_links.txt +1 -0
  54. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/entry_points.txt +4 -0
  55. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/requires.txt +30 -0
  56. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/scm_file_list.json +201 -0
  57. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/scm_version.json +8 -0
  58. precisionai_agrieval-0.1.0.dev0/precisionai_agrieval.egg-info/top_level.txt +1 -0
  59. precisionai_agrieval-0.1.0.dev0/pyproject.toml +177 -0
  60. precisionai_agrieval-0.1.0.dev0/requirements-dev.txt +20 -0
  61. precisionai_agrieval-0.1.0.dev0/requirements.txt +6 -0
  62. precisionai_agrieval-0.1.0.dev0/setup.cfg +4 -0
@@ -0,0 +1,12 @@
1
+ # Normalize line endings to LF on commit, regardless of editor/OS settings.
2
+ * text=auto eol=lf
3
+
4
+ # Treat binary files as binary (no line-ending conversion).
5
+ *.png binary
6
+ *.jpg binary
7
+ *.jpeg binary
8
+ *.JPG binary
9
+ *.JPEG binary
10
+ *.svg binary
11
+ *.pdf binary
12
+ *.ipynb text eol=lf
@@ -0,0 +1,203 @@
1
+ # Existing project-specific ignores
2
+ .venv/
3
+ exports/
4
+ lightning_logs/
5
+ .streamlit/users.json
6
+ .streamlit/secrets.toml
7
+
8
+ # Byte-compiled / optimized / DLL files
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ develop-eggs/
20
+ dist/
21
+ downloads/
22
+ eggs/
23
+ .eggs/
24
+ lib/
25
+ lib64/
26
+ parts/
27
+ sdist/
28
+ var/
29
+ wheels/
30
+ share/python-wheels/
31
+ *.egg-info/
32
+ .installed.cfg
33
+ *.egg
34
+ MANIFEST
35
+
36
+ # PyInstaller
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py,cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+ temp/
63
+
64
+ # Django stuff:
65
+ *.log
66
+ local_settings.py
67
+ db.sqlite3
68
+ db.sqlite3-journal
69
+
70
+ # Flask stuff:
71
+ instance/
72
+ .webassets-cache
73
+
74
+ # Scrapy stuff:
75
+ .scrapy
76
+
77
+ # Sphinx documentation
78
+ docs/_build/
79
+
80
+ # PyBuilder
81
+ .pybuilder/
82
+ target/
83
+
84
+ # Jupyter Notebook
85
+ .ipynb_checkpoints
86
+
87
+ # IPython
88
+ profile_default/
89
+ ipython_config.py
90
+
91
+ # pyenv
92
+ .python-version
93
+
94
+ # pipenv
95
+ Pipfile.lock
96
+
97
+ # poetry
98
+ poetry.lock
99
+
100
+ # pdm
101
+ .pdm.toml
102
+
103
+ # PEP 582
104
+ __pypackages__/
105
+
106
+ # Celery stuff
107
+ celerybeat-schedule
108
+ celerybeat.pid
109
+
110
+ # SageMath parsed files
111
+ *.sage.py
112
+
113
+ # Environments
114
+ .env
115
+ .venv
116
+ env/
117
+ venv/
118
+ ENV/
119
+ env.bak/
120
+ venv.bak/
121
+
122
+ # Spyder project settings
123
+ .spyderproject
124
+ .spyproject
125
+
126
+ # Rope project settings
127
+ .ropeproject
128
+
129
+ # mkdocs documentation
130
+ /site
131
+
132
+ # mypy
133
+ .mypy_cache/
134
+ .dmypy.json
135
+ dmypy.json
136
+
137
+ # Pyre type checker
138
+ .pyre/
139
+
140
+ # pytype static type analyzer
141
+ .pytype/
142
+
143
+ # Cython debug symbols
144
+ cython_debug/
145
+
146
+ # PyCharm
147
+ .idea/
148
+
149
+ # VS Code
150
+ .vscode/
151
+
152
+ # PyTorch / Machine Learning
153
+ *.pth
154
+ *.pt
155
+ *.ckpt
156
+ *.pkl
157
+ *.h5
158
+ *.hdf5
159
+ *.onnx
160
+ *.pb
161
+ *.tflite
162
+ *.tfl
163
+ *.pdf
164
+ checkpoints/
165
+ models/
166
+ weights/
167
+ wandb/
168
+ mlruns/
169
+ .neptune/
170
+
171
+ # OS files
172
+ .DS_Store
173
+ .DS_Store?
174
+ ._*
175
+ .Spotlight-V100
176
+ .Trashes
177
+ ehthumbs.db
178
+ Thumbs.db
179
+ *~
180
+
181
+ # Temporary files
182
+ *.tmp
183
+ *.temp
184
+ *.swp
185
+ *.swo
186
+ *~
187
+
188
+ # Data files (uncomment if you don't want to track datasets)
189
+ # *.csv
190
+ # *.json
191
+ # *.parquet
192
+ # *.h5
193
+ # *.hdf5
194
+ # data/
195
+ dataset/
196
+ output/
197
+
198
+ # packaging artifacts
199
+ *.egg-info/
200
+ dist/
201
+ build/
202
+
203
+ dummy_input.json
@@ -0,0 +1,46 @@
1
+ repos:
2
+ # ── File hygiene ────────────────────────────────────────────────────────────
3
+ - repo: https://github.com/pre-commit/pre-commit-hooks
4
+ rev: v6.0.0
5
+ hooks:
6
+ - id: check-added-large-files
7
+ # Keep committed test/image fixtures small enough for fast clones and CI.
8
+ args: ["--maxkb=1800"]
9
+ - id: check-yaml
10
+ - id: check-json
11
+ - id: check-toml
12
+ - id: end-of-file-fixer
13
+ - id: trailing-whitespace
14
+ - id: check-merge-conflict
15
+ - id: detect-private-key
16
+ - id: debug-statements
17
+ - id: fix-byte-order-marker
18
+
19
+ # ── Ruff: lint + format + import sorting ───────────────────────────────────
20
+ - repo: https://github.com/astral-sh/ruff-pre-commit
21
+ rev: v0.15.17
22
+ hooks:
23
+ - id: ruff
24
+ args: ["--fix"]
25
+ - id: ruff-format
26
+
27
+ # ── Type checking (pyright / pylance engine) ────────────────────────────────
28
+ - repo: local
29
+ hooks:
30
+ - id: pyright
31
+ name: pyright
32
+ entry: python -m pyright
33
+ language: system
34
+ types: [python]
35
+ pass_filenames: false
36
+
37
+ # ── Tests + coverage (≥ 90%) ────────────────────────────────────────────────
38
+ - repo: local
39
+ hooks:
40
+ - id: pytest
41
+ name: pytest (coverage ≥ 90%)
42
+ entry: python -m pytest
43
+ language: system
44
+ args: ["tests/emb/", "tests/seg/", "-q", "--tb=short", "--no-header"]
45
+ pass_filenames: false
46
+ always_run: true
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - Initial public release
11
+
12
+ - `precisionai.agrieval.emb` — embedding evaluation: KNN retrieval benchmarking (nDCG, MAP, MRR, purity), geometry diagnostics, and interactive visualizations.
13
+ - `precisionai.agrieval.seg` — semantic segmentation evaluation: per-class IoU, Dice/F1, accuracy, mIoU, mAcc, FWIoU from colour-coded masks.
14
+ - Unified FastAPI server exposing both subpackages, plus a standalone segmentation CLI (`precisionai-agrieval-seg`).
15
+ - Top-level re-exports on both subpackages so the primary entry points can be imported directly, e.g. `from precisionai.agrieval.emb import run_image2image_eval` and `from precisionai.agrieval.seg import run_seg_eval`.
16
+
17
+ [Unreleased]: https://github.com/Precision-AI-Inc/agrieval/compare/v0.1.0...HEAD
18
+ [0.1.0]: https://github.com/Precision-AI-Inc/agrieval/releases/tag/v0.1.0
@@ -0,0 +1,218 @@
1
+ # Precision AI — Python Project Standards
2
+
3
+ Apply these standards when writing, reviewing, or refactoring code in any PAI Python project.
4
+
5
+ ---
6
+
7
+ ## Environment
8
+
9
+ - Python 3.10+, managed with `python -m venv .venv` (never conda)
10
+ - Install: `pip install -e ".[dev]"` → installs all deps including pre-commit
11
+ - Register hooks once: `pre-commit install`
12
+
13
+ ---
14
+
15
+ ## Project layout
16
+
17
+ ```
18
+ precisionai/<namespace>/<subpackage>/
19
+ api/
20
+ routes/ # FastAPI route handlers (thin — delegate to services)
21
+ config.py # env-var config only
22
+ app.py # FastAPI app factory
23
+ schemas/ # Pydantic v2 request/response models
24
+ services/ # Business logic (evaluate.py, reporting.py, …)
25
+ metrics/ # Pure computation modules
26
+ __init__.py # re-exports only — no logic
27
+ docs/ # Sphinx (HTML + LaTeX/PDF)
28
+ tests/<subpackage>/ # mirrors precisionai.<namespace>.<subpackage>, e.g. tests/emb/, tests/seg/
29
+ examples/<subpackage>/ # standalone runnable scripts, e.g. examples/emb/, examples/seg/
30
+ ```
31
+
32
+ ---
33
+
34
+ ## pyproject.toml — canonical config
35
+
36
+ ```toml
37
+ [tool.ruff]
38
+ line-length = 120
39
+ target-version = "py310"
40
+
41
+ [tool.ruff.lint]
42
+ select = ["E","W","F","I","UP","B","SIM","N","C90","D","PT","RUF","PL","ANN","PERF","S"]
43
+ ignore = [
44
+ "E501", # enforced by ruff-format
45
+ "B008", # FastAPI default-arg pattern
46
+ "SIM108", # ternary readability
47
+ "D100","D104", # module/package docstrings optional
48
+ "D203","D213", # pydocstyle conflicts — always ignore these two
49
+ "PLR0913","PLR2004", # arg count + magic values common in metrics/tests
50
+ "ANN401", # Any is allowed for genuinely dynamic types
51
+ "S311", # pseudo-random generators are intentional in scientific code
52
+ "S104", # binding to 0.0.0.0 is intentional for a configurable server host
53
+ ]
54
+ [tool.ruff.lint.per-file-ignores]
55
+ "**/__init__.py" = ["F401"]
56
+ "tests/<subpackage>/**" = ["D","PLR","ANN","S"] # e.g. tests/emb/**, tests/seg/**
57
+ "docs/conf.py" = ["E402","UP031","ANN","S"]
58
+
59
+ [tool.ruff.lint.pydocstyle]
60
+ convention = "numpy" # enforces NumPy docstring style
61
+
62
+ [tool.ruff.lint.mccabe]
63
+ max-complexity = 10
64
+
65
+ [tool.ruff.lint.isort]
66
+ known-first-party = ["precisionai"] # adjust namespace per project
67
+
68
+ [tool.ruff.format]
69
+ quote-style = "double"
70
+ indent-style = "space"
71
+ docstring-code-format = true # formats code blocks inside docstrings
72
+
73
+ [tool.pytest.ini_options]
74
+ addopts = "--cov=precisionai --cov-report=term-missing --cov-fail-under=90"
75
+
76
+ [tool.coverage.report]
77
+ fail_under = 90
78
+ exclude_lines = ["pragma: no cover","if __name__ == .__main__.:",
79
+ "raise ImportError","except ImportError"]
80
+
81
+ [tool.pyright]
82
+ pythonVersion = "3.10"
83
+ typeCheckingMode = "standard"
84
+ reportMissingImports = false
85
+ reportMissingModuleSource = false
86
+ ```
87
+
88
+ ---
89
+
90
+ ## pre-commit
91
+
92
+ ```yaml
93
+ repos:
94
+ - repo: https://github.com/pre-commit/pre-commit-hooks
95
+ rev: v6.0.0
96
+ hooks: [check-added-large-files (--maxkb=1800), check-yaml, check-json,
97
+ check-toml, end-of-file-fixer, trailing-whitespace,
98
+ check-merge-conflict, detect-private-key, debug-statements,
99
+ fix-byte-order-marker]
100
+
101
+ - repo: https://github.com/astral-sh/ruff-pre-commit
102
+ rev: v0.15.17
103
+ hooks: [ruff (--fix), ruff-format]
104
+
105
+ - repo: local
106
+ hooks:
107
+ - id: pyright
108
+ name: pyright
109
+ entry: python -m pyright
110
+ language: system
111
+ types: [python]
112
+ pass_filenames: false
113
+
114
+ - repo: local
115
+ hooks:
116
+ - id: pytest
117
+ entry: python -m pytest
118
+ language: system
119
+ args: [tests/emb/, tests/seg/, -q, --tb=short, --no-header]
120
+ always_run: true
121
+ ```
122
+
123
+ ---
124
+
125
+ ## Code style
126
+
127
+ ### Imports
128
+ - All imports at the **top of the file** — never inside functions
129
+ - Optional/unavailable deps: module-level `try/except ImportError` with a flag variable
130
+ - No silent fallbacks unless mathematically equivalent (document why)
131
+ - `__init__.py` re-exports only — no logic, no comments between import blocks
132
+ - `__all__` must be **alphabetically sorted**
133
+
134
+ ```python
135
+ # optional dep pattern
136
+ try:
137
+ import plotly.graph_objects as go # type: ignore[import]
138
+ _PLOTLY_AVAILABLE = True
139
+ except ImportError:
140
+ _PLOTLY_AVAILABLE = False
141
+
142
+ # inside function that needs it
143
+ if not _PLOTLY_AVAILABLE:
144
+ raise ImportError("plotly is required: pip install plotly") from None
145
+ ```
146
+
147
+ ### Docstrings
148
+ - **NumPy style** on all public functions, classes, and modules
149
+ - Module docstrings: plain English, no prefixes (no P0/P1/P2, no "original", no labels)
150
+ - One-line summary in **imperative mood** ("Compute …", "Return …", "Save …")
151
+ - Blank line between summary and extended description (D205)
152
+
153
+ ### Type hints
154
+ - Required on **all** function signatures (public and private) — enforced by ruff (`ANN`) and pyright
155
+ - Use `X | Y` union syntax (Python 3.10+), not `Union[X, Y]` or `(X, Y)` in isinstance
156
+ - Use `Any` from `typing` for genuinely dynamic types — don't use `object` when methods will be called on it
157
+ - pyright config lives in `[tool.pyright]` in `pyproject.toml` — never pass type-checker flags inline
158
+
159
+ ### Comments
160
+ - Only when the **why** is non-obvious
161
+ - No section-divider comments that describe what the code already says
162
+ - No cryptic labels, no TODO/FIXME without a ticket reference
163
+
164
+ ### Exception handling
165
+ - Always `raise X from err` or `raise X from None` inside `except` blocks (B904)
166
+
167
+ ### General
168
+ - `len()` returns `int` — never `int(len(...))`
169
+ - Loop variables not used in the body → rename to `_`
170
+ - `assert a and b` in tests → split into separate asserts
171
+ - `@pytest.fixture` not `@pytest.fixture()`
172
+ - `pytest.raises` always includes `match=` parameter
173
+ - No `# type: ignore[attr-defined]` when `Any` already covers the attribute
174
+
175
+ ---
176
+
177
+ ## Docs (Sphinx)
178
+
179
+ ```
180
+ docs/
181
+ conf.py # version from git tag, logo, LaTeX/fancyhdr, enumitem fix
182
+ index.rst # toctree: readme, modules
183
+ modules.rst # autodoc for all public submodules
184
+ requirements.txt # sphinx, sphinx-rtd-theme, myst-parser, sphinx-autodoc-typehints
185
+ Makefile # make html | make latexpdf | make clean
186
+ assets/logo.png
187
+ ```
188
+
189
+ - `conf.py` copies root `README.md` → `docs/readme.md` at build time
190
+ - Version read from `git describe --tags --exact-match`, falls back to `0.0.0`
191
+
192
+ ---
193
+
194
+ ## Testing
195
+
196
+ - Mirror package structure: `tests/<subpackage>/test_<module>.py` (e.g. `tests/emb/`, `tests/seg/`)
197
+ - Shared fixtures in each subpackage's `tests/<subpackage>/conftest.py`
198
+ - 90% coverage hard minimum — enforced by pytest and pre-commit
199
+ - No mocks for database/filesystem unless truly unavoidable
200
+ - Integration tests marked `@pytest.mark.integration` and excluded from default runs
201
+
202
+ ---
203
+
204
+ ## What to avoid
205
+
206
+ | Pattern | Instead |
207
+ |---|---|
208
+ | `int(len(x))` | `len(x)` |
209
+ | `isinstance(x, (A, B))` | `isinstance(x, A \| B)` |
210
+ | `assert a and b` (tests) | two separate asserts |
211
+ | `@pytest.fixture()` | `@pytest.fixture` |
212
+ | `pytest.raises(ValueError)` | `pytest.raises(ValueError, match="…")` |
213
+ | `raise X` inside except | `raise X from None` or `raise X from err` |
214
+ | Deferred imports inside functions | Module-level try/except with flag |
215
+ | Cryptic prefixes (P0–P4, "original") | Plain descriptive names |
216
+ | `# type: ignore[attr-defined]` on `Any` | Remove — redundant |
217
+ | `# noqa` suppression | Fix the underlying issue |
218
+ | Silent fallback for optional dep | Raise `ImportError` with install hint |
@@ -0,0 +1,67 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment:
18
+
19
+ - Demonstrating empathy and kindness toward other people
20
+ - Being respectful of differing opinions, viewpoints, and experiences
21
+ - Giving and gracefully accepting constructive feedback
22
+ - Accepting responsibility and apologizing to those affected by our mistakes,
23
+ and learning from the experience
24
+ - Focusing on what is best not just for us as individuals, but for the overall
25
+ community
26
+
27
+ Examples of unacceptable behavior:
28
+
29
+ - The use of sexualized language or imagery, and sexual attention or advances
30
+ of any kind
31
+ - Trolling, insulting or derogatory comments, and personal or political attacks
32
+ - Public or private harassment
33
+ - Publishing others' private information, such as a physical or email address,
34
+ without their explicit permission
35
+ - Other conduct which could reasonably be considered inappropriate in a
36
+ professional setting
37
+
38
+ ## Enforcement Responsibilities
39
+
40
+ Community leaders are responsible for clarifying and enforcing our standards of
41
+ acceptable behavior and will take appropriate and fair corrective action in
42
+ response to any behavior that they deem inappropriate, threatening, offensive,
43
+ or harmful.
44
+
45
+ ## Scope
46
+
47
+ This Code of Conduct applies within all community spaces, and also applies when
48
+ an individual is officially representing the community in public spaces.
49
+
50
+ ## Enforcement
51
+
52
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
53
+ reported to the community leaders responsible for enforcement at
54
+ **michael@precision.ai**. All complaints will be reviewed and investigated
55
+ promptly and fairly.
56
+
57
+ All community leaders are obligated to respect the privacy and security of the
58
+ reporter of any incident.
59
+
60
+ ## Attribution
61
+
62
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
63
+ version 2.1, available at
64
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
65
+
66
+ [homepage]: https://www.contributor-covenant.org
67
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
@@ -0,0 +1,75 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in contributing to Precision AI AgriEval.
4
+
5
+ By participating in this project, you agree to abide by the [Code of Conduct](CODE_OF_CONDUCT.md).
6
+
7
+ ## Setup
8
+
9
+ Requires Python 3.10+.
10
+
11
+ ```bash
12
+ git clone https://github.com/Precision-AI-Inc/agrieval.git
13
+ cd agrieval
14
+
15
+ python -m venv .venv
16
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
17
+
18
+ pip install -e ".[dev]"
19
+ pre-commit install
20
+ ```
21
+
22
+ `pip install -e ".[dev]"` installs all dependencies including test, analysis, and pre-commit tooling. `pre-commit install` registers the hooks so they run automatically on every commit.
23
+
24
+ ## Making changes
25
+
26
+ 1. Create a branch from `main`.
27
+ 2. Make your changes.
28
+ 3. Add or update tests — coverage must remain at or above 90%.
29
+ 4. Commit. Pre-commit hooks run automatically and will block the commit if any check fails.
30
+
31
+ If a hook auto-fixes files (ruff lint/format), stage the changes and commit again.
32
+
33
+ ## Pre-commit hooks
34
+
35
+ | Hook | What it checks |
36
+ |---|---|
37
+ | File hygiene | Large files (>1800 KB), trailing whitespace, merge conflicts, private keys, debug statements, BOM removal |
38
+ | `ruff` | Linting and import sorting (auto-fix); includes `ANN` rules that enforce PEP 484 annotations |
39
+ | `ruff-format` | Code formatting (auto-fix) |
40
+ | `pyright` | Static type checking (pylance engine) — config in `[tool.pyright]` in `pyproject.toml` |
41
+ | `pytest` | Full test suite with ≥ 90% coverage |
42
+
43
+ To run all hooks manually without committing:
44
+
45
+ ```bash
46
+ pre-commit run --all-files
47
+ ```
48
+
49
+ ## Code style
50
+
51
+ - **Formatter / linter:** ruff (`line-length = 120`, Python 3.10 target).
52
+ - **Type hints:** all functions (public and private) must have complete PEP 484 type annotations. Enforced at lint time by ruff (`ANN` rules) and statically by pyright. `Any` is allowed for genuinely dynamic types; explicit `Any` is preferred over `object` when methods will be called on a value.
53
+ - **Docstrings:** NumPy style for all public functions, classes, and modules.
54
+ - **Comments:** only where the _why_ is non-obvious. No inline narration of what the code does.
55
+
56
+ ## Tests
57
+
58
+ ```bash
59
+ pytest # run all tests with coverage report
60
+ pytest tests/emb/test_metrics.py # run a specific file
61
+ pytest tests/seg/ # run a single subpackage
62
+ pytest -k "test_purity" # run tests matching a pattern
63
+ ```
64
+
65
+ Tests live in `tests/` and mirror the package structure. The coverage threshold (90%) is enforced both by `pytest` directly and by the pre-commit hook.
66
+
67
+ ## Pull requests
68
+
69
+ - Keep PRs focused — one logical change per PR.
70
+ - Write a clear description of what changed and why.
71
+ - All pre-commit hooks must pass before requesting review.
72
+
73
+ ## License
74
+
75
+ By contributing, you agree that your contributions are licensed under the Apache License, Version 2.0.