Skip to content

Commit b9e5305

Browse files
carlkesselmanclaude
andcommitted
Update to use domain_schemas (plural) API from deriva-ml
The DerivaML class changed from domain_schema (singular string) to domain_schemas (set of strings) and default_schema. This update: - ConnectionInfo.domain_schema -> domain_schemas (set[str] | None) - ConnectionManager.connect() parameter updated - All references to ml.domain_schema updated to use ml.domain_schemas or ml.default_schema as appropriate - Resources now iterate over all domain schemas instead of just one Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 99f8a44 commit b9e5305

File tree

4 files changed

+49
-36
lines changed

4 files changed

+49
-36
lines changed

src/deriva_ml_mcp/connection.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class ConnectionInfo:
5050

5151
hostname: str
5252
catalog_id: str | int
53-
domain_schema: str | None
53+
domain_schemas: set[str] | None
5454
ml_instance: DerivaML
5555
workflow_rid: str | None = None
5656
execution: Any = None # Execution object from deriva_ml
@@ -147,15 +147,15 @@ def connect(
147147
self,
148148
hostname: str,
149149
catalog_id: str | int,
150-
domain_schema: str | None = None,
150+
domain_schemas: set[str] | None = None,
151151
set_active: bool = True,
152152
) -> DerivaML:
153153
"""Connect to a DerivaML catalog.
154154
155155
Args:
156156
hostname: Hostname of the Deriva server.
157157
catalog_id: Catalog identifier.
158-
domain_schema: Optional domain schema name.
158+
domain_schemas: Optional set of domain schema names. Auto-detected if omitted.
159159
set_active: If True, set this as the active connection.
160160
161161
Returns:
@@ -179,7 +179,7 @@ def connect(
179179
ml = DerivaML(
180180
hostname=hostname,
181181
catalog_id=catalog_id,
182-
domain_schema=domain_schema,
182+
domain_schemas=domain_schemas,
183183
check_auth=True,
184184
)
185185

@@ -189,7 +189,7 @@ def connect(
189189
self._connections[key] = ConnectionInfo(
190190
hostname=hostname,
191191
catalog_id=catalog_id,
192-
domain_schema=domain_schema,
192+
domain_schemas=domain_schemas,
193193
ml_instance=ml,
194194
workflow_rid=workflow_rid,
195195
execution=execution,
@@ -339,7 +339,7 @@ def list_connections(self) -> list[dict[str, Any]]:
339339
{
340340
"hostname": info.hostname,
341341
"catalog_id": info.catalog_id,
342-
"domain_schema": info.domain_schema,
342+
"domain_schemas": list(info.domain_schemas) if info.domain_schemas else None,
343343
"is_active": key == self._active_connection,
344344
"workflow_rid": info.workflow_rid,
345345
"execution_rid": info.execution.execution_rid if info.execution else None,

src/deriva_ml_mcp/resources.py

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -443,24 +443,27 @@ def get_catalog_schema() -> str:
443443
schema_info = {
444444
"hostname": ml.host_name,
445445
"catalog_id": str(ml.catalog_id),
446-
"domain_schema": ml.domain_schema,
446+
"domain_schemas": list(ml.domain_schemas),
447+
"default_schema": ml.default_schema,
447448
"ml_schema": ml.ml_schema,
448449
"tables": [],
449450
}
450451

451-
# Get domain schema tables
452-
domain = ml.model.schemas.get(ml.domain_schema)
453-
if domain:
454-
for table in domain.tables.values():
455-
table_info = {
456-
"name": table.name,
457-
"columns": [
458-
{"name": col.name, "type": str(col.type)}
459-
for col in table.columns
460-
],
461-
"is_vocabulary": hasattr(table, "is_vocabulary") and table.is_vocabulary,
462-
}
463-
schema_info["tables"].append(table_info)
452+
# Get tables from all domain schemas
453+
for domain_schema in ml.domain_schemas:
454+
domain = ml.model.schemas.get(domain_schema)
455+
if domain:
456+
for table in domain.tables.values():
457+
table_info = {
458+
"name": table.name,
459+
"schema": domain_schema,
460+
"columns": [
461+
{"name": col.name, "type": str(col.type)}
462+
for col in table.columns
463+
],
464+
"is_vocabulary": hasattr(table, "is_vocabulary") and table.is_vocabulary,
465+
}
466+
schema_info["tables"].append(table_info)
464467

465468
return json.dumps(schema_info, indent=2)
466469
except Exception as e:
@@ -481,7 +484,8 @@ def get_catalog_vocabularies() -> str:
481484
try:
482485
vocabularies = {}
483486
# Iterate through schemas to find vocabulary tables
484-
for schema_name in [ml.ml_schema, ml.domain_schema]:
487+
schemas_to_check = [ml.ml_schema] + list(ml.domain_schemas)
488+
for schema_name in schemas_to_check:
485489
schema = ml.model.schemas.get(schema_name)
486490
if schema:
487491
for table in schema.tables.values():
@@ -617,21 +621,25 @@ def get_catalog_features() -> str:
617621
mime_type="application/json",
618622
)
619623
def get_catalog_tables() -> str:
620-
"""Return all tables in the domain schema with metadata."""
624+
"""Return all tables in the domain schemas with metadata."""
621625
ml = conn_manager.get_active_connection()
622626
if ml is None:
623627
return json.dumps({"error": "No active catalog connection"})
624628

625629
try:
626630
tables = []
627-
for table in ml.model.schemas[ml.domain_schema].tables.values():
628-
tables.append({
629-
"name": table.name,
630-
"comment": table.comment or "",
631-
"is_vocabulary": ml.model.is_vocabulary(table),
632-
"is_asset": ml.model.is_asset(table),
633-
"column_count": len(list(table.columns)),
634-
})
631+
for domain_schema in ml.domain_schemas:
632+
if domain_schema not in ml.model.schemas:
633+
continue
634+
for table in ml.model.schemas[domain_schema].tables.values():
635+
tables.append({
636+
"name": table.name,
637+
"schema": domain_schema,
638+
"comment": table.comment or "",
639+
"is_vocabulary": ml.model.is_vocabulary(table),
640+
"is_asset": ml.model.is_asset(table),
641+
"column_count": len(list(table.columns)),
642+
})
635643
return json.dumps(tables, indent=2)
636644
except Exception as e:
637645
return json.dumps({"error": str(e)})
@@ -1514,7 +1522,8 @@ def get_catalog_info() -> str:
15141522
result = {
15151523
"hostname": ml.host_name,
15161524
"catalog_id": str(ml.catalog_id),
1517-
"domain_schema": ml.domain_schema,
1525+
"domain_schemas": list(ml.domain_schemas),
1526+
"default_schema": ml.default_schema,
15181527
"ml_schema": ml.ml_schema,
15191528
"project_name": ml.project_name,
15201529
}

src/deriva_ml_mcp/tools/catalog.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,17 @@ async def connect_catalog(
4444
connect_catalog("dev.eye-ai.org", "52") -> connects to eye-ai catalog
4545
"""
4646
try:
47-
ml = conn_manager.connect(hostname, catalog_id, domain_schema)
47+
# Convert single domain_schema to set for the new API
48+
domain_schemas = {domain_schema} if domain_schema else None
49+
ml = conn_manager.connect(hostname, catalog_id, domain_schemas)
4850
conn_info = conn_manager.get_active_connection_info()
4951

