comparator-recommender 0.1.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.
Files changed (24) hide show
  1. comparator_recommender-0.1.1/.github/release-drafter.yml +31 -0
  2. comparator_recommender-0.1.1/.github/workflows/ci.yml +10 -0
  3. comparator_recommender-0.1.1/.github/workflows/compatibility.yml +65 -0
  4. comparator_recommender-0.1.1/.github/workflows/merge.yml +13 -0
  5. comparator_recommender-0.1.1/.github/workflows/publish.yml +21 -0
  6. comparator_recommender-0.1.1/.gitignore +9 -0
  7. comparator_recommender-0.1.1/PKG-INFO +94 -0
  8. comparator_recommender-0.1.1/README.md +79 -0
  9. comparator_recommender-0.1.1/pyproject.toml +52 -0
  10. comparator_recommender-0.1.1/src/comparator_recommender/__init__.py +10 -0
  11. comparator_recommender-0.1.1/src/comparator_recommender/adapters.py +57 -0
  12. comparator_recommender-0.1.1/src/comparator_recommender/backends/__init__.py +6 -0
  13. comparator_recommender-0.1.1/src/comparator_recommender/backends/base.py +54 -0
  14. comparator_recommender-0.1.1/src/comparator_recommender/backends/postgresql.py +620 -0
  15. comparator_recommender-0.1.1/src/comparator_recommender/config.py +29 -0
  16. comparator_recommender-0.1.1/src/comparator_recommender/models.py +98 -0
  17. comparator_recommender-0.1.1/src/comparator_recommender/plugin.py +197 -0
  18. comparator_recommender-0.1.1/src/comparator_recommender/services.py +74 -0
  19. comparator_recommender-0.1.1/src/comparator_recommender/setup_cli.py +77 -0
  20. comparator_recommender-0.1.1/src/comparator_recommender/tools.py +47 -0
  21. comparator_recommender-0.1.1/tests/test_adapters.py +22 -0
  22. comparator_recommender-0.1.1/tests/test_configuration_mwe.py +194 -0
  23. comparator_recommender-0.1.1/tests/test_sqlalchemy_backend.py +310 -0
  24. comparator_recommender-0.1.1/uv.lock +4257 -0
