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_type: str,
|
||||
formula: str | None = None,
|
||||
label: str | None = None,
|
||||
) -> str:
|
||||
"""Add a column to a table. Returns column ID."""
|
||||
fields = {"type": column_type}
|
||||
if formula:
|
||||
fields["formula"] = formula
|
||||
if label:
|
||||
fields["label"] = label
|
||||
|
||||
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
||||
data = await self._request("POST", f"/tables/{table}/columns", json=payload)
|
||||
@@ -219,13 +222,16 @@ class GristClient:
|
||||
column_id: str,
|
||||
type: str | None = None,
|
||||
formula: str | None = None,
|
||||
label: str | None = None,
|
||||
) -> None:
|
||||
"""Modify a column's type or formula."""
|
||||
"""Modify a column's type, formula, or label."""
|
||||
fields = {}
|
||||
if type is not None:
|
||||
fields["type"] = type
|
||||
if formula is not None:
|
||||
fields["formula"] = formula
|
||||
if label is not None:
|
||||
fields["label"] = label
|
||||
|
||||
payload = {"columns": [{"id": column_id, "fields": fields}]}
|
||||
await self._request("PATCH", f"/tables/{table}/columns", json=payload)
|
||||
|
||||
@@ -186,13 +186,14 @@ def create_server(
|
||||
"column_id": {"type": "string"},
|
||||
"column_type": {"type": "string"},
|
||||
"formula": {"type": "string"},
|
||||
"label": {"type": "string", "description": "Display label for the column"},
|
||||
},
|
||||
"required": ["document", "table", "column_id", "column_type"],
|
||||
},
|
||||
),
|
||||
Tool(
|
||||
name="modify_column",
|
||||
description="Modify a column's type or formula",
|
||||
description="Modify a column's type, formula, or label",
|
||||
inputSchema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -201,6 +202,7 @@ def create_server(
|
||||
"column_id": {"type": "string"},
|
||||
"type": {"type": "string"},
|
||||
"formula": {"type": "string"},
|
||||
"label": {"type": "string", "description": "Display label for the column"},
|
||||
},
|
||||
"required": ["document", "table", "column_id"],
|
||||
},
|
||||
@@ -311,6 +313,7 @@ def create_server(
|
||||
_current_agent, auth, arguments["document"], arguments["table"],
|
||||
arguments["column_id"], arguments["column_type"],
|
||||
formula=arguments.get("formula"),
|
||||
label=arguments.get("label"),
|
||||
)
|
||||
elif name == "modify_column":
|
||||
result = await _modify_column(
|
||||
@@ -318,6 +321,7 @@ def create_server(
|
||||
arguments["column_id"],
|
||||
type=arguments.get("type"),
|
||||
formula=arguments.get("formula"),
|
||||
label=arguments.get("label"),
|
||||
)
|
||||
elif name == "delete_column":
|
||||
result = await _delete_column(
|
||||
|
||||
@@ -31,6 +31,7 @@ async def add_column(
|
||||
column_id: str,
|
||||
column_type: str,
|
||||
formula: str | None = None,
|
||||
label: str | None = None,
|
||||
client: GristClient | None = None,
|
||||
) -> dict:
|
||||
"""Add a column to a table."""
|
||||
@@ -40,7 +41,9 @@ async def add_column(
|
||||
doc = auth.get_document(document)
|
||||
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}
|
||||
|
||||
|
||||
@@ -52,16 +55,17 @@ async def modify_column(
|
||||
column_id: str,
|
||||
type: str | None = None,
|
||||
formula: str | None = None,
|
||||
label: str | None = None,
|
||||
client: GristClient | None = None,
|
||||
) -> dict:
|
||||
"""Modify a column's type or formula."""
|
||||
"""Modify a column's type, formula, or label."""
|
||||
auth.authorize(agent, document, Permission.SCHEMA)
|
||||
|
||||
if client is None:
|
||||
doc = auth.get_document(document)
|
||||
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}
|
||||
|
||||
|
||||
|
||||
@@ -155,6 +155,27 @@ async def test_add_column(client, httpx_mock: HTTPXMock):
|
||||
col_id = await client.add_column("Table1", "NewCol", "Text", formula=None)
|
||||
|
||||
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
|
||||
@@ -169,6 +190,22 @@ async def test_modify_column(client, httpx_mock: HTTPXMock):
|
||||
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
|
||||
async def test_delete_column(client, httpx_mock: HTTPXMock):
|
||||
httpx_mock.add_response(
|
||||
|
||||
@@ -81,6 +81,25 @@ async def test_add_column(auth, mock_client):
|
||||
)
|
||||
|
||||
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
|
||||
@@ -95,6 +114,25 @@ async def test_modify_column(auth, mock_client):
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user