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 core/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"
version = "1.1.1"
version = "1.1.2"
authors = [
{ name = "UTCP Contributors" },
]
Expand Down
9 changes: 5 additions & 4 deletions core/src/utcp/implementations/default_variable_substitutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ def substitute(self, obj: dict | list | str, config: UtcpClientConfig, variable_
raise ValueError(f"Variable namespace '{variable_namespace}' contains invalid characters. Only alphanumeric characters and underscores are allowed.")

if isinstance(obj, str):
# Skip substitution for JSON $ref strings
if '$ref' in obj:
# Skip substitution for JSON Schema $ref (but not variables like $refresh_token)
if re.search(r'\$ref(?![a-zA-Z0-9_])', obj):
return obj

# Use a regular expression to find all variables in the string, supporting ${VAR} and $VAR formats
Expand Down Expand Up @@ -168,9 +168,10 @@ def find_required_variables(self, obj: dict | list | str, variable_namespace: Op
result.extend(vars)
return result
elif isinstance(obj, str):
# Skip substitution for JSON $ref strings
if '$ref' in obj:
# Skip JSON Schema $ref (but not variables like $refresh_token)
if re.search(r'\$ref(?![a-zA-Z0-9_])', obj):
return []

# Find all variables in the string, supporting ${VAR} and $VAR formats
variables = []
pattern = r'\${([a-zA-Z0-9_]+)}|\$([a-zA-Z0-9_]+)'
Expand Down
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.0"
version = "1.1.1"
authors = [
{ name = "UTCP Contributors" },
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ class OpenApiConverter:
Attributes:
spec: The parsed OpenAPI specification dictionary.
spec_url: Optional URL where the specification was retrieved from.
base_url: Optional base URL override for all API endpoints.
placeholder_counter: Counter for generating unique placeholder variables.
call_template_name: Normalized name for the call_template derived from the spec.
"""

def __init__(self, openapi_spec: Dict[str, Any], spec_url: Optional[str] = None, call_template_name: Optional[str] = None, auth_tools: Optional[Auth] = None):
def __init__(self, openapi_spec: Dict[str, Any], spec_url: Optional[str] = None, call_template_name: Optional[str] = None, auth_tools: Optional[Auth] = None, base_url: Optional[str] = None):
"""Initializes the OpenAPI converter.

Args:
Expand All @@ -98,10 +99,13 @@ def __init__(self, openapi_spec: Dict[str, Any], spec_url: Optional[str] = None,
the specification title is not provided.
auth_tools: Optional auth configuration for generated tools.
Applied only to endpoints that require authentication per OpenAPI spec.
base_url: Optional base URL override for all API endpoints.
When provided, this takes precedence over servers in the spec.
"""
self.spec = openapi_spec
self.spec_url = spec_url
self.auth_tools = auth_tools
self._base_url_override = base_url
# Single counter for all placeholder variables
self.placeholder_counter = 0
if call_template_name is None:
Expand Down Expand Up @@ -141,9 +145,12 @@ def convert(self) -> UtcpManual:
"""
self.placeholder_counter = 0
tools = []
servers = self.spec.get("servers")
if servers:
base_url = servers[0].get("url", "/")

# Determine base URL: override > servers > spec_url > fallback
if self._base_url_override:
base_url = self._base_url_override
elif self.spec.get("servers"):
base_url = self.spec["servers"][0].get("url", "/")
elif self.spec_url:
parsed_url = urlparse(self.spec_url)
base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
Expand Down