5052
result = {
5153
"status": "connected",
5254
"hostname": hostname,
5355
"catalog_id": catalog_id,
54-
"domain_schema": ml.domain_schema,
56+
"domain_schemas": list(ml.domain_schemas),
57+
"default_schema": ml.default_schema,
5558
"project_name": ml.project_name,
5659
}
5760

@@ -133,13 +136,14 @@ async def create_catalog(
133136
model.create_schema(Schema.define(project_name))
134137

135138
# Connect to the newly created catalog
136-
ml = conn_manager.connect(hostname, str(catalog.catalog_id), project_name)
139+
ml = conn_manager.connect(hostname, str(catalog.catalog_id), {project_name})
137140

138141
result = {
139142
"status": "created",
140143
"hostname": hostname,
141144
"catalog_id": str(catalog.catalog_id),
142-
"domain_schema": ml.domain_schema,
145+
"domain_schemas": list(ml.domain_schemas),
146+
"default_schema": ml.default_schema,
143147
"project_name": project_name,
144148
}
145149
if catalog_alias:

src/deriva_ml_mcp/tools/schema.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ async def create_table(
114114
for fk in foreign_keys:
115115
fkey_defs.append(ForeignKeyDefinition(
116116
colnames=[fk["column"]],
117-
pk_sname=ml.domain_schema,
117+
pk_sname=ml.default_schema,
118118
pk_tname=fk["referenced_table"],
119119
pk_colnames=[fk.get("referenced_column", "RID")],
120120
on_delete=fk.get("on_delete", "NO ACTION"),

0 commit comments

Comments
 (0)