Skip to content

Commit 4df590d

Browse files
committed
Replace REST stubs with FastAPI and wire gRPC CLI runtime
1 parent a968ea4 commit 4df590d

30 files changed

Lines changed: 414 additions & 237 deletions

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,33 @@
11
# Changelog
22

3+
## [2025-10-16T16:35:00-04:00 (America/New_York)]
4+
### Added
5+
- Added a `serve-grpc` CLI subcommand (`meshmind/cli/__main__.py`) that instantiates
6+
`MemoryService` via `create_graph_driver`, delegates to
7+
`meshmind.api.grpc_server.serve_forever`, and is exercised by
8+
`meshmind/tests/test_cli_admin.py` alongside the new docker-compose service
9+
definitions (`docker-compose.yml`, `meshmind/tests/docker/full-stack.yml`).
10+
- Recorded CLI runtime coverage and protobuf drift checks by extending
11+
`meshmind/tests/test_cli_admin.py` and `meshmind/tests/test_protos_packaging.py`,
12+
ensuring the new `serve-grpc` command and `scripts/check_protos.py` guard remain
13+
functional.
14+
15+
### Changed
16+
- Removed the legacy REST stub and Celery fallbacks by requiring real FastAPI and
17+
Celery imports (`meshmind/api/rest.py`, `meshmind/tasks/celery_app.py`,
18+
`meshmind/tasks/scheduled.py`) and updated smoke tests to exercise the FastAPI
19+
app via `fastapi.testclient.TestClient` (`meshmind/tests/test_service_interfaces.py`,
20+
`meshmind/tests/test_counts_smoke.py`).
21+
- Hardened protobuf utilities (`scripts/generate_protos.py`, `scripts/check_protos.py`)
22+
to normalise relative imports so package builds remain import-safe.
23+
- Updated provisioning assets and documentation (README.md, SETUP.md,
24+
docs/api.md, docs/operations.md, docs/testing.md, PROJECT.md, PLAN.md,
25+
RECOMMENDATIONS.md, FINDINGS.md, ROADMAP.md, DUMMIES.md, CLEANUP.md,
26+
ENVIRONMENT_NEEDS.md, NEEDED_FOR_TESTING.md, SOT.md, TODO.md, RESUME_NOTES.md)
27+
to describe the new gRPC workflow, retired shims, and compose stacks.
28+
- Expanded the documentation guard mapping (`scripts/check_docs_sync.py`) so CLI
29+
changes require updates to the API/operations guides.
30+
331
## [2025-10-16T12:06:05-04:00 (America/New_York)]
432
### Added
533
- Introduced `meshmind/api/grpc_server.py` with `create_server`, `serve`, and `serve_forever` helpers so production deployments

CLEANUP.md

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,34 @@ place, and the exact remediation steps required to bring the implementation in l
1010
- **Files**: `meshmind/_compat/pydantic.py`, modules importing from `meshmind._compat.pydantic`.
1111
- **Status**: Completed – the shim has been removed, `pydantic>=2.11` is a required dependency, and all models/tests now consume the official APIs directly.
1212

13-
### Retire FastAPI Stub
13+
### Retire FastAPI Stub (Completed)
1414
- **Files**: `meshmind/api/rest.py`, `meshmind/api/service.py`, `docs/api.md`, `SETUP.md`.
15-
- **Current State**: A lightweight FastAPI replacement exposes REST endpoints without requiring the framework.
16-
- **Action**:
17-
1. Install `fastapi`, `uvicorn`, and related extras via the setup scripts.
18-
2. Replace the stub implementation with a true FastAPI app using pydantic request/response models.
19-
3. Update tests to spin up the FastAPI test client instead of the stub.
20-
4. Refresh documentation to reflect the production stack only.
15+
- **Status**: Completed – the REST layer now requires FastAPI, tests rely on
16+
`fastapi.testclient.TestClient`, and documentation reflects the production
17+
stack.
2118

2219
### Replace gRPC Dataclass Shim (Completed)
2320
- **Files**: `meshmind/api/grpc.py`, `meshmind/protos/memory_service.proto`, `meshmind/tests/test_service_interfaces.py`, `docs/api.md`.
2421
- **Status**: Completed – protobuf definitions now live under `meshmind/protos`, generated modules back the Python stub, setup scripts install `grpcio`/`grpcio-tools`, and tests exercise the canonical schema.
2522