@@ -0,0 +1,31 @@
1
+ name-template: 'v$RESOLVED_VERSION'
2
+ tag-template: 'v$RESOLVED_VERSION'
3
+ commitish: main
4
+
5
+ categories:
6
+ - title: Breaking Changes
7
+ labels: ['breaking']
8
+ - title: Features
9
+ labels: ['feature']
10
+ - title: Fixes
11
+ labels: ['fix']
12
+ - title: Dependencies
13
+ labels: ['dependencies']
14
+
15
+ template: |
16
+ $CHANGES
17
+
18
+ change-template: '- **$TITLE** (#$NUMBER) @$AUTHOR'
19
+
20
+ version-resolver:
21
+ major:
22
+ labels: ['breaking']
23
+ minor:
24
+ labels: ['feature']
25
+ patch:
26
+ labels: ['fix', 'dependencies']
27
+ default: patch
28
+
29
+ exclude-labels: ['chore']
30
+
31
+ autolabeler: []
@@ -0,0 +1,10 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ branches: [main]
5
+ types: [opened, synchronize, reopened, labeled, unlabeled]
6
+ jobs:
7
+ label-gate:
8
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/label-gate.yml@main
9
+ build-test:
10
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test.yml@main
@@ -0,0 +1,65 @@
1
+ name: Compatibility
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ paths:
7
+ - .github/workflows/compatibility.yml
8
+ - pyproject.toml
9
+ - uv.lock
10
+ - src/**
11
+ - tests/**
12
+ push:
13
+ tags: ['v*']
14
+ repository_dispatch:
15
+ types: [groundworkers-compatibility]
16
+ workflow_dispatch:
17
+ inputs:
18
+ groundworkers_version:
19
+ description: Released Groundworkers version to test
20
+ required: true
21
+ default: 0.7.0
22
+ python_versions:
23
+ description: Comma-separated Python versions to test
24
+ required: true
25
+ default: 3.12,3.13
26
+ schedule:
27
+ - cron: "17 3 * * 1"
28
+
29
+ permissions:
30
+ contents: read
31
+
32
+ jobs:
33
+ prepare:
34
+ runs-on: ubuntu-latest
35
+ outputs:
36
+ include: ${{ steps.matrix.outputs.include }}
37
+ steps:
38
+ - id: matrix
39
+ env:
40
+ REQUESTED_GROUNDWORKERS: ${{ github.event.client_payload.groundworkers_version || inputs.groundworkers_version || '0.7.0' }}
41
+ REQUESTED_PYTHON_JSON: ${{ toJSON(github.event.client_payload.python_versions) }}
42
+ INPUT_PYTHON_VERSIONS: ${{ inputs.python_versions || '3.12,3.13' }}
43
+ run: |
44
+ python -c 'import json, os; raw=os.environ["REQUESTED_PYTHON_JSON"]; versions=json.loads(raw) if raw not in ("", "null") else [v.strip() for v in os.environ["INPUT_PYTHON_VERSIONS"].split(",") if v.strip()]; gw=os.environ["REQUESTED_GROUNDWORKERS"]; print("include=" + json.dumps({"include": [{"python": version, "groundworkers": gw} for version in versions]}, separators=(",", ":")))' >> "$GITHUB_OUTPUT"
45
+
46
+ compatibility:
47
+ needs: prepare
48
+ runs-on: ubuntu-latest
49
+ strategy:
50
+ fail-fast: false
51
+ matrix: ${{ fromJSON(needs.prepare.outputs.include) }}
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+ - uses: actions/setup-python@v5
55
+ with:
56
+ python-version: ${{ matrix.python }}
57
+ - uses: astral-sh/setup-uv@v6
58
+ with:
59
+ enable-cache: true
60
+ - run: uv build --wheel --out-dir compatibility-dist
61
+ - run: uv venv --python "${{ matrix.python }}" .compatibility-venv
62
+ - run: uv pip install --python .compatibility-venv/bin/python "groundworkers==${{ matrix.groundworkers }}"
63
+ - run: uv pip install --python .compatibility-venv/bin/python compatibility-dist/*.whl "pytest>=9,<10"
64
+ - run: .compatibility-venv/bin/python -m pytest -q
65
+
@@ -0,0 +1,13 @@
1
+ name: Release Update
2
+ on:
3
+ pull_request:
4
+ types: [closed]
5
+ branches: [main]
6
+ permissions:
7
+ contents: write
8
+ pull-requests: read
9
+ jobs:
10
+ draft:
11
+ if: github.event.pull_request.merged == true
12
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/release-drafter.yml@main
13
+ secrets: inherit
@@ -0,0 +1,21 @@
1
+ name: Publish
2
+ on:
3
+ push:
4
+ tags: ['v*']
5
+ jobs:
6
+ build:
7
+ uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/publish.yml@main
8
+ publish:
9
+ # Inline: PyPI OIDC checks job_workflow_ref, which must point to this file.
10
+ # Moving pypa/gh-action-pypi-publish into cava-devops would break the trusted publisher.
11
+ needs: build
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ id-token: write
15
+ environment:
16
+ name: pypi
17
+ url: https://pypi.org/p/comparator-recommender
18
+ steps:
19
+ - uses: actions/download-artifact@v4
20
+ with: { name: dist, path: dist/ }
21
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ .ruff_cache/
4
+ .ty/
5
+ __pycache__/
6
+ *.py[cod]
7
+ dist/
8
+ data/
9
+ .DS_Store
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.5
2
+ Name: comparator-recommender
3
+ Version: 0.1.1
4
+ Summary: Groundworkers plugin for recommending comparator cohorts.
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: groundworkers[tui]<1,>=0.7
7
+ Requires-Dist: oa-configurator<3,>=2
8
+ Requires-Dist: omop-emb<4,>=3
9
+ Requires-Dist: omop-llm<2,>=1
10
+ Requires-Dist: pandas>=3
11
+ Requires-Dist: pgvector<1,>=0.5
12
+ Requires-Dist: pydantic<3,>=2
13
+ Requires-Dist: sqlalchemy<3,>=2
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Comparator Recommender
17
+
18
+ This package is an installable Groundworkers plugin for finding target cohorts
19
+ and recommending pairwise comparators from a precomputed comparator catalogue.
20
+
21
+ It contributes two entry points:
22
+
23
+ - `omop.config` exposes `ComparatorRecommenderConfig` to oa-configurator.
24
+ - `groundworkers.plugins` exposes the plugin singleton to Groundworkers.
25
+
26
+ The configuration schema selects a generic comparator database, optionally selects an embedding model for target lookup, and sets the default minimum database support threshold. Groundworkers builds the setup-console workflow directly from this schema without plugin-specific TUI code.
27
+
28
+ The setup console also exposes the plugin's registered preparation steps:
29
+
30
+ - `Load comparator source` asks for the cohort and pairwise-similarity CSVs and loads them into the catalogue.
31
+ - `Create comparator embeddings` generates the stored vectors after the source is loaded.
32
+
33
+ The CSV paths are run arguments, not persistent plugin configuration. Both steps use Groundworkers' durable maintenance-run surface, so progress and logs appear with the core graph and embedding preparation runs.
34
+
35
+ Run the MWE against the published Groundworkers 0.7 stack:
36
+
37
+ ```console
38
+ uv sync --group dev
39
+ uv run pytest
40
+ ```
41
+
42
+ The acceptance test selects an existing CDM database, leaves the optional
43
+ embedding resources unconfigured, reviews the generated change, applies it, and
44
+ verifies the resulting `[tools.comparator_recommender]` section.
45
+
46
+ ## Upgrading to the Groundworkers 0.7 stack
47
+
48
+ This plugin requires `groundworkers[tui]>=0.7,<1`, `oa-configurator>=2,<3`
49
+ and `omop-emb>=3,<4`. For CDM database entries, replace the former
50
+ `schema_name` setting with `cdm_schema`; generic databases such as
51
+ `comparator_db` still use `schema_name`. Remove schema settings from SQLite
52
+ database entries. See the [Groundworkers upgrade guide](https://github.com/AustralianCancerDataNetwork/groundworkers/blob/main/docs/usage/upgrading-from-0.6.md)
53
+ for the shared configuration changes.
54
+
55
+ **The embedding-store migration script is not available yet.** It is tracked
56
+ in [oa-configurator issue #40](https://github.com/AustralianCancerDataNetwork/oa-configurator/issues/40).
57
+ Existing shared stores created before omop-emb 3.0 report `LEGACY_REGISTRY`.
58
+ The [omop-emb legacy-registry guard and migration-command placeholder](https://github.com/AustralianCancerDataNetwork/omop-emb/blob/main/src/omop_emb/model_registry/model_registry_orm.py)
59
+ remain the source of the planned migration command; follow the issue for its
60
+ availability before attempting migration. This plugin does not migrate shared
61
+ embedding stores.
62
+
63
+ Comparator vectors live in `cs_cohort.embedding_vector` in the comparator
64
+ database. The plugin uses omop-emb to generate vectors directly from the selected
65
+ model, without opening the shared embedding-store registry. Upgrading the Python
66
+ packages does not migrate or regenerate existing comparator vectors. Keep the
67
+ same embedding model for creation and lookup; if changing models, explicitly
68
+ rerun `Create comparator embeddings` after loading the source catalogue.
69
+
70
+ ## Architecture
71
+
72
+ The package separates four responsibilities:
73
+
74
+ - `config.py` declares operator-controlled settings and references to shared OA
75
+ resources.
76
+ - `adapters.py` owns the resolved database connection and backend.
77
+ - `models.py` reflects the two non-OMOP catalogue tables into SQLAlchemy mappings.
78
+ - `backends/postgresql.py` uses SQLAlchemy `select`, pgvector expressions,
79
+ mapped row updates, and `Index` objects, with one isolated column migration
80
+ for older catalogue tables. Its backend initialization follows the
81
+ `omop-emb` lifecycle and ensures the pgvector extension before setup runs.
82
+ - `services.py` owns input policy and recommendation defaults. It receives
83
+ ordinary Python values from adapters and contains no MCP code.
84
+ - `tools.py` exposes service operations to agents. Tools should be thin wrappers,
85
+ not a second implementation of the analysis.
86
+
87
+ `plugin.py` is the composition root: Groundworkers calls it once during startup
88
+ to connect configuration to adapters and services, then asks it to register the
89
+ tools. Business logic should not be implemented inside `build()`.
90
+
91
+ The comparator catalogue is not an OMOP CDM table, so it should not be added to
92
+ `omop-alchemy`'s model registry. The local reflected mapping follows the same
93
+ SQLAlchemy model/query conventions while leaving the shared OMOP package focused
94
+ on CDM semantics.
@@ -0,0 +1,79 @@
1
+ # Comparator Recommender
2
+
3
+ This package is an installable Groundworkers plugin for finding target cohorts
4
+ and recommending pairwise comparators from a precomputed comparator catalogue.
5
+
6
+ It contributes two entry points:
7
+
8
+ - `omop.config` exposes `ComparatorRecommenderConfig` to oa-configurator.
9
+ - `groundworkers.plugins` exposes the plugin singleton to Groundworkers.
10
+
11
+ The configuration schema selects a generic comparator database, optionally selects an embedding model for target lookup, and sets the default minimum database support threshold. Groundworkers builds the setup-console workflow directly from this schema without plugin-specific TUI code.
12
+
13
+ The setup console also exposes the plugin's registered preparation steps:
14
+
15
+ - `Load comparator source` asks for the cohort and pairwise-similarity CSVs and loads them into the catalogue.
16
+ - `Create comparator embeddings` generates the stored vectors after the source is loaded.
17
+
18
+ The CSV paths are run arguments, not persistent plugin configuration. Both steps use Groundworkers' durable maintenance-run surface, so progress and logs appear with the core graph and embedding preparation runs.
19
+
20
+ Run the MWE against the published Groundworkers 0.7 stack:
21
+
22
+ ```console
23
+ uv sync --group dev
24
+ uv run pytest
25
+ ```
26
+
27
+ The acceptance test selects an existing CDM database, leaves the optional
28
+ embedding resources unconfigured, reviews the generated change, applies it, and
29
+ verifies the resulting `[tools.comparator_recommender]` section.
30
+
31
+ ## Upgrading to the Groundworkers 0.7 stack
32
+
33
+ This plugin requires `groundworkers[tui]>=0.7,<1`, `oa-configurator>=2,<3`
34
+ and `omop-emb>=3,<4`. For CDM database entries, replace the former
35
+ `schema_name` setting with `cdm_schema`; generic databases such as
36
+ `comparator_db` still use `schema_name`. Remove schema settings from SQLite
37
+ database entries. See the [Groundworkers upgrade guide](https://github.com/AustralianCancerDataNetwork/groundworkers/blob/main/docs/usage/upgrading-from-0.6.md)
38
+ for the shared configuration changes.
39
+
40
+ **The embedding-store migration script is not available yet.** It is tracked
41
+ in [oa-configurator issue #40](https://github.com/AustralianCancerDataNetwork/oa-configurator/issues/40).
42
+ Existing shared stores created before omop-emb 3.0 report `LEGACY_REGISTRY`.
43
+ The [omop-emb legacy-registry guard and migration-command placeholder](https://github.com/AustralianCancerDataNetwork/omop-emb/blob/main/src/omop_emb/model_registry/model_registry_orm.py)
44
+ remain the source of the planned migration command; follow the issue for its
45
+ availability before attempting migration. This plugin does not migrate shared
46
+ embedding stores.
47
+
48
+ Comparator vectors live in `cs_cohort.embedding_vector` in the comparator
49
+ database. The plugin uses omop-emb to generate vectors directly from the selected
50
+ model, without opening the shared embedding-store registry. Upgrading the Python
51
+ packages does not migrate or regenerate existing comparator vectors. Keep the
52
+ same embedding model for creation and lookup; if changing models, explicitly
53
+ rerun `Create comparator embeddings` after loading the source catalogue.
54
+
55
+ ## Architecture
56
+
57
+ The package separates four responsibilities:
58
+
59
+ - `config.py` declares operator-controlled settings and references to shared OA
60
+ resources.
61
+ - `adapters.py` owns the resolved database connection and backend.
62
+ - `models.py` reflects the two non-OMOP catalogue tables into SQLAlchemy mappings.
63
+ - `backends/postgresql.py` uses SQLAlchemy `select`, pgvector expressions,
64
+ mapped row updates, and `Index` objects, with one isolated column migration
65
+ for older catalogue tables. Its backend initialization follows the
66
+ `omop-emb` lifecycle and ensures the pgvector extension before setup runs.
67
+ - `services.py` owns input policy and recommendation defaults. It receives
68
+ ordinary Python values from adapters and contains no MCP code.
69
+ - `tools.py` exposes service operations to agents. Tools should be thin wrappers,
70
+ not a second implementation of the analysis.
71
+
72
+ `plugin.py` is the composition root: Groundworkers calls it once during startup
73
+ to connect configuration to adapters and services, then asks it to register the
74
+ tools. Business logic should not be implemented inside `build()`.
75
+
76
+ The comparator catalogue is not an OMOP CDM table, so it should not be added to
77
+ `omop-alchemy`'s model registry. The local reflected mapping follows the same
78
+ SQLAlchemy model/query conventions while leaving the shared OMOP package focused
79
+ on CDM semantics.
@@ -0,0 +1,52 @@
1
+ [project]
2
+ name = "comparator-recommender"
3
+ version = "0.1.1"
4
+ description = "Groundworkers plugin for recommending comparator cohorts."
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "groundworkers[tui]>=0.7,<1",
9
+ "oa-configurator>=2,<3",
10
+ "omop-emb>=3,<4",
11
+ "omop-llm>=1,<2",
12
+ "pandas>=3",
13
+ "pgvector>=0.5,<1",
14
+ "pydantic>=2,<3",
15
+ "SQLAlchemy>=2,<3",
16
+ ]
17
+
18
+ [project.entry-points."omop.config"]
19
+ comparator_recommender = "comparator_recommender.config:ComparatorRecommenderConfig"
20
+
21
+ [project.entry-points."groundworkers.plugins"]
22
+ comparator_recommender = "comparator_recommender.plugin:plugin"
23
+
24
+ [dependency-groups]
25
+ dev = [
26
+ "groundskeeping>=0.9.1,<1",
27
+ "pytest>=9,<10",
28
+ "ruff>=0.4",
29
+ "ty>=0.0.59",
30
+ ]
31
+
32
+ [build-system]
33
+ requires = ["hatchling"]
34
+ build-backend = "hatchling.build"
35
+
36
+ [tool.uv]
37
+ constraint-dependencies = ["setuptools>=83.0.0"]
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/comparator_recommender"]
41
+
42
+ [tool.pytest.ini_options]
43
+ testpaths = ["tests"]
44
+
45
+ [tool.ruff]
46
+ src = ["src", "tests"]
47
+
48
+ [tool.ruff.lint]
49
+ select = ["E4", "E7", "E9", "F", "I", "UP", "RUF"]
50
+
51
+ [tool.ty.src]
52
+ include = ["src"]
@@ -0,0 +1,10 @@
1
+ """Comparator Recommender plugin configuration MWE."""
2
+
3
+ from comparator_recommender.config import ComparatorRecommenderConfig
4
+ from comparator_recommender.plugin import ComparatorRecommenderPlugin, plugin
5
+
6
+ __all__ = [
7
+ "ComparatorRecommenderConfig",
8
+ "ComparatorRecommenderPlugin",
9
+ "plugin",
10
+ ]
@@ -0,0 +1,57 @@
1
+ """Connections to the comparator catalogue and its embedding model."""
2
+
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass
5
+
6
+ from groundworkers.plugins import PluginReadinessResult
7
+ from oa_configurator import ResolvedDatabase
8
+ from omop_llm import ModelBackend
9
+
10
+ from comparator_recommender.backends import (
11
+ ComparatorSelectorBackend,
12
+ PostgresComparatorSelectorBackend,
13
+ )
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class ComparatorDataAdapter:
18
+ """Own the database-backed comparator operations."""
19
+
20
+ database: ResolvedDatabase
21
+ backend: ComparatorSelectorBackend
22
+
23
+ @classmethod
24
+ def build(
25
+ cls,
26
+ database: ResolvedDatabase,
27
+ model_backend_factory: Callable[[], ModelBackend] | None = None,
28
+ model_source: str | None = None,
29
+ ) -> "ComparatorDataAdapter":
30
+ return cls(
31
+ database=database,
32
+ backend=PostgresComparatorSelectorBackend(
33
+ engine=database.create_engine(register_claims=False),
34
+ schema=database.schema_name or "public",
35
+ model_backend_factory=model_backend_factory,
36
+ model_source=model_source,
37
+ ),
38
+ )
39
+
40
+ def find_target(self, name: str, top_n: int) -> list[tuple[int, str]]:
41
+ return self.backend.find_target(name, top_n)
42
+
43
+ def recommend_comparators(
44
+ self, target_id: int, top_n: int, min_databases: int
45
+ ) -> list[tuple[float, str]]:
46
+ return self.backend.recommend_comparators(target_id, top_n, min_databases)
47
+
48
+ def insert_data(self, cohort_table_path: str, similarity_table_path: str) -> None:
49
+ self.backend.insert_data(cohort_table_path, similarity_table_path)
50
+
51
+ def create_embedding_vectors(self) -> None:
52
+ self.backend.create_embedding_vectors()
53
+
54
+ def verify_readiness(self) -> PluginReadinessResult:
55
+ """Return the backend's read-only readiness report."""
56
+
57
+ return self.backend.verify_readiness()
@@ -0,0 +1,6 @@
1
+ """Backend implementations for comparator catalogue storage."""
2
+
3
+ from comparator_recommender.backends.base import ComparatorSelectorBackend
4
+ from comparator_recommender.backends.postgresql import PostgresComparatorSelectorBackend
5
+
6
+ __all__ = ["ComparatorSelectorBackend", "PostgresComparatorSelectorBackend"]
@@ -0,0 +1,54 @@
1
+ """Storage-independent comparator backend contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from collections.abc import Callable
7
+
8
+ from groundworkers.plugins import PluginReadinessResult
9
+ from omop_llm import ModelBackend
10
+ from sqlalchemy import Engine
11
+
12
+
13
+ class ComparatorSelectorBackend(ABC):
14
+ """Operations required by the comparator recommender service."""
15
+
16
+ def __init__(
17
+ self,
18
+ engine: Engine,
19
+ schema: str,
20
+ model_backend_factory: Callable[[], ModelBackend] | None = None,
21
+ model_source: str | None = None,
22
+ ) -> None:
23
+ if not schema.strip():
24
+ raise ValueError("schema must not be empty")
25
+ self.engine = engine
26
+ self.schema = schema
27
+ self.model_backend_factory = model_backend_factory
28
+ self.model_source = model_source
29
+
30
+ def pre_initialise_store(self) -> None:
31
+ """Prepare mutating setup prerequisites; the default is a no-op.
32
+
33
+ Backend construction and readiness checks are deliberately read-only.
34
+ Mutating setup operations call this hook explicitly when needed.
35
+ """
36
+
37
+ @abstractmethod
38
+ def find_target(self, name: str, top_n: int) -> list[tuple[int, str]]: ...
39
+
40
+ @abstractmethod
41
+ def recommend_comparators(
42
+ self, target_id: int, top_n: int, min_databases: int
43
+ ) -> list[tuple[float, str]]: ...
44
+
45
+ @abstractmethod
46
+ def insert_data(
47
+ self, cohort_table_path: str, similarity_table_path: str
48
+ ) -> None: ...
49
+
50
+ @abstractmethod
51
+ def create_embedding_vectors(self) -> None: ...
52
+
53
+ @abstractmethod
54
+ def verify_readiness(self) -> PluginReadinessResult: ...