Skip to content

feat: Edit Distance Wrapper Service (Text and Graphs) - #25

Open
synapp009 wants to merge 20 commits into
masterfrom
codex/edit-distance-wrapper-service
Open

feat: Edit Distance Wrapper Service (Text and Graphs)#25
synapp009 wants to merge 20 commits into
masterfrom
codex/edit-distance-wrapper-service

Conversation

@synapp009

Copy link
Copy Markdown
Collaborator

Adds noise-generation-wrapper-service for issue #9.

The service wraps 5 text edit distance libraries (RapidFuzz, textdistance, jellyfish, edlib, diff-match-patch) and 3 graph edit distance libraries (NetworkX, GEDLIB via gedlibpy, GMatch4py) into a unified REST API and exposes OpenAPI, CLI, Docker, tests, and CI support. It runs fully self-contained — no external credentials, API keys, or cloud dependencies required.

@synapp009 synapp009 linked an issue Jul 28, 2026 that may be closed by this pull request
5 tasks
synapp009 added 13 commits July 28, 2026 20:24
- Implemented unit tests for text edit distance algorithms covering various backends.
- Added unit tests for graph edit distance computation with multiple algorithm/backend combinations.
- Created integration tests for the edit distance service API, validating HTTP responses and error handling.
- Introduced a smoke test script to verify the overall functionality of the service via HTTP API.
…cing backend param

Align with noise-generation-service pattern:
- Remove `backend` from API/CLI request bodies — each algorithm now
  auto-selects its default backend
- Add `_GED_DEFAULT_BACKEND` dict for graph algorithms mirroring
  `_get_default_backend()` for text
