feat: add label parameter to add_column and modify_column tools
Allow setting a human-readable display label for columns, separate from the column_id used in formulas and API calls. The label defaults to the column_id if not provided.
This commit is contained in:
@@ -203,11 +203,14 @@ class GristClient:
|
|||||||
column_id: str,
|
column_id: str,
|
||||||
column_type: str,
|
column_type: str,
|
||||||
formula: str | None = None,
|
formula: str | None = None,
|
||||||
|
label: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Add a column to a table. Returns column ID."""
|
"""Add a column to a table. Returns column ID."""
|
||||||
fields = {"type": column_type}
|
fields = {"type": column_type}
|
||||||
if formula:
|
if formula:
|
||||||
fields["formula"] = formula
|
fields["formula"] = formula
|
||||||
|
if label:
|
||||||
|
fields["label"] = label
|
||||||
|
|
||||||
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
||||||
data = await self._request("POST", f"/tables/{table}/columns", json=payload)
|
data = await self._request("POST", f"/tables/{table}/columns", json=payload)
|
||||||
@@ -219,13 +222,16 @@ class GristClient:
|
|||||||
column_id: str,
|
column_id: str,
|
||||||
type: str | None = None,
|
type: str | None = None,
|
||||||
formula: str | None = None,
|
formula: str | None = None,
|
||||||
|
label: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Modify a column's type or formula."""
|
"""Modify a column's type, formula, or label."""
|
||||||
fields = {}
|
fields = {}
|
||||||
if type is not None:
|
if type is not None:
|
||||||
fields["type"] = type
|
fields["type"] = type
|
||||||
if formula is not None:
|
if formula is not None:
|
||||||
fields["formula"] = formula
|
fields["formula"] = formula
|
||||||
|
if label is not None:
|
||||||
|
fields["label"] = label
|
||||||
|
|
||||||
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
||||||
await self._request("PATCH", f"/tables/{table}/columns", json=payload)
|
await self._request("PATCH", f"/tables/{table}/columns", json=payload)
|
||||||
|
|||||||
@@ -186,13 +186,14 @@ def create_server(
|
|||||||
"column_id": {"type": "string"},
|
"column_id": {"type": "string"},
|
||||||
"column_type": {"type": "string"},
|
"column_type": {"type": "string"},
|
||||||
"formula": {"type": "string"},
|
"formula": {"type": "string"},
|
||||||
|
"label": {"type": "string", "description": "Display label for the column"},
|
||||||
},
|
},
|
||||||
"required": ["document", "table", "column_id", "column_type"],
|
"required": ["document", "table", "column_id", "column_type"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Tool(
|
Tool(
|
||||||
name="modify_column",
|
name="modify_column",
|
||||||
description="Modify a column's type or formula",
|
description="Modify a column's type, formula, or label",
|
||||||
inputSchema={
|
inputSchema={
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -201,6 +202,7 @@ def create_server(
|
|||||||
"column_id": {"type": "string"},
|
"column_id": {"type": "string"},
|
||||||
"type": {"type": "string"},
|
"type": {"type": "string"},
|
||||||
"formula": {"type": "string"},
|
"formula": {"type": "string"},
|
||||||
|
"label": {"type": "string", "description": "Display label for the column"},
|
||||||
},
|
},
|
||||||
"required": ["document", "table", "column_id"],
|
"required": ["document", "table", "column_id"],
|
||||||
},
|
},
|
||||||
@@ -311,6 +313,7 @@ def create_server(
|
|||||||
_current_agent, auth, arguments["document"], arguments["table"],
|
_current_agent, auth, arguments["document"], arguments["table"],
|
||||||
arguments["column_id"], arguments["column_type"],
|
arguments["column_id"], arguments["column_type"],
|
||||||
formula=arguments.get("formula"),
|
formula=arguments.get("formula"),
|
||||||
|
label=arguments.get("label"),
|
||||||
)
|
)
|
||||||
elif name == "modify_column":
|
elif name == "modify_column":
|
||||||
result = await _modify_column(
|
result = await _modify_column(
|
||||||
@@ -318,6 +321,7 @@ def create_server(
|
|||||||
arguments["column_id"],
|
arguments["column_id"],
|
||||||
type=arguments.get("type"),
|
type=arguments.get("type"),
|
||||||
formula=arguments.get("formula"),
|
formula=arguments.get("formula"),
|
||||||
|
label=arguments.get("label"),
|
||||||
)
|
)
|
||||||
elif name == "delete_column":
|
elif name == "delete_column":
|
||||||
result = await _delete_column(
|
result = await _delete_column(
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ async def add_column(
|
|||||||
column_id: str,
|
column_id: str,
|
||||||
column_type: str,
|
column_type: str,
|
||||||
formula: str | None = None,
|
formula: str | None = None,
|
||||||
|
label: str | None = None,
|
||||||
client: GristClient | None = None,
|
client: GristClient | None = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Add a column to a table."""
|
"""Add a column to a table."""
|
||||||
@@ -40,7 +41,9 @@ async def add_column(
|
|||||||
doc = auth.get_document(document)
|
doc = auth.get_document(document)
|
||||||
client = GristClient(doc)
|
client = GristClient(doc)
|
||||||
|
|
||||||
created_id = await client.add_column(table, column_id, column_type, formula=formula)
|
created_id = await client.add_column(
|
||||||
|
table, column_id, column_type, formula=formula, label=label
|
||||||
|
)
|
||||||
return {"column_id": created_id}
|
return {"column_id": created_id}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,16 +55,17 @@ async def modify_column(
|
|||||||
column_id: str,
|
column_id: str,
|
||||||
type: str | None = None,
|
type: str | None = None,
|
||||||
formula: str | None = None,
|
formula: str | None = None,
|
||||||
|
label: str | None = None,
|
||||||
client: GristClient | None = None,
|
client: GristClient | None = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Modify a column's type or formula."""
|
"""Modify a column's type, formula, or label."""
|
||||||
auth.authorize(agent, document, Permission.SCHEMA)
|
auth.authorize(agent, document, Permission.SCHEMA)
|
||||||
|
|
||||||
if client is None:
|
if client is None:
|
||||||
doc = auth.get_document(document)
|
doc = auth.get_document(document)
|
||||||
client = GristClient(doc)
|
client = GristClient(doc)
|
||||||
|
|
||||||
await client.modify_column(table, column_id, type=type, formula=formula)
|
await client.modify_column(table, column_id, type=type, formula=formula, label=label)
|
||||||
return {"modified": True}
|
return {"modified": True}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,27 @@ async def test_add_column(client, httpx_mock: HTTPXMock):
|
|||||||
col_id = await client.add_column("Table1", "NewCol", "Text", formula=None)
|
col_id = await client.add_column("Table1", "NewCol", "Text", formula=None)
|
||||||
|
|
||||||
assert col_id == "NewCol"
|
assert col_id == "NewCol"
|
||||||
|
request = httpx_mock.get_request()
|
||||||
|
import json
|
||||||
|
payload = json.loads(request.content)
|
||||||
|
assert payload == {"columns": [{"id": "NewCol", "fields": {"type": "Text"}}]}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_add_column_with_label(client, httpx_mock: HTTPXMock):
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="https://grist.example.com/api/docs/abc123/tables/Table1/columns",
|
||||||
|
method="POST",
|
||||||
|
json={"columns": [{"id": "first_name"}]},
|
||||||
|
)
|
||||||
|
|
||||||
|
col_id = await client.add_column("Table1", "first_name", "Text", label="First Name")
|
||||||
|
|
||||||
|
assert col_id == "first_name"
|
||||||
|
request = httpx_mock.get_request()
|
||||||
|
import json
|
||||||
|
payload = json.loads(request.content)
|
||||||
|
assert payload == {"columns": [{"id": "first_name", "fields": {"type": "Text", "label": "First Name"}}]}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@@ -169,6 +190,22 @@ async def test_modify_column(client, httpx_mock: HTTPXMock):
|
|||||||
await client.modify_column("Table1", "Amount", type="Int", formula="$Price * $Qty")
|
await client.modify_column("Table1", "Amount", type="Int", formula="$Price * $Qty")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_modify_column_with_label(client, httpx_mock: HTTPXMock):
|
||||||
|
httpx_mock.add_response(
|
||||||
|
url="https://grist.example.com/api/docs/abc123/tables/Table1/columns",
|
||||||
|
method="PATCH",
|
||||||
|
json={},
|
||||||
|
)
|
||||||
|
|
||||||
|
await client.modify_column("Table1", "Col1", label="Column One")
|
||||||
|
|
||||||
|
request = httpx_mock.get_request()
|
||||||
|
import json
|
||||||
|
payload = json.loads(request.content)
|
||||||
|
assert payload == {"columns": [{"id": "Col1", "fields": {"label": "Column One"}}]}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_delete_column(client, httpx_mock: HTTPXMock):
|
async def test_delete_column(client, httpx_mock: HTTPXMock):
|
||||||
httpx_mock.add_response(
|
httpx_mock.add_response(
|
||||||
|
|||||||
@@ -81,6 +81,25 @@ async def test_add_column(auth, mock_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert result == {"column_id": "NewCol"}
|
assert result == {"column_id": "NewCol"}
|
||||||
|
mock_client.add_column.assert_called_once_with(
|
||||||
|
"Table1", "NewCol", "Text", formula=None, label=None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_add_column_with_label(auth, mock_client):
|
||||||
|
agent = auth.authenticate("schema-token")
|
||||||
|
|
||||||
|
result = await add_column(
|
||||||
|
agent, auth, "budget", "Table1", "first_name", "Text",
|
||||||
|
label="First Name",
|
||||||
|
client=mock_client,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == {"column_id": "NewCol"}
|
||||||
|
mock_client.add_column.assert_called_once_with(
|
||||||
|
"Table1", "first_name", "Text", formula=None, label="First Name"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
@@ -95,6 +114,25 @@ async def test_modify_column(auth, mock_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert result == {"modified": True}
|
assert result == {"modified": True}
|
||||||
|
mock_client.modify_column.assert_called_once_with(
|
||||||
|
"Table1", "Col1", type="Int", formula="$A + $B", label=None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_modify_column_with_label(auth, mock_client):
|
||||||
|
agent = auth.authenticate("schema-token")
|
||||||
|
|
||||||
|
result = await modify_column(
|
||||||
|
agent, auth, "budget", "Table1", "Col1",
|
||||||
|
label="Column One",
|
||||||
|
client=mock_client,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == {"modified": True}
|
||||||
|
mock_client.modify_column.assert_called_once_with(
|
||||||
|
"Table1", "Col1", type=None, formula=None, label="Column One"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|||||||
Reference in New Issue
Block a user