diff --git a/.gitignore b/.gitignore index e3f7150..c7419b5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ __pycache__/ chembl_*.txt # Files generated by scimesh workloads +results/ *_similarities.csv test_results.csv test_structures/ diff --git a/scimesh/cli.py b/scimesh/cli.py index c144de6..683cf3c 100644 --- a/scimesh/cli.py +++ b/scimesh/cli.py @@ -14,6 +14,7 @@ def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( prog="scimesh", description="Run local scientific workloads on molecular datasets.", + epilog="Run 'scimesh help' for a quick start and copy-paste examples.", ) subparsers = parser.add_subparsers(dest="workload", required=True) registry = WorkloadRegistry() diff --git a/scimesh/workloads/__init__.py b/scimesh/workloads/__init__.py index e74bfc1..e5cc2f1 100644 --- a/scimesh/workloads/__init__.py +++ b/scimesh/workloads/__init__.py @@ -3,11 +3,13 @@ from __future__ import annotations from scimesh.core.registry import WorkloadRegistry +from scimesh.workloads.help import HelpWorkload from scimesh.workloads.similarity_graph import SimilarityGraphWorkload from scimesh.workloads.similarity_search import SimilaritySearchWorkload def register_workloads(registry: WorkloadRegistry) -> None: """Register built-in workloads in one place, outside the main CLI.""" + registry.register(HelpWorkload()) registry.register(SimilaritySearchWorkload()) registry.register(SimilarityGraphWorkload()) diff --git a/scimesh/workloads/help.py b/scimesh/workloads/help.py new file mode 100644 index 0000000..a220195 --- /dev/null +++ b/scimesh/workloads/help.py @@ -0,0 +1,65 @@ +"""Quick-start help workload.""" + +from __future__ import annotations + +import argparse +from textwrap import dedent + + +HELP_TEXT = dedent( + """\ + SciMesh quick start + =================== + + SciMesh runs molecular similarity workloads locally. Input must be a ChEMBL TSV + with chembl_id and canonical_smiles columns. + + 1. Activate the project environment and create a directory for outputs: + + source .venv/bin/activate + mkdir -p results + + 2. Find molecules similar to gefitinib (CHEMBL939): + + scimesh similarity-search chembl_37_chemreps.txt \\ + --query-id CHEMBL939 \\ + --top-k 20 \\ + --max-rows 10000 \\ + --output results/gefitinib_top20.csv + + 3. Search by a SMILES query instead of a ChEMBL ID: + + scimesh similarity-search chembl_37_chemreps.txt \\ + --query-smiles 'CCO' \\ + --top-k 20 \\ + --output results/smiles_search.csv + + 4. Build a small exact similarity graph: + + scimesh similarity-graph chembl_37_chemreps.txt \\ + --max-rows 1000 \\ + --threshold 0.7 \\ + --block-size 250 \\ + --output results/similarity_graph.csv + + Use --max-rows for quick local tests; omit it to process the full dataset. + For all options, run: + + scimesh similarity-search --help + scimesh similarity-graph --help + """ +) + + +class HelpWorkload: + """Expose practical examples without adding special logic to the main CLI.""" + + name = "help" + help = "Show a quick start and runnable examples." + + def configure_parser(self, parser: argparse.ArgumentParser) -> None: + parser.description = "Show SciMesh setup and usage examples." + + def run(self, args: argparse.Namespace) -> int: + print(HELP_TEXT) + return 0 diff --git a/tests/test_cli_help.py b/tests/test_cli_help.py new file mode 100644 index 0000000..ee193d2 --- /dev/null +++ b/tests/test_cli_help.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from scimesh.cli import main + + +def test_help_command_prints_runnable_examples(capsys: object) -> None: + assert main(["help"]) == 0 + output = capsys.readouterr().out + assert "scimesh similarity-search" in output + assert "scimesh similarity-graph" in output + assert "mkdir -p results" in output