Report a stemless --db path as a usage error and separate the two lancedb.uri migrations
An empty lancedb.uri, which init-config used to emit, is told to remove the key; only a non-empty value is told the databases spelling. haiku-rag --db and haiku-ingester --db turn a path with no stem into typer.BadParameter.
This commit is contained in:
parent
a04a16c717
commit
3814b2bc78
7 changed files with 52 additions and 6 deletions
|
|
@ -24,7 +24,8 @@
|
|||
- Every database has a name: the key in `lancedb.databases`, or the path's stem
|
||||
for `--db PATH`, `db_path=` and the default database, which is the entry
|
||||
`haiku.rag` under `storage.data_dir` and selectable by that name.
|
||||
`SearchResult.source`, `Document.source` and `Citation.source` always carry it.
|
||||
`SearchResult.source`, `Document.source` and `Citation.source` carry it on
|
||||
every value a database produces.
|
||||
- `db_path=` beside a configured `lancedb.databases` raises
|
||||
`AmbiguousDatabaseError` (`HaikuRAG`, `create_capability`, `create_mcp_server`,
|
||||
`Sandbox`). `haiku-rag --db PATH` and `haiku-ingester --db PATH` open that path
|
||||
|
|
|
|||
|
|
@ -102,7 +102,10 @@ def resolve_scope(
|
|||
"pass --db or --db-name, not both: they name the same thing"
|
||||
)
|
||||
if db is not None:
|
||||
return DatabaseScope.at(db)
|
||||
try:
|
||||
return DatabaseScope.at(db)
|
||||
except ValueError as error:
|
||||
raise typer.BadParameter(str(error), param_hint="--db") from error
|
||||
scope = DatabaseScope.resolve(get_config(), database_name=_db_name)
|
||||
if scope.covers_multiple and not covers_set:
|
||||
raise AmbiguousDatabaseError(
|
||||
|
|
|
|||
|
|
@ -120,9 +120,14 @@ class LanceDBConfig(ConfigModel):
|
|||
@classmethod
|
||||
def _uri_names_its_replacement(cls, data: Any) -> Any:
|
||||
if isinstance(data, dict) and "uri" in data:
|
||||
if str(data["uri"]).strip():
|
||||
raise ValueError(
|
||||
"lancedb.uri was removed; write lancedb.databases: {NAME: "
|
||||
f"{data['uri']!r}}} instead"
|
||||
)
|
||||
raise ValueError(
|
||||
"lancedb.uri was removed; write lancedb.databases: {NAME: "
|
||||
f"{data['uri']!r}}} instead"
|
||||
"lancedb.uri was removed; remove the empty key. With no "
|
||||
"lancedb.databases the database is haiku.rag under storage.data_dir"
|
||||
)
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,12 @@ def _scope_for(db: Path | None) -> "DatabaseScope | None":
|
|||
is configured. None leaves placement to the configuration."""
|
||||
from haiku.rag.client.scope import DatabaseScope
|
||||
|
||||
return DatabaseScope.at(db) if db is not None else None
|
||||
if db is None:
|
||||
return None
|
||||
try:
|
||||
return DatabaseScope.at(db)
|
||||
except ValueError as error:
|
||||
raise typer.BadParameter(str(error), param_hint="--db") from error
|
||||
|
||||
|
||||
@_cli.command("serve")
|
||||
|
|
|
|||
|
|
@ -547,6 +547,16 @@ class TestPlacingTheIngesterDatabase:
|
|||
tmp_path / "local.lancedb"
|
||||
)
|
||||
|
||||
def test_a_path_without_a_stem_is_a_usage_error(self):
|
||||
from pathlib import Path
|
||||
|
||||
import typer
|
||||
|
||||
from haiku.rag.ingester.cli import _scope_for
|
||||
|
||||
with pytest.raises(typer.BadParameter, match="no name"):
|
||||
_scope_for(Path("/"))
|
||||
|
||||
def test_a_python_caller_cannot_pass_a_path(self):
|
||||
from haiku.rag.ingester.app import IngesterApp
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,16 @@ class TestOneDatabaseCommands:
|
|||
assert scope.names == ("other",)
|
||||
assert not scope.covers_multiple
|
||||
|
||||
def test_a_path_without_a_stem_is_a_usage_error(self, monkeypatch):
|
||||
"""A path that names no database is the operator's mistake, reported as
|
||||
one."""
|
||||
import typer
|
||||
|
||||
self._install(monkeypatch)
|
||||
|
||||
with pytest.raises(typer.BadParameter, match="no name"):
|
||||
resolve_scope(Path("/"))
|
||||
|
||||
def test_no_configured_databases_is_allowed(self, monkeypatch, tmp_path):
|
||||
import haiku.rag.config as config_module
|
||||
|
||||
|
|
|
|||
|
|
@ -812,7 +812,19 @@ def test_lancedb_uri_is_refused_with_the_replacement_named():
|
|||
|
||||
message = str(raised.value)
|
||||
assert "lancedb.uri" in message
|
||||
assert "lancedb.databases" in message
|
||||
assert "lancedb.databases: {NAME: 's3://bucket/notes.lancedb'}" in message
|
||||
|
||||
with pytest.raises(ValidationError, match="lancedb.databases"):
|
||||
LanceDBConfig.model_validate({"uri": "/data/notes.lancedb"})
|
||||
|
||||
|
||||
def test_an_empty_lancedb_uri_is_refused_with_removal_as_the_remedy():
|
||||
"""Generated configs carried `uri: ""` for the local default. The remedy is
|
||||
to delete the key, never a mapping with an empty location."""
|
||||
with pytest.raises(ValidationError) as raised:
|
||||
AppConfig.model_validate({"lancedb": {"uri": ""}})
|
||||
|
||||
message = str(raised.value)
|
||||
assert "lancedb.uri" in message
|
||||
assert "remove" in message
|
||||
assert "{NAME" not in message
|
||||
|
|
|
|||
Loading…
Reference in a new issue