- Remove `--backend` CLI option from both `compare` and `ged-compare`
- Strip `"backend"` from all HTTP test examples, smoke tests, and README
- Add `scipy` dep (required by NetworkX's graph_edit_distance)
- Add `edit-distance-service` CLI entry point to pyproject.toml
- Clean up response models: remove unused import fields, dead code
…nds, trim dead code

- Delete `src/cli.py` (241 lines) — unused Click CLI wrapper duplicating the HTTP API
- Delete `src/__init__.py` — unnecessary one-line docstring file
- Merge 3 identical GMatch4py functions into `_gmatch4py_compute(cls_name)`
- Merge 2 identical GEDLIB functions into `_gedlib_compute(is_exact)`
- Collapse `_networkx_ged_astar` — eliminate 4 redundant try/except blocks and inline cost helpers
- Remove silent numpy fallback in `_textdistance_gotoh` / `_textdistance_smith_waterman`
- Replace if/elif chain in `_jellyfish_phonetic` with dict dispatch; drop dead `match_rating` branch
- Strip `links` field and `by_alias` from `GedResultResponse` (vestige of deleted GET/DELETE endpoints)
- Remove `ProblemDetail.invalid_params` (never populated)
- Remove `from __future__ import annotations` (Python ≥3.11 native)
- Drop unused `click` dependency from pyproject.toml
- Shorten verbose OpenAPI description
- All 70 tests pass (0 regressions)
…nds, trim dead code

- Delete `src/cli.py` (241 lines) — unused Click CLI wrapper duplicating the HTTP API
- Delete `src/__init__.py` — unnecessary one-line docstring file
- Merge 3 identical GMatch4py functions into `_gmatch4py_compute(cls_name)`
- Merge 2 identical GEDLIB functions into `_gedlib_compute(is_exact)`
- Collapse `_networkx_ged_astar` — eliminate 4 redundant try/except blocks and inline cost helpers
- Remove silent numpy fallback in `_textdistance_gotoh` / `_textdistance_smith_waterman`
- Replace if/elif chain in `_jellyfish_phonetic` with dict dispatch; drop dead `match_rating` branch
- Strip `links` field and `by_alias` from `GedResultResponse` (vestige of deleted GET/DELETE endpoints)
- Remove `ProblemDetail.invalid_params` (never populated)
- Remove `from __future__ import annotations` (Python ≥3.11 native)
- Drop unused `click` dependency from pyproject.toml
- Shorten verbose OpenAPI description
- All 70 tests pass (0 regressions)
- models.py: replace Any with concrete types (ResultModel union,
  EditScriptResult.diffs, AlignmentResult.locations)
- text/__init__.py: fix compute_text() return type annotation,
  add dict[str, Any] to all params, handle edlib tuple locations
- graph/__init__.py: fix _graph_ref_to_nx() return type to nx.Graph,
  add Callable import, add dict[str, Any] to params
- main.py: pass Pydantic models directly instead of model_dump()
- workflow: fix lint step (use make lint), replace missing
  test_smoke.sh with inline smoke tests, add set -e
- tests/test_smoke.sh: create smoke test script for 6 endpoints

All 70 unit tests pass, lint is clean, Docker build and
container smoke tests verified.
…ive curl examples

- Remove redundant `/ged` segment from graph routes:
  `/v1/graphs/ged/algorithms` → `/v1/graphs/algorithms`
  `/v1/graphs/ged/compute`   → `/v1/graphs/distance`
- Rename text route for consistency:
  `/v1/text/compare` → `/v1/text/distance`
- Update all references in source code, OpenAPI spec, tests,
  HTTP test files, README, and agent instructions
- Add complete curl examples for all 15 text algorithms and
  4 graph algorithms (6 variants) to README.md
@synapp009
synapp009 force-pushed the codex/edit-distance-wrapper-service branch from 69b8c24 to 0bc1df9 Compare July 28, 2026 19:34
- Add typed Pydantic request models (TextCompareRequest, GedComputeRequest)
- Fix backend override: request.backend now respected over hardcoded default
- Change GED response HTTP status from 201 to 200 (nothing is persisted)
- Remove status field from GedResultResponse (always 'completed')
- Remove empty TestGedResultLifecycle class
- Remove if __name__ block in main.py
- Fix Needleman-Wunsch: gap_cost parameter now passed to textdistance
- Pass edlib parameters (mode, task, k, additional_equalities) correctly
- Fix typo additional_equalites -> additional_equalities
- Make NetworkX GED label-aware: matching node/edge attributes yield cost 0
- Fix test assertions: missing-algorithm now returns 422 via Pydantic
- Auto-fix import ordering and formatting with ruff
The GedResultResponse.status field was removed since it was always
'completed'. Update both the local smoke script (test_smoke.sh) and
the CI workflow (service-edit-distance-service.yml) to assert on
'algorithm' instead of 'status'.
…fy code

- Add Click-based CLI (src/cli.py) mirroring all REST endpoints:
  health, list-text, list-graphs, text-distance, ged-distance
  Supports --base/EDIT_DISTANCE_BASE_URL, inline/file input, param shorthand
- Register edit-distance CLI entry point in pyproject.toml
- Add click and requests to base dependencies

- Install gmatch4py in Dockerfile (enables ged_hausdorff, ged_greedy backends)
- Add .dockerignore to prevent polluted build context
- Add dev/prod docker-compose targets to Makefile

Audit & simplify source code:
- Remove CatalogEntry model (unused class, 0 references)
- Remove GraphRef.graph_ref field (never set, never read)
- Inline ProblemDetail Pydantic model → plain dict
- Inline _make_label_aware_cost factory → lambdas inside _networkx_ged_astar
- Remove Callable import from graph/__init__.py
- Remove redundant deadline=param.get("deadline", None) → .get("deadline")
- Simplify _SHORTHAND_BOOL dict → if/elif chain
- Strip empty docstring from src/__init__.py

Update CI workflow smoke-test assertions.
Update README with CLI usage examples and updated structure.
- Replace `list[dict]` with typed unions (`InputPair | InputPhonetic`,
  `GraphPair`) on request models — Pydantic now validates inputs at
  the boundary, giving 422 instead of 500 on bad data.
- Add 3 GraphRef formats: default (nodes+edges), `node_link`
  (networkx JSON), `adjacency_matrix` (dense matrix).
- Remove manual dict unpacking in `main.py` — dead code after typing.
- Add 2 integration tests for the new graph formats.
- Document all input formats in README.md with JSON examples.
@plc-dev
plc-dev self-requested a review July 29, 2026 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Integration of a Edit-Distance Service

1 participant