2623
### Promote gRPC Server Implementation
27-
- **Files**: `meshmind/api/grpc.py`, future server entry point, integration tests.
28-
- **Current State**: Tests rely on the in-process stub; there is no deployable server or channel bootstrap yet.
24+
- **Files**: `meshmind/api/grpc.py`, `meshmind/api/grpc_server.py`, CLI entry points,
25+
integration tests.
26+
- **Current State**: An asyncio server helper and CLI (`meshmind serve-grpc`) now
27+
run the service; Docker Compose provisions a gRPC container. Integration tests
28+
against a live server remain outstanding.
2929
- **Action**:
30-
1. Implement a gRPC server (synchronous or `grpc.aio`) that binds the generated service to an actual channel.
31-
2. Add integration tests (possibly using `grpc.aio.insecure_channel`) that cover ingestion, search, and memory counts against the running server.
32-
3. Document provisioning steps (`SETUP.md`, `docs/api.md`) and add CLI helpers or docker-compose services if required.
30+
1. Add integration tests (possibly using `grpc.aio.insecure_channel`) that cover
31+
ingestion, search, and memory counts against the running server.
32+
2. Publish generated client artifacts for downstream consumers once
33+
infrastructure is available.
3334

3435
## Task Scheduling Workarounds
3536

36-
### Remove Celery Dummy App and Beat Fallback
37+
### Remove Celery Dummy App and Beat Fallback (Completed)
3738
- **Files**: `meshmind/tasks/celery_app.py`, `meshmind/tasks/scheduled.py`.
38-
- **Current State**: Custom placeholders allow imports without Celery and Celery Beat.
39-
- **Action**:
40-
1. Make `celery` a required dependency for maintenance tasks.
41-
2. Refactor scheduling utilities to import real Celery constructs and fail fast when misconfigured.
42-
3. Add integration tests that execute Celery workers against Redis or RabbitMQ in docker-compose.
43-
4. Delete fallback classes once coverage exists.
39+
- **Status**: Completed – Celery is a required dependency, the runtime imports the
40+
real app/beat scheduler, and docker-compose stacks provision Redis for workers.
4441

4542
## Testing Fakes
4643

DUMMIES.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ recommended next step now that full dependencies can be installed.
66

77
| Component | Location | Purpose | Current Usage | Recommended Action |
88
| --- | --- | --- | --- | --- |
9-
| FastAPI REST stub | `meshmind/api/rest.py` (`RestAPIStub`, `create_app`) | Exposes REST behaviour without the FastAPI dependency. | Tests use the stub when FastAPI is not installed; production should use FastAPI. | Keep temporarily for offline tests but plan to gate it behind an explicit test flag once FastAPI becomes mandatory. |
109
| gRPC stub implementation | `meshmind/api/grpc.py` (`GrpcServiceStub` + generated protobuf helpers) | Provides an in-process service implementation backed by the canonical proto schema so tests can exercise the service layer without spinning up gRPC infrastructure. | Unit tests and docs rely on the stub while production traffic should flow through the new asyncio helpers in `meshmind.api.grpc_server`. | Keep the stub for tests; package the new server behind a CLI entry point and retire any ad-hoc wrappers once infrastructure is provisioned. |
11-
| Celery dummy app | `meshmind/tasks/celery_app.py` (`_DummyCeleryApp`) | Allows module imports when Celery is missing. | Unit tests rely on the dummy to avoid Celery; production should use real Celery. | Retire dummy once Celery is a hard dependency; until then ensure tests explicitly exercise the real app when installed. |
12-
| Celery beat fallback | `meshmind/tasks/scheduled.py` (`crontab` shim) | Supplies a no-op crontab when Celery beat is missing. | Prevents import errors in test environments without Celery. | Remove once Celery is required; otherwise guard usage with feature flags. |
1310
| Fake graph/storage drivers | `meshmind/testing/fakes.py` (`FakeMemgraphDriver`, `FakeRedisBroker`, `FakeEmbeddingEncoder`) | Provide offline stand-ins for Memgraph, Redis, and embedding models. | Pytest fixtures and documentation rely on these for isolation. | Keep as long as offline tests are desired; supplement with integration suites that use real services. |
1411
| Fake LLM client | `meshmind/testing/fakes.py` (`FakeLLMClient`) | Records per-request overrides and emits deterministic responses so tests exercise reranking without installing the OpenAI SDK. | Service/interface tests (`meshmind/tests/test_service_interfaces.py`, `test_client.py`) and the CLI fixtures inject this stub when `openai` is unavailable. | Keep for unit tests; add integration tests with real providers once keys and network access are provisioned. |
1512
| Dummy encoder fixture | `meshmind/tests/conftest.py` (`dummy_encoder`) and dependent tests | Supplies a lightweight embedding encoder for search tests. | Used across retrieval and service tests to avoid network calls. | Keep for unit tests; add integration coverage with real encoders once APIs are configured. |
@@ -18,3 +15,5 @@ recommended next step now that full dependencies can be installed.
1815
## Retired Items
1916

