Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/communication_protocols/http/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "utcp-http"
version = "1.1.8"
version = "1.1.9"
authors = [
{ name = "UTCP Contributors" },
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,15 @@
from utcp_http.http_call_template import HttpCallTemplate
from utcp_http._security import ensure_secure_url, is_loopback_url

# HTTP methods that HttpCallTemplate.http_method accepts. Kept as the single
# source of truth for both the operation loop filter and per-operation
# validation so the two can never drift apart.
# All HTTP methods that OpenAPI defines as operation fields on a Path Item
# Object. The conversion loop uses this to tell operations apart from the other
# path-item keys (parameters, summary, $ref, servers, ...), so that genuinely
# unsupported operations still reach _create_tool and get a warning rather than
# being silently dropped by the loop.
OPENAPI_OPERATION_METHODS: Tuple[str, ...] = ("get", "put", "post", "delete", "options", "head", "patch", "trace")

# The subset of HTTP methods that HttpCallTemplate.http_method accepts.
# _create_tool validates against this and skips anything else with a warning.
SUPPORTED_HTTP_METHODS: Tuple[str, ...] = ("GET", "POST", "PUT", "DELETE", "PATCH")

class OpenApiConverter:
Expand Down Expand Up @@ -190,7 +196,7 @@ def convert(self) -> UtcpManual:

for path, path_item in self.spec.get("paths", {}).items():
for method, operation in path_item.items():
if method.upper() in SUPPORTED_HTTP_METHODS:
if method.lower() in OPENAPI_OPERATION_METHODS:
tool = self._create_tool(path, method, operation, base_url)
if tool:
tools.append(tool)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def test_openapi_converter_parameter_examples():
assert example_value["email"] == "jane@example.com"


def test_openapi_converter_skips_unsupported_methods():
def test_openapi_converter_skips_unsupported_methods(capsys):
"""Operations with HTTP methods HttpCallTemplate cannot represent are skipped, not crashed on."""
openapi_spec = {
"openapi": "3.0.0",
Expand Down Expand Up @@ -254,6 +254,13 @@ def test_openapi_converter_skips_unsupported_methods():
tool_names = {tool.name for tool in manual.tools}
assert tool_names == {"listThings"}

# Unsupported operations must reach _create_tool and emit a skip warning,
# not be silently dropped by the loop filter.
stderr = capsys.readouterr().err
assert "optionsThings" in stderr
assert "headThings" in stderr
assert "traceThings" in stderr


def test_openapi_converter_schema_level_examples_normalized():
"""Examples declared at the schema level (not the media type) are normalized into 'examples'."""
Expand Down
Loading