assay-engine 0.5.0.dev2__py3-none-any.whl
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.
- assay/__init__.py +83 -0
- assay/_cli_app.py +102 -0
- assay/_cli_io.py +130 -0
- assay/_json.py +34 -0
- assay/_optional.py +69 -0
- assay/_version.py +5 -0
- assay/additive.py +104 -0
- assay/agreement.py +312 -0
- assay/calibration.py +167 -0
- assay/cli.py +55 -0
- assay/compose.py +31 -0
- assay/composite.py +228 -0
- assay/contracts.py +886 -0
- assay/errors.py +166 -0
- assay/limits.py +13 -0
- assay/measurement.py +1325 -0
- assay/metrics.py +238 -0
- assay/minimum.py +82 -0
- assay/models.py +111 -0
- assay/normalize.py +74 -0
- assay/py.typed +0 -0
- assay/ranking.py +361 -0
- assay/settings.py +90 -0
- assay/uncertainty.py +190 -0
- assay/weighted_mean.py +109 -0
- assay_engine-0.5.0.dev2.dist-info/METADATA +250 -0
- assay_engine-0.5.0.dev2.dist-info/RECORD +30 -0
- assay_engine-0.5.0.dev2.dist-info/WHEEL +4 -0
- assay_engine-0.5.0.dev2.dist-info/entry_points.txt +2 -0
- assay_engine-0.5.0.dev2.dist-info/licenses/LICENSE +21 -0
assay/errors.py
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""Stable, scoring-only Assay error codes."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from enum import StrEnum
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"AssayError",
|
|
9
|
+
"CliExtraMissing",
|
|
10
|
+
"CliInputInvalid",
|
|
11
|
+
"CliOutputInvalid",
|
|
12
|
+
"CommandMovedToAvow",
|
|
13
|
+
"CommandReplaced",
|
|
14
|
+
"ContractCode",
|
|
15
|
+
"ContractValidationError",
|
|
16
|
+
"EmptyRelevantSet",
|
|
17
|
+
"InsufficientSamples",
|
|
18
|
+
"InvalidAgreementRequest",
|
|
19
|
+
"InvalidMethod",
|
|
20
|
+
"InvalidRankingRequest",
|
|
21
|
+
"InvalidScoreRequest",
|
|
22
|
+
"InvalidSettings",
|
|
23
|
+
"MetricsExtraMissing",
|
|
24
|
+
"ReplayRefused",
|
|
25
|
+
"UnknownMetric",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ContractCode(StrEnum):
|
|
30
|
+
"""Stable, value-free validation codes for public scoring contracts."""
|
|
31
|
+
|
|
32
|
+
DUPLICATE_IDENTIFIER = "assay.duplicate_identifier"
|
|
33
|
+
DUPLICATE_FIELD = "assay.duplicate_field"
|
|
34
|
+
EMPTY_COMPONENTS = "assay.empty_components"
|
|
35
|
+
EMPTY_TERMS = "assay.empty_terms"
|
|
36
|
+
INVALID_CLAMP_POLICY = "assay.invalid_clamp_policy"
|
|
37
|
+
INVALID_COEFFICIENT = "assay.invalid_coefficient"
|
|
38
|
+
INVALID_CONTRACT = "assay.invalid_contract"
|
|
39
|
+
INVALID_DIRECTION = "assay.invalid_direction"
|
|
40
|
+
INVALID_IDENTIFIER = "assay.invalid_identifier"
|
|
41
|
+
INVALID_INPUTS_HASH = "assay.invalid_inputs_hash"
|
|
42
|
+
INVALID_ALIAS_CONFIG = "assay.invalid_alias_config"
|
|
43
|
+
INVALID_INTERVAL = "assay.invalid_interval"
|
|
44
|
+
INVALID_LABEL = "assay.invalid_label"
|
|
45
|
+
INVALID_METHOD = "assay.invalid_method"
|
|
46
|
+
INVALID_NUMBER = "assay.invalid_number"
|
|
47
|
+
INVALID_OBJECT = "assay.invalid_object"
|
|
48
|
+
INVALID_OPERATION = "assay.invalid_operation"
|
|
49
|
+
INVALID_RESULT = "assay.invalid_result"
|
|
50
|
+
INVALID_SCALE = "assay.invalid_scale"
|
|
51
|
+
INVALID_TEXT = "assay.invalid_text"
|
|
52
|
+
INVALID_WEIGHT = "assay.invalid_weight"
|
|
53
|
+
MISSING_FIELD = "assay.missing_field"
|
|
54
|
+
MISSING_WEIGHT = "assay.missing_weight"
|
|
55
|
+
OUT_OF_RANGE = "assay.out_of_range"
|
|
56
|
+
UNKNOWN_FIELD = "assay.unknown_field"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class AssayError(Exception):
|
|
60
|
+
"""Base class for Assay domain failures."""
|
|
61
|
+
|
|
62
|
+
code: str = "assay.error"
|
|
63
|
+
|
|
64
|
+
def __init__(self, _detail: object | None = None) -> None:
|
|
65
|
+
"""Expose only the stable code; caller values never enter the message."""
|
|
66
|
+
super().__init__(self.code)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ContractValidationError(AssayError):
|
|
70
|
+
"""A value-free public failure at an Assay JSON model boundary."""
|
|
71
|
+
|
|
72
|
+
code: str = ContractCode.INVALID_CONTRACT.value
|
|
73
|
+
|
|
74
|
+
def __init__(self, code: ContractCode = ContractCode.INVALID_CONTRACT) -> None:
|
|
75
|
+
self.code = code.value
|
|
76
|
+
super().__init__()
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class CliInputInvalid(AssayError):
|
|
80
|
+
"""A CLI input is unreadable, malformed, or unsafe."""
|
|
81
|
+
|
|
82
|
+
code: str = "assay.cli_input_invalid"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class CliExtraMissing(AssayError):
|
|
86
|
+
"""A current command was invoked without Assay's optional CLI dependency."""
|
|
87
|
+
|
|
88
|
+
code: str = "assay.cli_extra_missing"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class CliOutputInvalid(AssayError):
|
|
92
|
+
"""A CLI destination is unsafe or cannot be installed atomically."""
|
|
93
|
+
|
|
94
|
+
code: str = "assay.cli_output_invalid"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class CommandMovedToAvow(AssayError):
|
|
98
|
+
"""A historical evidence command now belongs to Avow."""
|
|
99
|
+
|
|
100
|
+
code: str = "assay.command_moved_to_avow"
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class CommandReplaced(AssayError):
|
|
104
|
+
"""A mixed historical scoring command has an explicit replacement."""
|
|
105
|
+
|
|
106
|
+
code: str = "assay.command_replaced"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class InvalidScoreRequest(AssayError):
|
|
110
|
+
"""A score request cannot produce a meaningful result."""
|
|
111
|
+
|
|
112
|
+
code: str = "assay.invalid_request"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class InvalidMethod(AssayError):
|
|
116
|
+
"""A score request has no recognized combiner discriminator."""
|
|
117
|
+
|
|
118
|
+
code: str = "assay.invalid_method"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class UnknownMetric(AssayError):
|
|
122
|
+
"""A requested metric is not registered."""
|
|
123
|
+
|
|
124
|
+
code: str = "assay.unknown_metric"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class InvalidRankingRequest(AssayError):
|
|
128
|
+
"""A ranked-retrieval input cannot be scored as given."""
|
|
129
|
+
|
|
130
|
+
code: str = "assay.invalid_ranking_request"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class EmptyRelevantSet(AssayError):
|
|
134
|
+
"""A ranking has no judged-relevant document."""
|
|
135
|
+
|
|
136
|
+
code: str = "assay.empty_relevant_set"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class InvalidAgreementRequest(AssayError):
|
|
140
|
+
"""An inter-rater input cannot be scored as given."""
|
|
141
|
+
|
|
142
|
+
code: str = "assay.invalid_agreement_request"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class InsufficientSamples(AssayError):
|
|
146
|
+
"""A sample count is below the declared uncertainty floor."""
|
|
147
|
+
|
|
148
|
+
code: str = "assay.insufficient_samples"
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class MetricsExtraMissing(AssayError):
|
|
152
|
+
"""An optional metric was requested without metric dependencies."""
|
|
153
|
+
|
|
154
|
+
code: str = "assay.metrics_extra_missing"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class InvalidSettings(AssayError):
|
|
158
|
+
"""Runtime settings are invalid or outside documented resource bounds."""
|
|
159
|
+
|
|
160
|
+
code: str = "assay.invalid_settings"
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class ReplayRefused(AssayError):
|
|
164
|
+
"""A historical score cannot be reproduced from its inputs."""
|
|
165
|
+
|
|
166
|
+
code: str = "assay.replay_refused"
|
assay/limits.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Documented resource bounds for optional scoring calculators."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
MAX_BOOTSTRAP_RESAMPLES = 1_000_000
|
|
6
|
+
MAX_BOOTSTRAP_WORK_CELLS = 10_000_000
|
|
7
|
+
MAX_BOOTSTRAP_BATCH_CELLS = 1_000_000
|
|
8
|
+
MAX_CALIBRATION_BINS = 10_000
|
|
9
|
+
MAX_ITEMS = 1_000_000
|
|
10
|
+
MAX_RANKING_K = 1_000_000
|
|
11
|
+
MAX_RELEVANCE_GAIN = 1_000_000
|
|
12
|
+
MAX_SCALE_LEVELS = 10_000
|
|
13
|
+
MAX_SEED = 2**63 - 1
|