descriptron-core 2.0.2__tar.gz → 2.0.4__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.
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/PKG-INFO +1 -1
- descriptron_core-2.0.4/pyproject.toml +82 -0
- descriptron_core-2.0.4/pyproject.toml.bak_pre_204_20260924_165335 +82 -0
- descriptron_core-2.0.4/pyproject.toml.bak_pre_keys_20260924_165335 +81 -0
- descriptron_core-2.0.4/src/descriptron_core/cli.py +99 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_llm_backend.py +6 -0
- descriptron_core-2.0.4/src/descriptron_core/tools/descriptron_credentials.py +178 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/run_full_pipeline_v2.py +13 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/.gitignore +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/LICENSE +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/NOTICE +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/README.md +0 -0
- /descriptron_core-2.0.2/pyproject.toml → /descriptron_core-2.0.4/pyproject.toml.bak_pre_203_20260924_145320 +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/__init__.py +0 -0
- /descriptron_core-2.0.2/src/descriptron_core/cli.py → /descriptron_core-2.0.4/src/descriptron_core/cli.py.bak_pre_keys_20260924_165335 +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/biorag_system_prompts_v1.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/biorag_system_prompts_v2.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/diaphorina_user_prompts.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/ontologies/aism.obo +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/ontologies/pato.obo +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD_EnumLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/SDD_TypeLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_BasePattern.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_CoreExtensions.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_CoreOntology.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_EnumLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_LinneanCore.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/UBIF_TypeLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/sdd_1.1/w3c-schemata/xml.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/sample_treatment_deposit_example.xml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/sample_zookeys_26056_tp.xml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/schemas/taxpub/tax-treatment-NS0-v1_flat.dtd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/taxon_profiles/TEMPLATE_taxon_profile.yaml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/data/biorag_prompts/taxon_profiles/diaphorina_taxon_profile.yaml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/FHS_and_CLAHE_V21.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_add_discrete_characters_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_annotation_reorient_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_annotation_screen_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_autapomorphy_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_calibrate_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_calibration_figures_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_character_gate_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_character_reliability_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_character_robustness_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_collaborator_forms_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_computed_sets_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_confabulation_checker_v2.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_congruence_compare_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_description_refiner_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_descriptive_scoring_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_feature_policy.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_frame_orientation_calibrate_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_frame_orientation_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_gate_compare_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_graph_identify_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_graph_support_figure_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_homology_frame_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_instrument_compare_v3.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_builder_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_feature_filter_v2.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_fuzzy_figures_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_fuzzy_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_holdout_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_jackknife_support_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_label_conflict_check_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_make_taxon_profile_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_methods_summary_figure_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_novelty_score_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_ontology_annotator_v2.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_outgroup_batch_check_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_outline_shape_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/biorag_system_prompts_v1.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/biorag_system_prompts_v2.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/diaphorina_user_prompts.txt +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/ontologies/aism.obo +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/ontologies/pato.obo +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD_EnumLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/SDD_TypeLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_BasePattern.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_CoreExtensions.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_CoreOntology.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_EnumLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_LinneanCore.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/UBIF_TypeLib.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/sdd_1.1/w3c-schemata/xml.xsd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/sample_treatment_deposit_example.xml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/sample_zookeys_26056_tp.xml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/schemas/taxpub/tax-treatment-NS0-v1_flat.dtd +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/taxon_profiles/TEMPLATE_taxon_profile.yaml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_prompts/taxon_profiles/diaphorina_taxon_profile.yaml +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_rebuild_downstream_v1.sh +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_reliability_figures_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_rename_species_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_rerun_descriptive_tables_v1.sh +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_retest_compare_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_specimen_id.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_subjective_checks_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_type_material_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_vlm_characters_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_vlm_heatmap_figures_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_vlm_reliability_figure_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_vlm_roi_figures_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biosyslit_rag_retrieval.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biosyslit_rag_retrieval_v2.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/build_monograph_exports_v1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/build_species_treatment_docx_v2.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/color_extraction_with_names-v8.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/color_phenomics_homology_v2_1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/compile_specimen_data.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/descriptron_rosetta.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/landmark_gpa_V1.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/make_reproducibility_bundle.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/semi_landmark_and_kpts_procrustesV34_GPA.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/texture_phenomics_from_coco.py +0 -0
- {descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/texture_phenomics_homology.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: descriptron-core
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: Evidence-tiered species descriptions, keys and audits from phenomic matrices
|
|
5
5
|
Project-URL: Homepage, https://github.com/alexrvandam/Descriptron
|
|
6
6
|
Project-URL: Repository, https://github.com/alexrvandam/Descriptron
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "descriptron-core"
|
|
7
|
+
version = "2.0.4"
|
|
8
|
+
description = "Evidence-tiered species descriptions, keys and audits from phenomic matrices"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{ name = "Alex R. Van Dam" }]
|
|
13
|
+
keywords = ["taxonomy", "morphometrics", "phenomics", "species description", "COCO"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
17
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"License :: OSI Approved :: Apache Software License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# Derived from the imports of the 62 programs in this package, not from memory:
|
|
24
|
+
# `python -m descriptron_core.cli --list` names them. No torch, no CUDA, no
|
|
25
|
+
# compiler — this installs in about a minute on Linux, macOS and Windows, and
|
|
26
|
+
# with the deposited COCO files it reproduces every analysis in the methods paper.
|
|
27
|
+
dependencies = [
|
|
28
|
+
"numpy>=1.23",
|
|
29
|
+
"pandas>=1.5",
|
|
30
|
+
"scipy>=1.9",
|
|
31
|
+
"matplotlib>=3.6",
|
|
32
|
+
"scikit-learn>=1.2",
|
|
33
|
+
"scikit-image>=0.20",
|
|
34
|
+
"opencv-python-headless>=4.7", # headless: the analysis half never opens a window
|
|
35
|
+
"pillow>=9",
|
|
36
|
+
"pycocotools>=2.0.6",
|
|
37
|
+
"seaborn>=0.12",
|
|
38
|
+
"statsmodels>=0.14",
|
|
39
|
+
"scikit-posthocs>=0.7",
|
|
40
|
+
"umap-learn>=0.5",
|
|
41
|
+
"networkx>=3",
|
|
42
|
+
"pyefd>=1.6",
|
|
43
|
+
"biopython>=1.81",
|
|
44
|
+
"PyYAML>=6",
|
|
45
|
+
"lxml>=4.9",
|
|
46
|
+
"openpyxl>=3.1",
|
|
47
|
+
"python-docx>=1.0", # treatment and monograph .docx export
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.optional-dependencies]
|
|
51
|
+
# Only needed to *write* treatments. The audit, key, matrix, novelty scoring and
|
|
52
|
+
# delimitation are all deterministic and need no model at all.
|
|
53
|
+
llm = ["anthropic>=0.40"]
|
|
54
|
+
# literature retrieval (the RAG in BioRAG): BioSysLit treatments from Zenodo and your
|
|
55
|
+
# own PDFs. Keyword retrieval needs only the first two; sentence-embedding retrieval
|
|
56
|
+
# (`index --embeddings`) also needs sentence-transformers + faiss-cpu, which pull in torch.
|
|
57
|
+
rag = ["requests>=2.28", "pdfplumber>=0.10"]
|
|
58
|
+
rag-embeddings = ["requests>=2.28", "pdfplumber>=0.10", "sentence-transformers>=2.2", "faiss-cpu>=1.7"]
|
|
59
|
+
dev = ["pytest>=7", "build>=1", "twine>=5"]
|
|
60
|
+
|
|
61
|
+
[project.scripts]
|
|
62
|
+
descriptron = "descriptron_core.cli:main"
|
|
63
|
+
biorag-pipeline = "descriptron_core.cli:run_pipeline"
|
|
64
|
+
biorag-key = "descriptron_core.cli:run_key_builder"
|
|
65
|
+
biorag-audit = "descriptron_core.cli:run_confabulation_checker"
|
|
66
|
+
biorag-novelty = "descriptron_core.cli:run_novelty_score"
|
|
67
|
+
biorag-calibrate = "descriptron_core.cli:run_calibrate"
|
|
68
|
+
descriptron-keys = "descriptron_core.cli:run_keys"
|
|
69
|
+
|
|
70
|
+
[project.urls]
|
|
71
|
+
Homepage = "https://github.com/alexrvandam/Descriptron"
|
|
72
|
+
Repository = "https://github.com/alexrvandam/Descriptron"
|
|
73
|
+
Issues = "https://github.com/alexrvandam/Descriptron/issues"
|
|
74
|
+
|
|
75
|
+
[tool.hatch.build.targets.wheel]
|
|
76
|
+
packages = ["src/descriptron_core"]
|
|
77
|
+
|
|
78
|
+
# tools/ and data/ sit inside the package directory, so `packages` already ships
|
|
79
|
+
# them; a force-include here would add every file a second time and the build
|
|
80
|
+
# fails with "a second file is being added to the wheel archive at the same path".
|
|
81
|
+
[tool.hatch.build]
|
|
82
|
+
artifacts = ["src/descriptron_core/tools/**", "src/descriptron_core/data/**"]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "descriptron-core"
|
|
7
|
+
version = "2.0.3"
|
|
8
|
+
description = "Evidence-tiered species descriptions, keys and audits from phenomic matrices"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{ name = "Alex R. Van Dam" }]
|
|
13
|
+
keywords = ["taxonomy", "morphometrics", "phenomics", "species description", "COCO"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
17
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"License :: OSI Approved :: Apache Software License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# Derived from the imports of the 62 programs in this package, not from memory:
|
|
24
|
+
# `python -m descriptron_core.cli --list` names them. No torch, no CUDA, no
|
|
25
|
+
# compiler — this installs in about a minute on Linux, macOS and Windows, and
|
|
26
|
+
# with the deposited COCO files it reproduces every analysis in the methods paper.
|
|
27
|
+
dependencies = [
|
|
28
|
+
"numpy>=1.23",
|
|
29
|
+
"pandas>=1.5",
|
|
30
|
+
"scipy>=1.9",
|
|
31
|
+
"matplotlib>=3.6",
|
|
32
|
+
"scikit-learn>=1.2",
|
|
33
|
+
"scikit-image>=0.20",
|
|
34
|
+
"opencv-python-headless>=4.7", # headless: the analysis half never opens a window
|
|
35
|
+
"pillow>=9",
|
|
36
|
+
"pycocotools>=2.0.6",
|
|
37
|
+
"seaborn>=0.12",
|
|
38
|
+
"statsmodels>=0.14",
|
|
39
|
+
"scikit-posthocs>=0.7",
|
|
40
|
+
"umap-learn>=0.5",
|
|
41
|
+
"networkx>=3",
|
|
42
|
+
"pyefd>=1.6",
|
|
43
|
+
"biopython>=1.81",
|
|
44
|
+
"PyYAML>=6",
|
|
45
|
+
"lxml>=4.9",
|
|
46
|
+
"openpyxl>=3.1",
|
|
47
|
+
"python-docx>=1.0", # treatment and monograph .docx export
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.optional-dependencies]
|
|
51
|
+
# Only needed to *write* treatments. The audit, key, matrix, novelty scoring and
|
|
52
|
+
# delimitation are all deterministic and need no model at all.
|
|
53
|
+
llm = ["anthropic>=0.40"]
|
|
54
|
+
# literature retrieval (the RAG in BioRAG): BioSysLit treatments from Zenodo and your
|
|
55
|
+
# own PDFs. Keyword retrieval needs only the first two; sentence-embedding retrieval
|
|
56
|
+
# (`index --embeddings`) also needs sentence-transformers + faiss-cpu, which pull in torch.
|
|
57
|
+
rag = ["requests>=2.28", "pdfplumber>=0.10"]
|
|
58
|
+
rag-embeddings = ["requests>=2.28", "pdfplumber>=0.10", "sentence-transformers>=2.2", "faiss-cpu>=1.7"]
|
|
59
|
+
dev = ["pytest>=7", "build>=1", "twine>=5"]
|
|
60
|
+
|
|
61
|
+
[project.scripts]
|
|
62
|
+
descriptron = "descriptron_core.cli:main"
|
|
63
|
+
biorag-pipeline = "descriptron_core.cli:run_pipeline"
|
|
64
|
+
biorag-key = "descriptron_core.cli:run_key_builder"
|
|
65
|
+
biorag-audit = "descriptron_core.cli:run_confabulation_checker"
|
|
66
|
+
biorag-novelty = "descriptron_core.cli:run_novelty_score"
|
|
67
|
+
biorag-calibrate = "descriptron_core.cli:run_calibrate"
|
|
68
|
+
descriptron-keys = "descriptron_core.cli:run_keys"
|
|
69
|
+
|
|
70
|
+
[project.urls]
|
|
71
|
+
Homepage = "https://github.com/alexrvandam/Descriptron"
|
|
72
|
+
Repository = "https://github.com/alexrvandam/Descriptron"
|
|
73
|
+
Issues = "https://github.com/alexrvandam/Descriptron/issues"
|
|
74
|
+
|
|
75
|
+
[tool.hatch.build.targets.wheel]
|
|
76
|
+
packages = ["src/descriptron_core"]
|
|
77
|
+
|
|
78
|
+
# tools/ and data/ sit inside the package directory, so `packages` already ships
|
|
79
|
+
# them; a force-include here would add every file a second time and the build
|
|
80
|
+
# fails with "a second file is being added to the wheel archive at the same path".
|
|
81
|
+
[tool.hatch.build]
|
|
82
|
+
artifacts = ["src/descriptron_core/tools/**", "src/descriptron_core/data/**"]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "descriptron-core"
|
|
7
|
+
version = "2.0.3"
|
|
8
|
+
description = "Evidence-tiered species descriptions, keys and audits from phenomic matrices"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{ name = "Alex R. Van Dam" }]
|
|
13
|
+
keywords = ["taxonomy", "morphometrics", "phenomics", "species description", "COCO"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Bio-Informatics",
|
|
17
|
+
"Topic :: Scientific/Engineering :: Image Processing",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
"License :: OSI Approved :: Apache Software License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
# Derived from the imports of the 62 programs in this package, not from memory:
|
|
24
|
+
# `python -m descriptron_core.cli --list` names them. No torch, no CUDA, no
|
|
25
|
+
# compiler — this installs in about a minute on Linux, macOS and Windows, and
|
|
26
|
+
# with the deposited COCO files it reproduces every analysis in the methods paper.
|
|
27
|
+
dependencies = [
|
|
28
|
+
"numpy>=1.23",
|
|
29
|
+
"pandas>=1.5",
|
|
30
|
+
"scipy>=1.9",
|
|
31
|
+
"matplotlib>=3.6",
|
|
32
|
+
"scikit-learn>=1.2",
|
|
33
|
+
"scikit-image>=0.20",
|
|
34
|
+
"opencv-python-headless>=4.7", # headless: the analysis half never opens a window
|
|
35
|
+
"pillow>=9",
|
|
36
|
+
"pycocotools>=2.0.6",
|
|
37
|
+
"seaborn>=0.12",
|
|
38
|
+
"statsmodels>=0.14",
|
|
39
|
+
"scikit-posthocs>=0.7",
|
|
40
|
+
"umap-learn>=0.5",
|
|
41
|
+
"networkx>=3",
|
|
42
|
+
"pyefd>=1.6",
|
|
43
|
+
"biopython>=1.81",
|
|
44
|
+
"PyYAML>=6",
|
|
45
|
+
"lxml>=4.9",
|
|
46
|
+
"openpyxl>=3.1",
|
|
47
|
+
"python-docx>=1.0", # treatment and monograph .docx export
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.optional-dependencies]
|
|
51
|
+
# Only needed to *write* treatments. The audit, key, matrix, novelty scoring and
|
|
52
|
+
# delimitation are all deterministic and need no model at all.
|
|
53
|
+
llm = ["anthropic>=0.40"]
|
|
54
|
+
# literature retrieval (the RAG in BioRAG): BioSysLit treatments from Zenodo and your
|
|
55
|
+
# own PDFs. Keyword retrieval needs only the first two; sentence-embedding retrieval
|
|
56
|
+
# (`index --embeddings`) also needs sentence-transformers + faiss-cpu, which pull in torch.
|
|
57
|
+
rag = ["requests>=2.28", "pdfplumber>=0.10"]
|
|
58
|
+
rag-embeddings = ["requests>=2.28", "pdfplumber>=0.10", "sentence-transformers>=2.2", "faiss-cpu>=1.7"]
|
|
59
|
+
dev = ["pytest>=7", "build>=1", "twine>=5"]
|
|
60
|
+
|
|
61
|
+
[project.scripts]
|
|
62
|
+
descriptron = "descriptron_core.cli:main"
|
|
63
|
+
biorag-pipeline = "descriptron_core.cli:run_pipeline"
|
|
64
|
+
biorag-key = "descriptron_core.cli:run_key_builder"
|
|
65
|
+
biorag-audit = "descriptron_core.cli:run_confabulation_checker"
|
|
66
|
+
biorag-novelty = "descriptron_core.cli:run_novelty_score"
|
|
67
|
+
biorag-calibrate = "descriptron_core.cli:run_calibrate"
|
|
68
|
+
|
|
69
|
+
[project.urls]
|
|
70
|
+
Homepage = "https://github.com/alexrvandam/Descriptron"
|
|
71
|
+
Repository = "https://github.com/alexrvandam/Descriptron"
|
|
72
|
+
Issues = "https://github.com/alexrvandam/Descriptron/issues"
|
|
73
|
+
|
|
74
|
+
[tool.hatch.build.targets.wheel]
|
|
75
|
+
packages = ["src/descriptron_core"]
|
|
76
|
+
|
|
77
|
+
# tools/ and data/ sit inside the package directory, so `packages` already ships
|
|
78
|
+
# them; a force-include here would add every file a second time and the build
|
|
79
|
+
# fails with "a second file is being added to the wheel archive at the same path".
|
|
80
|
+
[tool.hatch.build]
|
|
81
|
+
artifacts = ["src/descriptron_core/tools/**", "src/descriptron_core/data/**"]
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""
|
|
2
|
+
descriptron_core.cli — one entry point for the analysis programs
|
|
3
|
+
================================================================
|
|
4
|
+
|
|
5
|
+
The 62 programs in this package are run with `runpy` exactly as they are run
|
|
6
|
+
from a shell, rather than being imported as modules. That is deliberate: they
|
|
7
|
+
were written as scripts, they use `if __name__ == "__main__"`, and several
|
|
8
|
+
import their siblings by plain name. Executing them as `__main__` with their own
|
|
9
|
+
directory on `sys.path` preserves that behaviour exactly, so packaging cannot
|
|
10
|
+
quietly change what a program does — which matters when the output is a
|
|
11
|
+
published species description.
|
|
12
|
+
|
|
13
|
+
descriptron --list
|
|
14
|
+
descriptron biorag_key_builder_v1 --help
|
|
15
|
+
biorag-audit --help
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import os
|
|
20
|
+
import runpy
|
|
21
|
+
import sys
|
|
22
|
+
from importlib.resources import files
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
__all__ = ["main", "tools_dir", "data_path", "available"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def tools_dir() -> Path:
|
|
29
|
+
return Path(str(files("descriptron_core") / "tools"))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def data_path(*parts: str) -> Path:
|
|
33
|
+
"""Prompts, taxon profiles, ontology releases and schemas that ship with the package."""
|
|
34
|
+
return Path(str(files("descriptron_core") / "data")).joinpath(*parts)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def available() -> list[str]:
|
|
38
|
+
d = tools_dir()
|
|
39
|
+
if not d.exists():
|
|
40
|
+
return []
|
|
41
|
+
return sorted(p.stem for p in d.iterdir()
|
|
42
|
+
if p.suffix in (".py", ".sh") and not p.name.startswith("_"))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _resolve(name: str) -> Path:
|
|
46
|
+
d = tools_dir()
|
|
47
|
+
for candidate in (d / name, d / f"{name}.py", d / f"{name}.sh"):
|
|
48
|
+
if candidate.exists():
|
|
49
|
+
return candidate
|
|
50
|
+
matches = [t for t in available() if t.startswith(name)]
|
|
51
|
+
if len(matches) == 1:
|
|
52
|
+
return _resolve(matches[0])
|
|
53
|
+
if matches:
|
|
54
|
+
raise SystemExit(f"'{name}' is ambiguous: {', '.join(matches)}")
|
|
55
|
+
raise SystemExit(f"unknown program '{name}'. `descriptron --list` shows them all.")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def run(name: str, argv: list[str] | None = None) -> None:
|
|
59
|
+
path = _resolve(name)
|
|
60
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
61
|
+
# the programs' own directory goes on sys.path so a script that imports a
|
|
62
|
+
# sibling by plain name keeps working, and the packaged prompts and ontology
|
|
63
|
+
# releases are findable without anyone passing a path
|
|
64
|
+
sys.path.insert(0, str(path.parent))
|
|
65
|
+
os.environ.setdefault("DESCRIPTRON_DATA", str(data_path()))
|
|
66
|
+
if path.suffix == ".sh":
|
|
67
|
+
os.execvp("bash", ["bash", str(path), *argv])
|
|
68
|
+
sys.argv = [str(path), *argv]
|
|
69
|
+
runpy.run_path(str(path), run_name="__main__")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def main(argv: list[str] | None = None) -> None:
|
|
73
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
74
|
+
if not args or args[0] in ("-h", "--help", "help"):
|
|
75
|
+
print(__doc__.strip())
|
|
76
|
+
print(f"\n{len(available())} programs available; --list shows them.")
|
|
77
|
+
return
|
|
78
|
+
if args[0] in ("--list", "list"):
|
|
79
|
+
for name in available():
|
|
80
|
+
print(name)
|
|
81
|
+
return
|
|
82
|
+
if args[0] in ("--where", "where"):
|
|
83
|
+
print(f"tools: {tools_dir()}\ndata: {data_path()}")
|
|
84
|
+
return
|
|
85
|
+
run(args[0], args[1:])
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _fixed(script: str):
|
|
89
|
+
def entry() -> None:
|
|
90
|
+
run(script, sys.argv[1:])
|
|
91
|
+
return entry
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
run_pipeline = _fixed("run_full_pipeline_v2")
|
|
95
|
+
run_key_builder = _fixed("biorag_key_builder_v1")
|
|
96
|
+
run_confabulation_checker = _fixed("biorag_confabulation_checker_v2")
|
|
97
|
+
run_novelty_score = _fixed("biorag_novelty_score_v1")
|
|
98
|
+
run_calibrate = _fixed("biorag_calibrate_v1")
|
|
99
|
+
run_keys = _fixed("descriptron_credentials")
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_llm_backend.py
RENAMED
|
@@ -288,6 +288,12 @@ def client_from_args(args, log_path: Optional[str] = None):
|
|
|
288
288
|
--api-base-url, or no model at all."""
|
|
289
289
|
import os
|
|
290
290
|
key_env = getattr(args, "api_key_env", None) or "ANTHROPIC_API_KEY"
|
|
291
|
+
if (getattr(args, "llm_backend", "") or "").lower() == "api" and not os.environ.get(key_env):
|
|
292
|
+
try: # v2.0.4: credentials file / first-use prompt
|
|
293
|
+
import descriptron_credentials as _creds
|
|
294
|
+
_creds.ensure_key(key_env)
|
|
295
|
+
except ImportError:
|
|
296
|
+
pass
|
|
291
297
|
return make_llm_client(getattr(args, "llm_backend", "claude-code"),
|
|
292
298
|
api_key=os.environ.get(key_env),
|
|
293
299
|
claude_bin=getattr(args, "claude_bin", None),
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
descriptron_credentials.py — where Descriptron finds your API keys and tokens
|
|
4
|
+
=============================================================================
|
|
5
|
+
|
|
6
|
+
Two keys are ever needed, each by one optional part of Descriptron:
|
|
7
|
+
|
|
8
|
+
ANTHROPIC_API_KEY species descriptions with --llm_backend api
|
|
9
|
+
HF_TOKEN DINOLand, to download Meta's gated DINOv3 weights once
|
|
10
|
+
|
|
11
|
+
Where a key is looked up, in this order:
|
|
12
|
+
|
|
13
|
+
1. the environment (`export ANTHROPIC_API_KEY=...`) — always wins;
|
|
14
|
+
2. the credentials file, one `NAME=value` per line:
|
|
15
|
+
$DESCRIPTRON_CREDENTIALS, or ~/.config/descriptron/credentials
|
|
16
|
+
You can write this file yourself, or let Descriptron write it:
|
|
17
|
+
3. a prompt, the first time the key is actually needed — only in an interactive
|
|
18
|
+
terminal (or the GUI), never in batch jobs, and never when
|
|
19
|
+
DESCRIPTRON_NO_KEY_PROMPT=1. Pressing Enter skips it; the step that needed the
|
|
20
|
+
key then reports what is missing instead of failing obscurely.
|
|
21
|
+
|
|
22
|
+
The file is created readable by you only (0600). Keys are never written to logs,
|
|
23
|
+
project folders or the Docker image.
|
|
24
|
+
|
|
25
|
+
python descriptron_credentials.py --list # which keys are set (values hidden)
|
|
26
|
+
python descriptron_credentials.py --set HF_TOKEN # enter or replace one
|
|
27
|
+
python descriptron_credentials.py --remove HF_TOKEN
|
|
28
|
+
"""
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import argparse
|
|
32
|
+
import getpass
|
|
33
|
+
import os
|
|
34
|
+
import sys
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
from typing import Dict, Optional
|
|
37
|
+
|
|
38
|
+
KNOWN = {
|
|
39
|
+
"ANTHROPIC_API_KEY": ("species descriptions (--llm_backend api)",
|
|
40
|
+
"https://console.anthropic.com/settings/keys"),
|
|
41
|
+
"HF_TOKEN": ("DINOLand: downloading Meta's DINOv3 weights (accept the licence first at "
|
|
42
|
+
"https://huggingface.co/facebook/dinov3-vitb16-pretrain-lvd1689m)",
|
|
43
|
+
"https://huggingface.co/settings/tokens"),
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def credentials_path() -> Path:
|
|
48
|
+
p = os.environ.get("DESCRIPTRON_CREDENTIALS")
|
|
49
|
+
if p:
|
|
50
|
+
return Path(p).expanduser()
|
|
51
|
+
base = os.environ.get("XDG_CONFIG_HOME") or os.path.join(os.path.expanduser("~"), ".config")
|
|
52
|
+
return Path(base) / "descriptron" / "credentials"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def read_file(path: Optional[Path] = None) -> Dict[str, str]:
|
|
56
|
+
path = path or credentials_path()
|
|
57
|
+
out: Dict[str, str] = {}
|
|
58
|
+
try:
|
|
59
|
+
for line in path.read_text().splitlines():
|
|
60
|
+
line = line.strip()
|
|
61
|
+
if not line or line.startswith("#") or "=" not in line:
|
|
62
|
+
continue
|
|
63
|
+
k, v = line.split("=", 1)
|
|
64
|
+
k, v = k.strip(), v.strip().strip('"').strip("'")
|
|
65
|
+
if k and v:
|
|
66
|
+
out[k] = v
|
|
67
|
+
except OSError:
|
|
68
|
+
pass
|
|
69
|
+
return out
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def write_file(values: Dict[str, str], path: Optional[Path] = None) -> Path:
|
|
73
|
+
path = path or credentials_path()
|
|
74
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
try:
|
|
76
|
+
os.chmod(path.parent, 0o700)
|
|
77
|
+
except OSError:
|
|
78
|
+
pass
|
|
79
|
+
body = "# Descriptron keys — one NAME=value per line; keep this file private\n" + \
|
|
80
|
+
"".join(f"{k}={v}\n" for k, v in sorted(values.items()))
|
|
81
|
+
fd = os.open(str(path), os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
|
|
82
|
+
with os.fdopen(fd, "w") as f:
|
|
83
|
+
f.write(body)
|
|
84
|
+
os.chmod(path, 0o600)
|
|
85
|
+
return path
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def load_into_environment() -> Dict[str, str]:
|
|
89
|
+
"""Copy keys from the file into os.environ where not already set (the environment wins).
|
|
90
|
+
Returns the names that were loaded. Child processes then inherit them."""
|
|
91
|
+
loaded = {}
|
|
92
|
+
for k, v in read_file().items():
|
|
93
|
+
if not os.environ.get(k):
|
|
94
|
+
os.environ[k] = v
|
|
95
|
+
loaded[k] = v
|
|
96
|
+
return loaded
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def prompting_allowed() -> bool:
|
|
100
|
+
if os.environ.get("DESCRIPTRON_NO_KEY_PROMPT", "").strip() not in ("", "0", "false", "no"):
|
|
101
|
+
return False
|
|
102
|
+
try:
|
|
103
|
+
return sys.stdin.isatty() and sys.stderr.isatty()
|
|
104
|
+
except (AttributeError, ValueError):
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def save_key(name: str, value: str) -> Path:
|
|
109
|
+
vals = read_file()
|
|
110
|
+
vals[name] = value
|
|
111
|
+
os.environ[name] = value
|
|
112
|
+
return write_file(vals)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def ensure_key(name: str, purpose: Optional[str] = None, where: Optional[str] = None,
|
|
116
|
+
ask=None) -> Optional[str]:
|
|
117
|
+
"""Return the key: environment, then the credentials file, then (first use only) a prompt.
|
|
118
|
+
|
|
119
|
+
`ask` replaces the terminal prompt (the GUI passes a dialog); it receives
|
|
120
|
+
(name, purpose, where) and returns the value or None. Nothing is asked when prompting
|
|
121
|
+
is switched off or no one is there to answer; then None is returned."""
|
|
122
|
+
if os.environ.get(name):
|
|
123
|
+
return os.environ[name]
|
|
124
|
+
stored = read_file().get(name)
|
|
125
|
+
if stored:
|
|
126
|
+
os.environ[name] = stored
|
|
127
|
+
return stored
|
|
128
|
+
purpose = purpose or KNOWN.get(name, ("", ""))[0]
|
|
129
|
+
where = where or KNOWN.get(name, ("", ""))[1]
|
|
130
|
+
if os.environ.get("DESCRIPTRON_NO_KEY_PROMPT", "").strip() not in ("", "0", "false", "no"):
|
|
131
|
+
return None
|
|
132
|
+
if ask is not None:
|
|
133
|
+
value = ask(name, purpose, where)
|
|
134
|
+
elif prompting_allowed():
|
|
135
|
+
sys.stderr.write(f"\nDescriptron needs {name} for {purpose}.\n")
|
|
136
|
+
if where:
|
|
137
|
+
sys.stderr.write(f" Get one at: {where}\n")
|
|
138
|
+
sys.stderr.write(f" It will be saved (readable by you only) in {credentials_path()}\n"
|
|
139
|
+
f" so you are asked only once. Press Enter to skip.\n")
|
|
140
|
+
value = getpass.getpass(f" {name}: ")
|
|
141
|
+
else:
|
|
142
|
+
return None
|
|
143
|
+
value = (value or "").strip()
|
|
144
|
+
if not value:
|
|
145
|
+
return None
|
|
146
|
+
path = save_key(name, value)
|
|
147
|
+
sys.stderr.write(f" saved {name} to {path}\n")
|
|
148
|
+
return value
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def main(argv=None):
|
|
152
|
+
ap = argparse.ArgumentParser(description="Show, set or remove the keys Descriptron uses.")
|
|
153
|
+
g = ap.add_mutually_exclusive_group()
|
|
154
|
+
g.add_argument("--list", action="store_true", help="which keys are set (values hidden) — the default")
|
|
155
|
+
g.add_argument("--set", metavar="NAME", help="enter or replace a key (asked for without echo)")
|
|
156
|
+
g.add_argument("--remove", metavar="NAME", help="delete a key from the file")
|
|
157
|
+
a = ap.parse_args(argv)
|
|
158
|
+
path = credentials_path()
|
|
159
|
+
if a.set:
|
|
160
|
+
v = getpass.getpass(f"{a.set}: ").strip()
|
|
161
|
+
if not v:
|
|
162
|
+
print("nothing entered; unchanged"); return 1
|
|
163
|
+
print(f"saved {a.set} to {save_key(a.set, v)}"); return 0
|
|
164
|
+
if a.remove:
|
|
165
|
+
vals = read_file()
|
|
166
|
+
if vals.pop(a.remove, None) is None:
|
|
167
|
+
print(f"{a.remove} is not in {path}"); return 1
|
|
168
|
+
write_file(vals); print(f"removed {a.remove} from {path}"); return 0
|
|
169
|
+
stored = read_file()
|
|
170
|
+
print(f"credentials file: {path}{'' if path.exists() else ' (not created yet)'}")
|
|
171
|
+
for k in sorted(set(KNOWN) | set(stored)):
|
|
172
|
+
src = "environment" if os.environ.get(k) else ("file" if k in stored else "not set")
|
|
173
|
+
print(f" {k:18s} {src:12s} {KNOWN.get(k, ('',))[0]}")
|
|
174
|
+
return 0
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == "__main__":
|
|
178
|
+
sys.exit(main())
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/run_full_pipeline_v2.py
RENAMED
|
@@ -1871,6 +1871,19 @@ def main():
|
|
|
1871
1871
|
],
|
|
1872
1872
|
)
|
|
1873
1873
|
|
|
1874
|
+
# v2.0.4: the API key comes from the environment, the credentials file, or (first use, interactive
|
|
1875
|
+
# only) a prompt; asked here once so every step inherits it. Never logged.
|
|
1876
|
+
if args.llm_backend == "api":
|
|
1877
|
+
try:
|
|
1878
|
+
import descriptron_credentials as _creds
|
|
1879
|
+
_creds.load_into_environment()
|
|
1880
|
+
if not _creds.ensure_key("ANTHROPIC_API_KEY"):
|
|
1881
|
+
logger.warning(" --llm_backend api but no ANTHROPIC_API_KEY (environment, %s, or prompt): "
|
|
1882
|
+
"the description steps will fail; use --llm_backend none for the data-only "
|
|
1883
|
+
"outputs", _creds.credentials_path())
|
|
1884
|
+
except ImportError:
|
|
1885
|
+
pass
|
|
1886
|
+
|
|
1874
1887
|
logger.info("=" * 70)
|
|
1875
1888
|
logger.info("Descriptron → BioRAG Full Pipeline")
|
|
1876
1889
|
logger.info("=" * 70)
|
|
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
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/FHS_and_CLAHE_V21.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_calibrate_v1.py
RENAMED
|
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
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_key_fuzzy_v1.py
RENAMED
|
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
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/biorag_specimen_id.py
RENAMED
|
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
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/descriptron_rosetta.py
RENAMED
|
File without changes
|
{descriptron_core-2.0.2 → descriptron_core-2.0.4}/src/descriptron_core/tools/landmark_gpa_V1.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|