server: define async Store protocol (#306)#325
Merged
peteski22 merged 1 commit intomozilla-ai:mainfrom Apr 24, 2026
Merged
Conversation
Contributor
Author
|
Small note about the current _protocol. ending_queue/list_units share a uniform shape, get_user is stable. The API-key methods are trickier because create_api_key, get_api_key_for_user, get_api_key_by_hash, and list_api_keys_for_user, each project a different subset of columns (plus get_api_key_by_hash joins in username), so that needs a design call: one TypedDict with NotRequired fields, or separate types per method? |
Phase 1 step (3) of the RFC mozilla-ai#275 PostgreSQL-backend effort (epic mozilla-ai#257). Pure interface definition: new `cq_server.store._protocol.Store` with `async def` signatures covering every public method on today's `RemoteStore`. No implementations, no runtime callers touched. Because a subpackage and a module can't share a name, `store.py` moves to `store/__init__.py` (rename preserves history; only the two same-package relative imports change, `.scoring` -> `..scoring` and `.tables` -> `..tables`). The RemoteStore class is otherwise untouched. `@runtime_checkable` plus an `issubclass(RemoteStore, Store)` assertion covers the structural acceptance criterion — Python's runtime Protocol check inspects attribute names only, so sync RemoteStore satisfies the async protocol today and future async `SqliteStore` (mozilla-ai#308) will keep satisfying it. Deliberately out of scope: `db_path` (SQLite-specific property) and `__enter__`/`__exit__` (sync dunders; async `__aenter__`/`__aexit__` land with the real async `SqliteStore` in mozilla-ai#308). Closes mozilla-ai#306.
5754294 to
7959031
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Defines the async
Storeprotocol that bothSqliteStore(#308) and the eventualPostgresStorewill conform to. Pure interface — no implementations, no runtime wiring. Part of #257 / RFC #275, Phase 1 step (3).Changes
server/backend/src/cq_server/store/_protocol.py—Store(typing.Protocol)withasync defsignatures covering every public method onRemoteStoretoday.store.py→store/__init__.pyto makestorea package (prep for ImplementSqliteStoreagainstStoreprotocol via Core helpers #308, which re-exportsSqliteStorefrom the same package root). Pure rename: only change is.scoring/.tables→..scoring/..tablesrelative-import fix.Storefromcq_server.storeso callers don't reach into the private_protocolmodule.tests/test_store_protocol.py— structural TDD check thatRemoteStoresatisfiesStorevia@runtime_checkable+issubclass. The test docstring calls out the known limitation (runtime_checkable only checks attribute names, not sync-vs-async); onceSqliteStorelands in ImplementSqliteStoreagainstStoreprotocol via Core helpers #308 the same test continues to pass against a genuinely async impl.Scope deviation worth flagging
The issue said "No changes to existing `store.py`." The branch renames it to `store/init.py`. This is deliberate — #308 explicitly requires the `store/` package layout, and doing the move now avoids a churny second rename. Rename is behavior-preserving (99% similarity; only import paths adjusted).
Out of scope (intentionally deferred)
SqliteStoreagainstStoreprotocol via Core helpers #308.SqliteStoreagainstStoreprotocol via Core helpers #308 where the threadpool-shim question is live.🤖 Generated with Claude Code