2017
- **Pydantic compatibility shim (`meshmind/_compat/pydantic.py`)** – Removed now that the project installs `pydantic>=2.11` during setup. All models import directly from Pydantic and tests confirm no fallback is required.
18+
- **FastAPI REST stub (`meshmind/api/rest.py`)** – Removed in favour of the concrete FastAPI application now that `fastapi` is a required dependency and tests exercise it via `TestClient`.
19+
- **Celery dummy app and beat fallback (`meshmind/tasks/celery_app.py`, `meshmind/tasks/scheduled.py`)** – Retired because Celery is now installed by default; the real app and `crontab` integration are always imported.

FINDINGS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## General Observations
44
- Core modules are now wired through the `MeshMind` client, including CRUD, triplet storage, and retrieval helpers. Graph-backed wrappers fetch namespace/entity-label filtered candidates from the configured driver automatically; remaining integration work focuses on server-side query optimisation and heuristic evaluation loops.
5-
- Optional dependencies are largely guarded behind lazy imports or factory functions, improving portability. Environments still need to install tooling referenced by the Makefile and CI (ruff, pyright, typeguard, toml-sort, yamllint). `DUMMIES.md` now tracks remaining shims (FastAPI/gRPC/Celery) and documents retired items such as the former Pydantic fallback.
5+
- Optional dependencies are largely guarded behind lazy imports or factory functions, improving portability. Environments still need to install tooling referenced by the Makefile and CI (ruff, pyright, typeguard, toml-sort, yamllint). `DUMMIES.md` now tracks remaining shims (gRPC stub, offline fakes) and documents retired items such as the former Pydantic fallback.
66
- LLM usage is now centralized in `meshmind.llm_client` with per-operation defaults cascading from `LLM_*` environment variables and CLI overrides, reducing the risk of divergent configurations across pipelines and retrieval. REST/gRPC payloads now provide matching override dictionaries so services can experiment per request.
77
- Timestamp helpers default to timezone-aware UTC, eliminating naive datetime outputs that previously leaked into maintenance pipelines and compatibility shims.
88
- The gRPC interface is now defined by `meshmind/protos/memory_service.proto`; generated Python modules back the `GrpcServiceStub`
@@ -22,7 +22,7 @@
2222
embedding modules already encapsulate the SDK behind optional imports, easing the upcoming refactor to a dedicated
2323
wrapper.
2424
- Celery tasks initialize lazily, yet Redis/Memgraph services are still required at runtime. Docker Compose now provisions
25-
Memgraph, Neo4j, and Redis, while targeted stacks under `meshmind/tests/docker/` support integration testing. `SETUP.md`
25+
Memgraph, Neo4j, Redis, the gRPC server, and the Celery worker, while targeted stacks under `meshmind/tests/docker/` support integration testing. `SETUP.md`
2626
explains provisioning and teardown commands, and `scripts/benchmark_pagination.py` offers an offline way to measure driver throughput before integrating external services.
2727

2828
## Data Flow & Persistence

