paratext-cli 0.2.0__tar.gz → 0.2.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.
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/PKG-INFO +4 -2
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/README.md +3 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/paratext.example.toml +5 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/pyproject.toml +1 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/__init__.py +1 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/cli.py +5 -4
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/config.py +2 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/extract.py +3 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_config.py +8 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/uv.lock +1 -1
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/.github/workflows/ci.yml +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/.github/workflows/publish.yml +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/.gitignore +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/AGENTS.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/LICENSE +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/NOTICE +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/assets/logo.png +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/assets/logo.svg +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/configuration.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/export.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/green-scheduling.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/hf-export-spec.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/publishing.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/docs/scanned-cards.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/AGENTS.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/carbon.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/cards.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/catalogue.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/datasets.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/hf_export.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/inspect.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/io.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/packaging.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/paratext.example.toml +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/projects/__init__.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/projects/card_template/__init__.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/projects/card_template/prompt.md +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/projects/card_template/schema.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/records.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/__init__.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/hf_oauth.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/server.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/static/app.js +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/static/favicon.svg +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/static/index.html +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/static/oat.min.css +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/review/static/oat.min.js +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/runner.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/scaffold.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/sources.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/src/paratext/store.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_carbon.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_catalogue.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_cli.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_extract.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_guide.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_hf_export.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_io.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_packaging.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_project_audit.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_records.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_review.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_rounds.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_runner.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_scaffold.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_show_through.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_sources.py +0 -0
- {paratext_cli-0.2.0 → paratext_cli-0.2.1}/tests/test_verso.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: paratext-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Modular, project-based metadata extraction from digitised library/archive collections with a multimodal model
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -159,7 +159,9 @@ prompt version, keyed on the prompt's hash:
|
|
|
159
159
|
`-r3`, …). The UI shows the two most recent rounds side by side and highlights
|
|
160
160
|
what changed. The flag is needed because a run resumes on sample id: without
|
|
161
161
|
it the existing extractions are already there, so the model is never called.
|
|
162
|
-
paratext stops and says so rather than resuming into a stale file.
|
|
162
|
+
paratext stops and says so rather than resuming into a stale file. On a small
|
|
163
|
+
collection, `re-extract = true` in `paratext.toml` makes it the default and
|
|
164
|
+
the loop needs no flag.
|
|
163
165
|
- **Re-run the same prompt** (a resume, or a bigger `--limit`) → the current round
|
|
164
166
|
is updated in place, keeping the annotations you've already made.
|
|
165
167
|
|
|
@@ -134,7 +134,9 @@ prompt version, keyed on the prompt's hash:
|
|
|
134
134
|
`-r3`, …). The UI shows the two most recent rounds side by side and highlights
|
|
135
135
|
what changed. The flag is needed because a run resumes on sample id: without
|
|
136
136
|
it the existing extractions are already there, so the model is never called.
|
|
137
|
-
paratext stops and says so rather than resuming into a stale file.
|
|
137
|
+
paratext stops and says so rather than resuming into a stale file. On a small
|
|
138
|
+
collection, `re-extract = true` in `paratext.toml` makes it the default and
|
|
139
|
+
the loop needs no flag.
|
|
138
140
|
- **Re-run the same prompt** (a resume, or a bigger `--limit`) → the current round
|
|
139
141
|
is updated in place, keeping the annotations you've already made.
|
|
140
142
|
|
|
@@ -19,6 +19,11 @@ output = "output/cards.jsonl"
|
|
|
19
19
|
# prompt no longer opens a new round to compare against. Leave it unset unless
|
|
20
20
|
# that's what you want.
|
|
21
21
|
# review-out = "review/cards"
|
|
22
|
+
# Editing the prompt makes existing extractions stale, and paratext stops rather
|
|
23
|
+
# than resuming into them. On a small collection where a re-run is cheap, this
|
|
24
|
+
# discards them and calls the model again instead — the run/edit/re-run loop
|
|
25
|
+
# then needs no flag. Leave it off for anything big or metered.
|
|
26
|
+
# re-extract = true
|
|
22
27
|
|
|
23
28
|
# Verbatim passthrough into the request body — for provider parameters paratext
|
|
24
29
|
# doesn't model. Reasoning controls live here, and every provider spells them
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# the plain name on PyPI belongs to an unrelated project, so the distribution
|
|
4
4
|
# carries the `-cli` suffix.
|
|
5
5
|
name = "paratext-cli"
|
|
6
|
-
version = "0.2.
|
|
6
|
+
version = "0.2.1"
|
|
7
7
|
description = "Modular, project-based metadata extraction from digitised library/archive collections with a multimodal model"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
# Core is pure-Python + numpy/pillow/pydantic. The [detector] extra needs
|
|
@@ -61,6 +61,7 @@ HARDCODED_DEFAULTS: dict = {
|
|
|
61
61
|
"review_port": DEFAULT_PORT,
|
|
62
62
|
"no_structured": False,
|
|
63
63
|
"skip_preflight": False,
|
|
64
|
+
"re_extract": False,
|
|
64
65
|
"max_tokens": None, # None → runner.DEFAULT_MAX_TOKENS, or the project's own
|
|
65
66
|
}
|
|
66
67
|
|
|
@@ -214,7 +215,7 @@ def _do_extract(args: argparse.Namespace) -> None:
|
|
|
214
215
|
energy=energy,
|
|
215
216
|
max_tokens=getattr(args, "max_tokens", None),
|
|
216
217
|
extra_body=config_extra_body(args.project),
|
|
217
|
-
re_extract=
|
|
218
|
+
re_extract=args.re_extract,
|
|
218
219
|
)
|
|
219
220
|
|
|
220
221
|
|
|
@@ -675,9 +676,9 @@ def _add_extract_args(p: argparse.ArgumentParser) -> None:
|
|
|
675
676
|
p.add_argument("--base-url", default=None, help="model endpoint base URL (OpenAI-compatible)")
|
|
676
677
|
p.add_argument("--api-key", default=None, help="API key for the endpoint (often unused)")
|
|
677
678
|
p.add_argument("--limit", type=int, default=None, help="Process at most N inputs")
|
|
678
|
-
p.add_argument("--re-extract", action="store_true",
|
|
679
|
-
help="Discard existing extractions and call the model again "
|
|
680
|
-
"
|
|
679
|
+
p.add_argument("--re-extract", action="store_true", default=None,
|
|
680
|
+
help="Discard existing extractions and call the model again when the "
|
|
681
|
+
"prompt or model has changed (config re-extract, else stop and say so)")
|
|
681
682
|
p.add_argument("--max-tokens", type=int, default=None, metavar="N",
|
|
682
683
|
help="Output-token ceiling per call (default: 8192; raise it for "
|
|
683
684
|
"models that reason before answering)")
|
|
@@ -62,6 +62,7 @@ RECOGNISED = (
|
|
|
62
62
|
"limit",
|
|
63
63
|
"no_structured",
|
|
64
64
|
"skip_preflight",
|
|
65
|
+
"re_extract",
|
|
65
66
|
"max_tokens",
|
|
66
67
|
)
|
|
67
68
|
|
|
@@ -232,7 +233,7 @@ def coerce_paths(d: dict) -> dict:
|
|
|
232
233
|
for key in ("limit", "review_port", "max_tokens"):
|
|
233
234
|
if key in d and isinstance(d[key], str):
|
|
234
235
|
d[key] = int(d[key])
|
|
235
|
-
for key in ("no_structured", "skip_preflight"):
|
|
236
|
+
for key in ("no_structured", "skip_preflight", "re_extract"):
|
|
236
237
|
if key in d and isinstance(d[key], str):
|
|
237
238
|
d[key] = d[key].lower() in ("1", "true", "yes", "on")
|
|
238
239
|
return d
|
|
@@ -78,7 +78,9 @@ def _guard_stale_output(output: Path, header: dict, project: str, re_extract: bo
|
|
|
78
78
|
f"Those records answer a different question, and resume would skip every\n"
|
|
79
79
|
f"sample and call the model zero times. Either:\n"
|
|
80
80
|
f" paratext run -p {project} --re-extract # redo them\n"
|
|
81
|
-
f" paratext run -p {project} --output <new>.jsonl # keep both"
|
|
81
|
+
f" paratext run -p {project} --output <new>.jsonl # keep both\n"
|
|
82
|
+
f"On a small, cheap collection you can make the first the default:\n"
|
|
83
|
+
f" re-extract = true under [project.{project}] in paratext.toml"
|
|
82
84
|
)
|
|
83
85
|
|
|
84
86
|
|
|
@@ -162,3 +162,11 @@ def test_max_tokens_from_the_environment(tmp_path, monkeypatch):
|
|
|
162
162
|
monkeypatch.chdir(tmp_path)
|
|
163
163
|
monkeypatch.setenv("PARATEXT_MAX_TOKENS", "16384")
|
|
164
164
|
assert cfg.coerce_paths(cfg.load_defaults(None))["max_tokens"] == 16384
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_re_extract_is_recognised_and_coerced():
|
|
168
|
+
from paratext.config import RECOGNISED, coerce_paths
|
|
169
|
+
|
|
170
|
+
assert "re_extract" in RECOGNISED
|
|
171
|
+
assert coerce_paths({"re_extract": "true"})["re_extract"] is True
|
|
172
|
+
assert coerce_paths({"re_extract": "no"})["re_extract"] is False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|