Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ amplifier-context-intelligence/
│ ├── pipeline.py # Per-event dispatch spine (invoked by the drainer)
│ ├── neo4j_store.py # Neo4jGraphStore (managed-tx writes)
│ ├── graph_store.py # Graph store protocol / abstraction
│ ├── blob_store.py # AsyncDiskBlobStore
│ ├── blob_store/ # BlobStore Protocol + FileSystemBlobStore + config-driven factory
│ ├── idempotency.py # Idempotent MERGE / dedupe helpers
│ ├── auth.py # Bearer-token API authentication
│ ├── status.py # Status/version plumbing (EventRingBuffer, build_status_response, SERVER_VERSION)
Expand Down
4 changes: 2 additions & 2 deletions context_intelligence_server/blob_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ async def process_event_data(

key = f"{node_id}__{field_name}"
try:
uri = await blob_store.write(session_id, key, value)
data[field_name] = {"$blob_ref": uri}
ref = await blob_store.write(session_id, key, value)
data[field_name] = {"$blob_ref": ref.uri}
except Exception as exc: # noqa: BLE001
logger.warning(
"blob_offload_failed session=%s field=%s node=%s: %s",
Expand Down
237 changes: 0 additions & 237 deletions context_intelligence_server/blob_store.py

This file was deleted.

29 changes: 29 additions & 0 deletions context_intelligence_server/blob_store/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""blob_store \u2014 session-scoped, URI-addressable blob storage.

The public surface is the backend-neutral :class:`BlobStore` Protocol plus
:class:`BlobReference` / :class:`BlobNotFoundError` and the
:func:`create_blob_store` factory. Consumers should depend on these, never on
a concrete backend class.

Package layout:
protocol.py BlobStore Protocol, BlobReference, BlobNotFoundError \u2014 the
backend-neutral seam (no filesystem imports).
filesystem.py FileSystemBlobStore \u2014 the disk-backed implementation.
factory.py create_blob_store(settings) \u2014 the ONLY place a backend is
selected and the ONLY place (besides config.py) that reads
settings.blob_path.
"""

from __future__ import annotations

from .factory import create_blob_store
from .filesystem import FileSystemBlobStore
from .protocol import BlobNotFoundError, BlobReference, BlobStore

__all__ = [
"BlobNotFoundError",
"BlobReference",
"BlobStore",
"FileSystemBlobStore",
"create_blob_store",
]
46 changes: 46 additions & 0 deletions context_intelligence_server/blob_store/factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Config-driven BlobStore factory \u2014 the ONLY place a blob-store backend is selected.

This is the single seam through which the concrete backend is chosen. Adding
a new backend (e.g. Azure) means: one new module implementing
:class:`~.protocol.BlobStore`, one new branch here, and a config value \u2014
zero changes to :mod:`context_intelligence_server.registry` or any consumer.

This module (and :mod:`~context_intelligence_server.config`) are the only
places ``settings.blob_path`` is read \u2014 the on-disk root is a filesystem-
backend concern, resolved here and handed to the concrete backend at
construction time. Callers only ever see the :class:`~.protocol.BlobStore`
Protocol.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from .filesystem import FileSystemBlobStore
from .protocol import BlobStore

if TYPE_CHECKING:
from context_intelligence_server.config import Settings


def create_blob_store(settings: Settings) -> BlobStore:
"""Build the configured :class:`~.protocol.BlobStore` backend.

Reads ``settings.blob_backend`` (default ``"filesystem"``) to select the
implementation:

- ``"filesystem"``: :class:`~.filesystem.FileSystemBlobStore` rooted at
``settings.blob_path``.
- ``"azure"``: not yet implemented.
- anything else: rejected as an unknown backend.

Raises:
NotImplementedError: If ``blob_backend == "azure"`` (not yet built).
ValueError: If ``blob_backend`` names an unknown backend.
"""
backend = settings.blob_backend
if backend == "filesystem":
return FileSystemBlobStore(root=settings.blob_path)
if backend == "azure":
raise NotImplementedError("azure blob backend not yet implemented")
raise ValueError(f"Unknown blob_backend: {backend!r}")
Loading
Loading