NEEDED_FOR_TESTING.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@
6262
## Local Configuration Steps
6363
- Ensure an embedding encoder is registered before extraction or hybrid search. The bootstrap utilities invoked by the CLI and
6464
`MeshMind` constructor handle this, but custom scripts must call `bootstrap_encoders()`.
65-
- For REST/gRPC testing, instantiate the `RestAPIStub`/`GrpcServiceStub` with the in-memory driver to avoid external services.
65+
- For REST/gRPC testing, instantiate the FastAPI app via `meshmind.api.rest.create_app`
66+
and exercise it with `fastapi.testclient.TestClient` (requires the `httpx`
67+
package); pair it with the `GrpcServiceStub` for lightweight gRPC coverage when
68+
external services are unavailable.
6669
- Use `meshmind/testing` fakes (`FakeMemgraphDriver`, `FakeRedisBroker`, `FakeEmbeddingEncoder`, `FakeLLMClient`) in tests or demos to eliminate external infrastructure requirements.
6770
- Invoke `meshmind admin predicates` and `meshmind admin maintenance --max-attempts <n> --base-delay <seconds> --run <task>` during local runs to inspect predicate registries, telemetry, and tune maintenance retries without external services.
6871
- Use the benchmarking utilities in `scripts/` (`evaluate_importance.py`, `consolidation_benchmark.py`, `benchmark_pagination.py`) to validate heuristics and driver performance offline before connecting to live infrastructure.

PLAN.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@
3535
incrementally.
3636
2. **Automation & CI** – Makefile provides lint/format/type/test/docs-guard targets and CI runs fmt-check, docs guard, and
3737
pytest. Protobuf drift now fails CI via `make protos-check`. Add caching and matrix builds when dependencies stabilize.
38-
3. **Environment Provisioning** – Docker Compose now provisions Memgraph, Neo4j, and Redis (with targeted stacks for tests).
39-
Track multi-backend examples, document the new `SETUP.md`, keep docs current, and distribute the new `run/install_setup.sh`
40-
and `run/maintenance_setup.sh` automation scripts for environment bootstrap.
38+
3. **Environment Provisioning** – Docker Compose now provisions Memgraph, Neo4j,
39+
Redis, the gRPC server, and the Celery worker (with targeted stacks for tests).
40+
Track multi-backend examples, document the new `SETUP.md`, keep docs current,
41+
and distribute the new `run/install_setup.sh` and `run/maintenance_setup.sh`
42+
automation scripts for environment bootstrap.
4143

4244
## Phase 5 – Strategic Enhancements (Planned)
4345
1. **Graph-Backed Retrieval** – Extend the new driver-side filtering/pagination to full vector/lexical execution using backend-native indexes to avoid round-tripping candidate embeddings.
4446
2. **Operational Observability** – Export telemetry to Prometheus/OpenTelemetry and surface dashboards/alerts.
4547
3. **Celery Hardening** – Stress test consolidation/compression heuristics at scale and codify retry/backoff policies.
46-
4. **Service Contracts** – Generated protobuf modules (`meshmind/protos/memory_service.proto`) back both the Python stub and the
47-
new asyncio gRPC server helpers. Next: package a deployable entry point, publish generated clients, and add integration tests
48-
once infrastructure is ready.
48+
4. **Service Contracts** – Generated protobuf modules (`meshmind/protos/memory_service.proto`)
49+
back both the Python stub and the asyncio gRPC server helpers. A dedicated CLI
50+
entry point (`meshmind serve-grpc`) now launches the runtime. Next: publish
51+
generated clients and add integration tests once infrastructure is ready.

PROJECT.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@
1919
initialize lazily so import-time failures are avoided.
2020
- **Support code**: `meshmind.core` provides configuration, data models, embeddings, similarity math, and optional dependency
2121
guards around tokenization.
22-
- **Service adapters**: `meshmind.api.rest` and `.grpc` expose REST/gRPC entry points. The gRPC surface now uses generated
23-
protobuf messages (`meshmind/protos/memory_service.proto`) and runtime helpers in `meshmind.api.grpc_server` so tests,
24-
scripts, and deployments share a canonical schema while retaining the in-process stub for fast feedback.
22+
- **Service adapters**: `meshmind.api.rest` exposes a FastAPI application, while
23+
`.grpc` ships generated protobuf stubs alongside asyncio server helpers and a CLI
24+
(`meshmind serve-grpc`) so deployments share a canonical schema while retaining
25+
the in-process stub for fast feedback.
2526
- **Observability**: `meshmind.core.observability` collects metrics, gauges, and structured log events across pipelines and
2627
scheduled tasks.
2728
- **Tooling**: The CLI ingest command (`meshmind ingest`), updated example script, Makefile automation, CI workflow, and Docker
@@ -54,8 +55,8 @@
5455
- Graph-backed retrieval still hydrates namespace/entity-label filtered candidates client-side; pushing ranking into the graph store is future work.
5556
- Predicate management remains internal to the bootstrap process; external administration APIs are still missing.
5657
- Metrics remain in-memory; external exporters (Prometheus/OpenTelemetry) are not wired up.
57-
- gRPC deployments now rely on the asyncio server helpers; packaging an executable entry point and adding end-to-end integration
58-
tests remain future work.
58+
- gRPC deployments now rely on the asyncio server helpers; end-to-end integration
59+
tests against a live CLI-managed server remain future work.
5960

