indico_toolkit 6.14.1__tar.gz → 6.14.2__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.
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/PKG-INFO +1 -1
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/__init__.py +1 -1
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/client.py +1 -1
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/indico_wrapper/__init__.py +0 -6
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/ocr/__init__.py +0 -2
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/polling/autoreview.py +3 -3
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/polling/downstream.py +4 -4
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/polling/queries.py +3 -3
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/__init__.py +1 -1
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/document.py +12 -6
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/normalization.py +14 -3
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictionlist.py +22 -9
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/__init__.py +2 -2
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/group.py +9 -1
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/unbundling.py +11 -6
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/result.py +58 -7
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/utils.py +19 -17
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/pyproject.toml +1 -1
- indico_toolkit-6.14.1/indico_toolkit/auto_populate/__init__.py +0 -3
- indico_toolkit-6.14.1/indico_toolkit/auto_populate/populator.py +0 -362
- indico_toolkit-6.14.1/indico_toolkit/auto_populate/types.py +0 -66
- indico_toolkit-6.14.1/indico_toolkit/indico_wrapper/dataset.py +0 -114
- indico_toolkit-6.14.1/indico_toolkit/indico_wrapper/doc_extraction.py +0 -79
- indico_toolkit-6.14.1/indico_toolkit/indico_wrapper/reviewer.py +0 -111
- indico_toolkit-6.14.1/indico_toolkit/ocr/customocr_object.py +0 -42
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/LICENSE +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/README.md +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/association.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/extracted_tokens.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/line_items.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/positioning.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/association/splitting.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/auto_review/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/auto_review/auto_review_functions.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/auto_review/auto_reviewer.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/errors.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/cell.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/errors.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/etloutput.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/range.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/table.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/etloutput/token.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/indico_wrapper/download.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/indico_wrapper/indico_wrapper.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/indico_wrapper/modelop.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/indico_wrapper/workflow.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/metrics/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/metrics/compare_ground_truth.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/metrics/compare_models.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/metrics/metrics.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/metrics/plotting.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/ocr/ondoc_object.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/ocr/standard_object.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/pipelines/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/pipelines/file_processing.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/polling/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/py.typed +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/errors.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/model.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/box.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/citation.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/classification.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/documentextraction.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/extraction.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/formextraction.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/prediction.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/span.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/summarization.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/review.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/retry.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/snapshots/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/snapshots/snapshot.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/structure/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/structure/create_structure.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/structure/queries.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/structure/utils.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/types/__init__.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/types/classification.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/types/extractions.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/types/predictions.py +0 -0
- {indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/types/workflow_object.py +0 -0
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
from .dataset import Datasets
|
|
2
|
-
from .doc_extraction import DocExtraction
|
|
3
1
|
from .download import Download
|
|
4
2
|
from .indico_wrapper import IndicoWrapper
|
|
5
|
-
from .reviewer import Reviewer
|
|
6
3
|
from .workflow import Workflow
|
|
7
4
|
|
|
8
5
|
__all__ = (
|
|
9
|
-
"Datasets",
|
|
10
|
-
"DocExtraction",
|
|
11
6
|
"Download",
|
|
12
7
|
"IndicoWrapper",
|
|
13
|
-
"Reviewer",
|
|
14
8
|
"Workflow",
|
|
15
9
|
)
|
|
@@ -3,8 +3,8 @@ import logging
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
-
from indico import AsyncIndicoClient, IndicoConfig
|
|
7
|
-
from indico.queries import (
|
|
6
|
+
from indico import AsyncIndicoClient, IndicoConfig
|
|
7
|
+
from indico.queries import (
|
|
8
8
|
GetSubmission,
|
|
9
9
|
JobStatus,
|
|
10
10
|
RetrieveStorageObject,
|
|
@@ -41,7 +41,7 @@ class AutoReviewPoller:
|
|
|
41
41
|
and submits the review results concurrently.
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
|
-
def __init__(
|
|
44
|
+
def __init__( # type: ignore[no-any-unimported]
|
|
45
45
|
self,
|
|
46
46
|
config: IndicoConfig,
|
|
47
47
|
workflow_id: int,
|
|
@@ -2,12 +2,12 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from indico import AsyncIndicoClient, IndicoConfig
|
|
6
|
-
from indico.queries import (
|
|
5
|
+
from indico import AsyncIndicoClient, IndicoConfig
|
|
6
|
+
from indico.queries import (
|
|
7
7
|
GetSubmission,
|
|
8
8
|
UpdateSubmission,
|
|
9
9
|
)
|
|
10
|
-
from indico.types import Submission
|
|
10
|
+
from indico.types import Submission
|
|
11
11
|
|
|
12
12
|
from ..retry import retry
|
|
13
13
|
from .queries import SubmissionIdsPendingDownstream
|
|
@@ -29,7 +29,7 @@ class DownstreamPoller:
|
|
|
29
29
|
them concurrently, and marks them as retrieved.
|
|
30
30
|
"""
|
|
31
31
|
|
|
32
|
-
def __init__(
|
|
32
|
+
def __init__( # type: ignore[no-any-unimported]
|
|
33
33
|
self,
|
|
34
34
|
config: IndicoConfig,
|
|
35
35
|
workflow_id: int,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING
|
|
2
2
|
|
|
3
|
-
from indico.queries import GraphQLRequest
|
|
3
|
+
from indico.queries import GraphQLRequest
|
|
4
4
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
class SubmissionIdsPendingAutoReview(GraphQLRequest): # type: ignore[misc]
|
|
9
|
+
class SubmissionIdsPendingAutoReview(GraphQLRequest): # type: ignore[misc, no-any-unimported]
|
|
10
10
|
QUERY = """
|
|
11
11
|
query SubmissionIdsPendingAutoReview($workflowIds: [Int]) {
|
|
12
12
|
submissions(
|
|
@@ -33,7 +33,7 @@ class SubmissionIdsPendingAutoReview(GraphQLRequest): # type: ignore[misc]
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
class SubmissionIdsPendingDownstream(GraphQLRequest): # type: ignore[misc]
|
|
36
|
+
class SubmissionIdsPendingDownstream(GraphQLRequest): # type: ignore[misc, no-any-unimported]
|
|
37
37
|
QUERY = """
|
|
38
38
|
query SubmissionIdsPendingDownstream($workflowIds: [Int]) {
|
|
39
39
|
submissions(
|
|
@@ -12,13 +12,14 @@ class Document:
|
|
|
12
12
|
error: str
|
|
13
13
|
traceback: str
|
|
14
14
|
|
|
15
|
-
# Auto review changes must reproduce all model sections that were
|
|
16
|
-
# original result file. This may not be possible from the
|
|
17
|
-
# model had an empty section because it didn't
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
# reproduced later.
|
|
15
|
+
# Auto review changes must reproduce all model and component sections that were
|
|
16
|
+
# present in the original result file. This may not be possible from the
|
|
17
|
+
# predictions alone--if a model or component had an empty section because it didn't
|
|
18
|
+
# produce predictions or if all of the predictions for that section were dropped.
|
|
19
|
+
# As such, the models and components seen when parsing a result file are tracked
|
|
20
|
+
# per-document so that the empty sections can be reproduced later.
|
|
21
21
|
_model_sections: "frozenset[str]"
|
|
22
|
+
_component_sections: "frozenset[str]"
|
|
22
23
|
|
|
23
24
|
@staticmethod
|
|
24
25
|
def from_v1_dict(result: object) -> "Document":
|
|
@@ -38,6 +39,7 @@ class Document:
|
|
|
38
39
|
error="",
|
|
39
40
|
traceback="",
|
|
40
41
|
_model_sections=model_names,
|
|
42
|
+
_component_sections=frozenset(),
|
|
41
43
|
)
|
|
42
44
|
|
|
43
45
|
@staticmethod
|
|
@@ -46,7 +48,9 @@ class Document:
|
|
|
46
48
|
Create a `Document` from a v3 document dictionary.
|
|
47
49
|
"""
|
|
48
50
|
model_results = get(document, dict, "model_results", "ORIGINAL")
|
|
51
|
+
component_results = get(document, dict, "component_results", "ORIGINAL")
|
|
49
52
|
model_ids = frozenset(model_results.keys())
|
|
53
|
+
component_ids = frozenset(component_results.keys())
|
|
50
54
|
etl_output_uri = get(document, str, "etl_output")
|
|
51
55
|
|
|
52
56
|
return Document(
|
|
@@ -57,6 +61,7 @@ class Document:
|
|
|
57
61
|
error="",
|
|
58
62
|
traceback="",
|
|
59
63
|
_model_sections=model_ids,
|
|
64
|
+
_component_sections=component_ids,
|
|
60
65
|
)
|
|
61
66
|
|
|
62
67
|
@staticmethod
|
|
@@ -75,4 +80,5 @@ class Document:
|
|
|
75
80
|
error=error,
|
|
76
81
|
traceback=traceback,
|
|
77
82
|
_model_sections=frozenset(),
|
|
83
|
+
_component_sections=frozenset(),
|
|
78
84
|
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
+
from itertools import chain
|
|
2
3
|
from typing import TYPE_CHECKING
|
|
3
4
|
|
|
4
5
|
from .utils import get, has
|
|
@@ -88,12 +89,18 @@ def normalize_v3_result(result: "Any") -> None:
|
|
|
88
89
|
"""
|
|
89
90
|
task_type_by_model_group_id = {
|
|
90
91
|
model_group_id: model_group["task_type"]
|
|
91
|
-
for model_group_id, model_group in
|
|
92
|
+
for model_group_id, model_group in chain(
|
|
93
|
+
result["modelgroup_metadata"].items(),
|
|
94
|
+
result.get("component_metadata", {}).items(),
|
|
95
|
+
)
|
|
92
96
|
}
|
|
93
97
|
predictions_with_task_type: "Iterator[tuple[Any, str]]" = (
|
|
94
|
-
(prediction, task_type_by_model_group_id
|
|
98
|
+
(prediction, task_type_by_model_group_id.get(model_group_id, ""))
|
|
95
99
|
for submission_result in get(result, list, "submission_results")
|
|
96
|
-
for review_result in
|
|
100
|
+
for review_result in chain(
|
|
101
|
+
get(submission_result, dict, "model_results").values(),
|
|
102
|
+
get(submission_result, dict, "component_results").values(),
|
|
103
|
+
)
|
|
97
104
|
for model_group_id, model_results in review_result.items()
|
|
98
105
|
for prediction in model_results
|
|
99
106
|
)
|
|
@@ -139,6 +146,10 @@ def normalize_v3_result(result: "Any") -> None:
|
|
|
139
146
|
if task_type == "summarization" and "citations" not in prediction:
|
|
140
147
|
prediction["citations"] = []
|
|
141
148
|
|
|
149
|
+
# Prior to 7.2, v3 result files don't include a `component_metadata` section.
|
|
150
|
+
if not has(result, dict, "component_metadata"):
|
|
151
|
+
result["component_metadata"] = {}
|
|
152
|
+
|
|
142
153
|
# Prior to 6.8, v3 result files don't include a `reviews` section.
|
|
143
154
|
if not has(result, dict, "reviews"):
|
|
144
155
|
result["reviews"] = {}
|
|
@@ -337,7 +337,7 @@ class PredictionList(List[PredictionType]):
|
|
|
337
337
|
elif result.version == 3:
|
|
338
338
|
return self.to_v3_changes(result.documents)
|
|
339
339
|
else:
|
|
340
|
-
raise ValueError(f"unsupported file version `{result.version
|
|
340
|
+
raise ValueError(f"unsupported file version `{result.version}`")
|
|
341
341
|
|
|
342
342
|
def to_v1_changes(self, document: "Document") -> "dict[str, Any]":
|
|
343
343
|
"""
|
|
@@ -370,13 +370,8 @@ class PredictionList(List[PredictionType]):
|
|
|
370
370
|
continue
|
|
371
371
|
|
|
372
372
|
model_results: "dict[str, Any]" = {}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
"submissionfile_id": document.id,
|
|
376
|
-
"model_results": model_results,
|
|
377
|
-
"component_results": {},
|
|
378
|
-
}
|
|
379
|
-
)
|
|
373
|
+
component_results: "dict[str, Any]" = {}
|
|
374
|
+
|
|
380
375
|
predictions_by_model = self.where(
|
|
381
376
|
document=document,
|
|
382
377
|
).groupby(
|
|
@@ -384,12 +379,30 @@ class PredictionList(List[PredictionType]):
|
|
|
384
379
|
)
|
|
385
380
|
|
|
386
381
|
for model, predictions in predictions_by_model.items():
|
|
387
|
-
|
|
382
|
+
model_id = str(model.id)
|
|
383
|
+
prediction_dicts = [
|
|
388
384
|
prediction.to_v3_dict() for prediction in predictions
|
|
389
385
|
]
|
|
390
386
|
|
|
387
|
+
if model_id in document._model_sections:
|
|
388
|
+
model_results[model_id] = prediction_dicts
|
|
389
|
+
elif model_id in document._component_sections:
|
|
390
|
+
component_results[model_id] = prediction_dicts
|
|
391
|
+
|
|
391
392
|
for model_id in document._model_sections:
|
|
392
393
|
if model_id not in model_results:
|
|
393
394
|
model_results[model_id] = []
|
|
394
395
|
|
|
396
|
+
for component_id in document._component_sections:
|
|
397
|
+
if component_id not in component_results:
|
|
398
|
+
component_results[component_id] = []
|
|
399
|
+
|
|
400
|
+
changes.append(
|
|
401
|
+
{
|
|
402
|
+
"submissionfile_id": document.id,
|
|
403
|
+
"model_results": model_results,
|
|
404
|
+
"component_results": component_results,
|
|
405
|
+
}
|
|
406
|
+
)
|
|
407
|
+
|
|
395
408
|
return changes
|
{indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/__init__.py
RENAMED
|
@@ -62,7 +62,7 @@ def from_v1_dict(
|
|
|
62
62
|
elif model.type == FORM_EXTRACTION:
|
|
63
63
|
return FormExtraction.from_v1_dict(document, model, review, prediction)
|
|
64
64
|
else:
|
|
65
|
-
raise ResultError(f"unsupported v1 model type
|
|
65
|
+
raise ResultError(f"unsupported v1 model type {model.type!r}")
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def from_v3_dict(
|
|
@@ -85,4 +85,4 @@ def from_v3_dict(
|
|
|
85
85
|
elif model.type == UNBUNDLING:
|
|
86
86
|
return Unbundling.from_v3_dict(document, model, review, prediction)
|
|
87
87
|
else:
|
|
88
|
-
raise ResultError(f"unsupported v3 model type
|
|
88
|
+
raise ResultError(f"unsupported v3 model type {model.type!r}")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
1
|
+
from dataclasses import dataclass, replace
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ..utils import get
|
|
@@ -13,6 +13,14 @@ class Group:
|
|
|
13
13
|
name: str
|
|
14
14
|
index: int
|
|
15
15
|
|
|
16
|
+
def __next__(self) -> "Group":
|
|
17
|
+
"""
|
|
18
|
+
Return the `Group` with the next index.
|
|
19
|
+
|
|
20
|
+
Supports `group = next(group)`.
|
|
21
|
+
"""
|
|
22
|
+
return replace(self, index=self.index + 1)
|
|
23
|
+
|
|
16
24
|
@staticmethod
|
|
17
25
|
def from_dict(group: object) -> "Group":
|
|
18
26
|
return Group(
|
{indico_toolkit-6.14.1 → indico_toolkit-6.14.2}/indico_toolkit/results/predictions/unbundling.py
RENAMED
|
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING
|
|
|
4
4
|
from ..review import Review
|
|
5
5
|
from ..utils import get, omit
|
|
6
6
|
from .prediction import Prediction
|
|
7
|
+
from .span import Span
|
|
7
8
|
|
|
8
9
|
if TYPE_CHECKING:
|
|
9
10
|
from typing import Any
|
|
@@ -14,7 +15,14 @@ if TYPE_CHECKING:
|
|
|
14
15
|
|
|
15
16
|
@dataclass
|
|
16
17
|
class Unbundling(Prediction):
|
|
17
|
-
|
|
18
|
+
spans: "list[Span]"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def pages(self) -> "tuple[int, ...]":
|
|
22
|
+
"""
|
|
23
|
+
Return the pages covered by `self.spans`.
|
|
24
|
+
"""
|
|
25
|
+
return tuple(span.page for span in self.spans)
|
|
18
26
|
|
|
19
27
|
@staticmethod
|
|
20
28
|
def from_v3_dict(
|
|
@@ -32,10 +40,7 @@ class Unbundling(Prediction):
|
|
|
32
40
|
review=review,
|
|
33
41
|
label=get(prediction, str, "label"),
|
|
34
42
|
confidences=get(prediction, dict, "confidence"),
|
|
35
|
-
|
|
36
|
-
get(span, int, "page_num")
|
|
37
|
-
for span in get(prediction, list, "spans") # fmt: skip
|
|
38
|
-
],
|
|
43
|
+
spans=sorted(map(Span.from_dict, get(prediction, list, "spans"))),
|
|
39
44
|
extras=omit(prediction, "confidence", "label", "spans"),
|
|
40
45
|
)
|
|
41
46
|
|
|
@@ -47,5 +52,5 @@ class Unbundling(Prediction):
|
|
|
47
52
|
**self.extras,
|
|
48
53
|
"label": self.label,
|
|
49
54
|
"confidence": self.confidences,
|
|
50
|
-
"spans": [
|
|
55
|
+
"spans": [span.to_dict() for span in self.spans],
|
|
51
56
|
}
|
|
@@ -5,12 +5,13 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
|
|
6
6
|
from . import predictions as prediction
|
|
7
7
|
from .document import Document
|
|
8
|
+
from .errors import ResultError
|
|
8
9
|
from .model import ModelGroup
|
|
9
10
|
from .normalization import normalize_v1_result, normalize_v3_result
|
|
10
11
|
from .predictionlist import PredictionList
|
|
11
12
|
from .predictions import Prediction
|
|
12
13
|
from .review import Review, ReviewType
|
|
13
|
-
from .utils import get
|
|
14
|
+
from .utils import get, has
|
|
14
15
|
|
|
15
16
|
if TYPE_CHECKING:
|
|
16
17
|
from typing import Any
|
|
@@ -106,16 +107,33 @@ class Result:
|
|
|
106
107
|
submission_id = get(result, int, "submission_id")
|
|
107
108
|
submission_results = get(result, list, "submission_results")
|
|
108
109
|
modelgroup_metadata = get(result, dict, "modelgroup_metadata")
|
|
110
|
+
component_metadata = get(result, dict, "component_metadata")
|
|
109
111
|
review_metadata = get(result, dict, "reviews")
|
|
110
|
-
|
|
111
|
-
processed_documents = map(Document.from_v3_dict, submission_results)
|
|
112
112
|
errored_files = get(result, dict, "errored_files").values()
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
|
|
114
|
+
static_model_components = filter(
|
|
115
|
+
lambda component: (
|
|
116
|
+
get(component, str, "component_type").casefold() == "static_model"
|
|
117
|
+
),
|
|
118
|
+
component_metadata.values(),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
documents = sorted(
|
|
122
|
+
chain(
|
|
123
|
+
map(Document.from_v3_dict, submission_results),
|
|
124
|
+
map(Document.from_v3_errored_file, errored_files),
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
models = sorted(
|
|
128
|
+
chain(
|
|
129
|
+
map(ModelGroup.from_v3_dict, modelgroup_metadata.values()),
|
|
130
|
+
map(ModelGroup.from_v3_dict, static_model_components),
|
|
131
|
+
)
|
|
132
|
+
)
|
|
117
133
|
reviews = sorted(map(Review.from_dict, review_metadata.values()))
|
|
118
134
|
|
|
135
|
+
predictions: "PredictionList[Prediction]" = PredictionList()
|
|
136
|
+
|
|
119
137
|
for document_dict in submission_results:
|
|
120
138
|
document_id = get(document_dict, int, "submissionfile_id")
|
|
121
139
|
document = next(
|
|
@@ -124,11 +142,17 @@ class Result:
|
|
|
124
142
|
reviewed_model_predictions: "list[tuple[Review | None, Any]]" = [
|
|
125
143
|
(None, get(document_dict, dict, "model_results", "ORIGINAL"))
|
|
126
144
|
]
|
|
145
|
+
reviewed_component_predictions: "list[tuple[Review | None, Any]]" = [
|
|
146
|
+
(None, get(document_dict, dict, "component_results", "ORIGINAL"))
|
|
147
|
+
]
|
|
127
148
|
|
|
128
149
|
if reviews:
|
|
129
150
|
reviewed_model_predictions.append(
|
|
130
151
|
(reviews[-1], get(document_dict, dict, "model_results", "FINAL"))
|
|
131
152
|
)
|
|
153
|
+
reviewed_component_predictions.append(
|
|
154
|
+
(reviews[-1], get(document_dict, dict, "component_results", "FINAL")) # fmt: skip # noqa: E501
|
|
155
|
+
)
|
|
132
156
|
|
|
133
157
|
for review, model_section in reviewed_model_predictions:
|
|
134
158
|
for model_id, model_predictions in model_section.items():
|
|
@@ -142,6 +166,33 @@ class Result:
|
|
|
142
166
|
)
|
|
143
167
|
)
|
|
144
168
|
|
|
169
|
+
for review, component_section in reviewed_component_predictions:
|
|
170
|
+
for component_id, component_predictions in component_section.items():
|
|
171
|
+
try:
|
|
172
|
+
model = next(
|
|
173
|
+
filter(lambda model: model.id == int(component_id), models)
|
|
174
|
+
)
|
|
175
|
+
except StopIteration:
|
|
176
|
+
if has(component_metadata, str, component_id, "component_type"):
|
|
177
|
+
component_type = get(
|
|
178
|
+
component_metadata, str, component_id, "component_type"
|
|
179
|
+
)
|
|
180
|
+
raise ResultError(
|
|
181
|
+
f"unsupported component type {component_type!r} "
|
|
182
|
+
f"for component {component_id}"
|
|
183
|
+
)
|
|
184
|
+
else:
|
|
185
|
+
raise ResultError(
|
|
186
|
+
f"no component metadata for component {component_id}"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
predictions.extend(
|
|
190
|
+
map(
|
|
191
|
+
partial(prediction.from_v3_dict, document, model, review),
|
|
192
|
+
component_predictions,
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
|
|
145
196
|
return Result(
|
|
146
197
|
version=version,
|
|
147
198
|
submission_id=submission_id,
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
from collections.abc import Iterable, Iterator
|
|
2
2
|
from typing import Callable, TypeVar
|
|
3
3
|
|
|
4
|
-
from .errors import ResultError
|
|
5
|
-
|
|
6
4
|
Value = TypeVar("Value")
|
|
7
5
|
|
|
8
6
|
|
|
9
7
|
def get(result: object, value_type: "type[Value]", *keys: "str | int") -> Value:
|
|
10
8
|
"""
|
|
11
|
-
Return the value obtained by traversing `result` using `keys
|
|
12
|
-
|
|
9
|
+
Return the value of type `value_type` obtained by traversing `result` using `keys`.
|
|
10
|
+
Raise an error if a key doesn't exist or the value has the wrong type.
|
|
13
11
|
"""
|
|
14
12
|
for key in keys:
|
|
15
|
-
if isinstance(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
if isinstance(result, dict):
|
|
14
|
+
if key in result:
|
|
15
|
+
result = result[key]
|
|
16
|
+
else:
|
|
17
|
+
raise KeyError(f"{key!r} not in {result.keys()!r}")
|
|
18
|
+
elif isinstance(result, list):
|
|
19
|
+
if isinstance(key, int):
|
|
20
|
+
if 0 <= key < len(result):
|
|
21
|
+
result = result[key]
|
|
22
|
+
else:
|
|
23
|
+
raise IndexError(f"{key} out of range [0,{len(result)})")
|
|
24
|
+
else:
|
|
25
|
+
raise TypeError(f"list can't be indexed with {key!r}")
|
|
19
26
|
else:
|
|
20
|
-
raise
|
|
21
|
-
f"result object `{type(result)!r}` does not contain key `{key!r}`"
|
|
22
|
-
)
|
|
27
|
+
raise TypeError(f"{type(result)} can't be traversed")
|
|
23
28
|
|
|
24
29
|
if isinstance(result, value_type):
|
|
25
30
|
return result
|
|
26
31
|
else:
|
|
27
|
-
raise
|
|
28
|
-
f"result object `{type(result)!r}` does not have a value for "
|
|
29
|
-
f"key `{key!r}` of type `{value_type}`"
|
|
30
|
-
)
|
|
32
|
+
raise TypeError(f"value `{result!r}` doesn't have type {value_type}")
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
def has(result: object, value_type: "type[Value]", *keys: "str | int") -> bool:
|
|
@@ -35,9 +37,9 @@ def has(result: object, value_type: "type[Value]", *keys: "str | int") -> bool:
|
|
|
35
37
|
Check if `result` can be traversed using `keys` to a value of type `value_type`.
|
|
36
38
|
"""
|
|
37
39
|
for key in keys:
|
|
38
|
-
if isinstance(
|
|
40
|
+
if isinstance(result, dict) and key in result:
|
|
39
41
|
result = result[key]
|
|
40
|
-
elif isinstance(
|
|
42
|
+
elif isinstance(result, list) and isinstance(key, int) and 0 <= key < len(result): # fmt: skip # noqa: E501
|
|
41
43
|
result = result[key]
|
|
42
44
|
else:
|
|
43
45
|
return False
|
|
@@ -12,7 +12,7 @@ authors = [
|
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
urls = { source = "https://github.com/IndicoDataSolutions/Indico-Solutions-Toolkit" }
|
|
14
14
|
requires-python = ">=3.10"
|
|
15
|
-
version = "6.14.
|
|
15
|
+
version = "6.14.2"
|
|
16
16
|
dependencies = ["indico-client (>=6.14.0,<7.0.0)"]
|
|
17
17
|
|
|
18
18
|
[project.optional-dependencies]
|