Skip to content

Commit 325a20b

Browse files
committed
feat: add auth_tools support to text plugin
- Add auth_tools field to TextCallTemplate for OpenAPI-generated tools - Pass auth_tools to OpenApiConverter when processing local OpenAPI specs - Update documentation to reflect new authentication capabilities - Add test coverage for auth_tools functionality - Maintains backward compatibility (auth_tools is optional) This allows text plugin to apply authentication to tools generated from local OpenAPI specifications, enabling secure API calls while keeping file access authentication-free.
1 parent a0ac60d commit 325a20b

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,13 @@ Note the name change from `http_stream` to `streamable_http`.
479479
"name": "my_text_manual",
480480
"call_template_type": "text", // Required
481481
"file_path": "./manuals/my_manual.json", // Required
482-
"auth": null // Optional (always null for Text)
482+
"auth": null, // Optional (always null for Text)
483+
"auth_tools": { // Optional, authentication for generated tools from OpenAPI specs
484+
"auth_type": "api_key",
485+
"api_key": "Bearer ${API_TOKEN}",
486+
"var_name": "Authorization",
487+
"location": "header"
488+
}
483489
}
484490
```
485491

plugins/communication_protocols/text/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ A simple, file-based resource plugin for UTCP. This plugin allows you to define
88

99
- **Local File Content**: Define tools that read and return the content of local files.
1010
- **UTCP Manual Discovery**: Load tool definitions from local UTCP manual files in JSON or YAML format.
11+
- **OpenAPI Support**: Automatically converts local OpenAPI specs to UTCP tools with optional authentication.
1112
- **Static & Simple**: Ideal for returning mock data, configuration, or any static text content from a file.
1213
- **Version Control**: Tool definitions and their corresponding content files can be versioned with your code.
13-
- **No Authentication**: Designed for simple, local file access without authentication.
14+
- **No File Authentication**: Designed for simple, local file access without authentication for file reading.
15+
- **Tool Authentication**: Supports authentication for generated tools from OpenAPI specs via `auth_tools`.
1416

1517
## Installation
1618

plugins/communication_protocols/text/src/utcp_text/text_call_template.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from typing import Literal
1+
from typing import Literal, Optional
22
from pydantic import Field
33

44
from utcp.data.call_template import CallTemplate
5+
from utcp.data.auth import Auth
56
from utcp.interfaces.serializer import Serializer
67
from utcp.exceptions import UtcpSerializerValidationError
78
import traceback
@@ -16,12 +17,14 @@ class TextCallTemplate(CallTemplate):
1617
Attributes:
1718
call_template_type: Always "text" for text file call templates.
1819
file_path: Path to the file containing the UTCP manual or tool definitions.
19-
auth: Always None - text call templates don't support authentication.
20+
auth: Always None - text call templates don't support authentication for file access.
21+
auth_tools: Optional authentication to apply to generated tools from OpenAPI specs.
2022
"""
2123

2224
call_template_type: Literal["text"] = "text"
2325
file_path: str = Field(..., description="The path to the file containing the UTCP manual or tool definitions.")
2426
auth: None = None
27+
auth_tools: Optional[Auth] = Field(None, description="Authentication to apply to generated tools from OpenAPI specs.")
2528

2629

2730
class TextCallTemplateSerializer(Serializer[TextCallTemplate]):

plugins/communication_protocols/text/src/utcp_text/text_communication_protocol.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ async def register_manual(self, caller: 'UtcpClient', manual_call_template: Call
7070
utcp_manual: UtcpManual
7171
if isinstance(data, dict) and ("openapi" in data or "swagger" in data or "paths" in data):
7272
self._log_info("Detected OpenAPI specification. Converting to UTCP manual.")
73-
converter = OpenApiConverter(data, spec_url=file_path.as_uri(), call_template_name=manual_call_template.name)
73+
converter = OpenApiConverter(
74+
data,
75+
spec_url=file_path.as_uri(),
76+
call_template_name=manual_call_template.name,
77+
auth_tools=manual_call_template.auth_tools
78+
)
7479
utcp_manual = converter.convert()
7580
else:
7681
# Try to validate as UTCP manual directly

plugins/communication_protocols/text/tests/test_text_communication_protocol.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from utcp_text.text_call_template import TextCallTemplate
1313
from utcp.data.call_template import CallTemplate
1414
from utcp.data.register_manual_response import RegisterManualResult
15+
from utcp.data.auth_implementations.api_key_auth import ApiKeyAuth
1516
from utcp.utcp_client import UtcpClient
1617

1718
@pytest_asyncio.fixture
@@ -356,3 +357,18 @@ async def test_call_tool_streaming(text_protocol: TextCommunicationProtocol, sam
356357
assert chunks == [content]
357358
finally:
358359
Path(temp_file).unlink()
360+
361+
362+
@pytest.mark.asyncio
363+
async def test_text_call_template_with_auth_tools():
364+
"""Test that TextCallTemplate can be created with auth_tools."""
365+
auth_tools = ApiKeyAuth(api_key="test-key", var_name="Authorization", location="header")
366+
367+
template = TextCallTemplate(
368+
name="test-template",
369+
file_path="test.json",
370+
auth_tools=auth_tools
371+
)
372+
373+
assert template.auth_tools == auth_tools
374+
assert template.auth is None # auth should still be None for file access

0 commit comments

Comments
 (0)