6061
## External Services & Dependencies
6162
- **Graph backend**: Choose via `GRAPH_BACKEND`. In-memory and SQLite require no external services. Memgraph needs the `pymgclient` package (which exposes the `mgclient` module);

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ meshmind admin predicates --add RELATED_TO
174174
meshmind admin maintenance --max-attempts 5 --base-delay 2.5 --run consolidate
175175
meshmind admin graph --backend neo4j
176176
meshmind admin counts --namespace demo
177+
meshmind serve-grpc --host 0.0.0.0 --port 50051 --backend memgraph
177178
```
178179

179180
## Maintenance Tasks
@@ -190,8 +191,8 @@ Tasks instantiate the driver lazily, emit structured logs/metrics, and persist c
190191
to ensure code changes keep the wiki up to date.
191192
- **Examples**`examples/extract_preprocess_store_example.py` demonstrates ingestion, triplet creation, and multiple retrieval
192193
strategies.
193-
- **Dockerfile / docker-compose** – Container definition and orchestration files that provision Memgraph, Neo4j, Redis, and the
194-
Celery worker stacks documented in `SETUP.md` and `meshmind/tests/docker/`.
194+
- **Dockerfile / docker-compose** – Container definition and orchestration files that provision Memgraph, Neo4j, Redis, the
195+
Celery worker, and the gRPC server documented in `SETUP.md` and `meshmind/tests/docker/`.
195196
- **Provisioning scripts**`run/install_setup.sh` and `run/maintenance_setup.sh` validate that optional packages (`fastapi`,
196197
`neo4j`, `pymgclient`, `uvicorn`) are present and respect `MESH_SKIP_SYSTEM_PACKAGES=1` / `MESH_SKIP_PYTHON_SYNC=1` when you
197198
need a dry run without network access.
@@ -206,7 +207,7 @@ Tasks instantiate the driver lazily, emit structured logs/metrics, and persist c
206207
Use `make benchmarks` to run all three scripts with synthetic defaults and capture JSON summaries under `build/benchmarks/`.
207208

208209
## Service Interfaces
209-
- **REST**`meshmind.api.rest.create_app` returns a FastAPI app (or lightweight stub) that exposes `/memories`, `/triplets`,
210+
- **REST**`meshmind.api.rest.create_app` returns a FastAPI app that exposes `/memories`, `/triplets`,
210211
`/search`, and `/memories/counts` endpoints. Search payloads accept:
211212
- `use_llm_rerank` to toggle LLM-based reranking,
212213
- `llm_models`, `llm_base_urls`, and `llm_api_key` dictionaries for per-request overrides,
@@ -264,8 +265,9 @@ Tasks instantiate the driver lazily, emit structured logs/metrics, and persist c
264265
- MeshMind now depends on first-party Pydantic 2.x models; the legacy compatibility shim has been removed.
265266
- `meshmind/retrieval/bm25.py`, `meshmind/retrieval/fuzzy.py`, and `meshmind/core/similarity.py` include pure-Python fallbacks for scikit-learn, rapidfuzz, and numpy.
266267
- `meshmind/testing` exports fake Memgraph, Redis, and embedding drivers that power the pytest suite and examples without external infrastructure.
267-
- `DUMMIES.md` lists every remaining stub (REST/gRPC service adapters, Celery fallbacks, compatibility layers) with guidance
268-
on whether to remove or preserve them once external services are provisioned.
268+
- `DUMMIES.md` lists every remaining stub (for example the gRPC in-process adapter
269+
and offline test doubles) with guidance on whether to remove or preserve them
270+
once external services are provisioned.
269271

270272
## Testing
271273
- Run `pytest` to execute the suite; tests rely on fixtures and fake drivers so they do not require external services or optional libraries.

0 commit comments

Comments
 (0)