-
Notifications
You must be signed in to change notification settings - Fork 43
Expand file tree
/
Copy pathhttp_call_template.py
More file actions
165 lines (149 loc) · 6.19 KB
/
http_call_template.py
File metadata and controls
165 lines (149 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from utcp.data.call_template import CallTemplate, CallTemplateSerializer
from utcp.data.auth import Auth, AuthSerializer
from utcp.interfaces.serializer import Serializer
from utcp.exceptions import UtcpSerializerValidationError
import traceback
from typing import Optional, Dict, List, Literal, Any
from pydantic import Field, field_serializer, field_validator
class HttpCallTemplate(CallTemplate):
"""REQUIRED
Provider configuration for HTTP-based tools.
Supports RESTful HTTP/HTTPS APIs with various HTTP methods, authentication,
custom headers, and flexible request/response handling. Supports URL path
parameters using {parameter_name} syntax. All tool arguments not mapped to
URL body, headers or query pattern parameters are passed as query parameters using '?arg_name={arg_value}'.
Configuration Examples:
Basic HTTP GET request:
```json
{
"name": "my_rest_api",
"call_template_type": "http",
"url": "https://api.example.com/users/{user_id}",
"http_method": "GET"
}
```
POST with authentication:
```json
{
"name": "secure_api",
"call_template_type": "http",
"url": "https://api.example.com/users",
"http_method": "POST",
"content_type": "application/json",
"auth": {
"auth_type": "api_key",
"api_key": "Bearer ${API_KEY}",
"var_name": "Authorization",
"location": "header"
},
"auth_tools": {
"auth_type": "api_key",
"api_key": "Bearer ${TOOL_API_KEY}",
"var_name": "Authorization",
"location": "header"
},
"headers": {
"X-Custom-Header": "value"
},
"body_field": "body",
"header_fields": ["user_id"]
}
```
OAuth2 authentication:
```json
{
"name": "oauth_api",
"call_template_type": "http",
"url": "https://api.example.com/data",
"http_method": "GET",
"auth": {
"auth_type": "oauth2",
"client_id": "${CLIENT_ID}",
"client_secret": "${CLIENT_SECRET}",
"token_url": "https://auth.example.com/token"
}
}
```
Basic authentication:
```json
{
"name": "basic_auth_api",
"call_template_type": "http",
"url": "https://api.example.com/secure",
"http_method": "GET",
"auth": {
"auth_type": "basic",
"username": "${USERNAME}",
"password": "${PASSWORD}"
}
}
```
Attributes:
call_template_type: Always "http" for HTTP providers.
http_method: The HTTP method to use for requests.
url: The base URL for the HTTP endpoint. Supports path parameters like
"https://api.example.com/users/{user_id}/posts/{post_id}".
content_type: The Content-Type header for requests.
auth: Optional authentication configuration for accessing the OpenAPI spec URL.
auth_tools: Optional authentication configuration for generated tools. Applied only to endpoints requiring auth per OpenAPI spec.
headers: Optional static headers to include in all requests.
body_field: Name of the tool argument to map to the HTTP request body.
header_fields: List of tool argument names to map to HTTP request headers.
"""
call_template_type: Literal["http"] = "http"
http_method: Literal["GET", "POST", "PUT", "DELETE", "PATCH"] = "GET"
url: str
content_type: str = Field(default="application/json")
auth: Optional[Auth] = None
auth_tools: Optional[Auth] = Field(default=None, description="Authentication configuration for generated tools (applied only to endpoints requiring auth per OpenAPI spec)")
headers: Optional[Dict[str, str]] = None
body_field: Optional[str] = Field(default="body", description="The name of the single input field to be sent as the request body.")
header_fields: Optional[List[str]] = Field(default=None, description="List of input fields to be sent as request headers.")
@field_serializer('auth')
def serialize_auth(self, auth: Optional[Auth]) -> Optional[dict]:
"""Serialize auth to dictionary."""
if auth is None:
return None
return AuthSerializer().to_dict(auth)
@field_validator('auth', mode='before')
@classmethod
def validate_auth(cls, v: Any) -> Optional[Auth]:
"""Validate and deserialize auth from dictionary."""
if v is None:
return None
if isinstance(v, Auth):
return v
if isinstance(v, dict):
return AuthSerializer().validate_dict(v)
raise ValueError(f"auth must be None, Auth instance, or dict, got {type(v)}")
@field_serializer('auth_tools')
def serialize_auth_tools(self, auth_tools: Optional[Auth]) -> Optional[dict]:
"""Serialize auth_tools to dictionary."""
if auth_tools is None:
return None
return AuthSerializer().to_dict(auth_tools)
@field_validator('auth_tools', mode='before')
@classmethod
def validate_auth_tools(cls, v: Any) -> Optional[Auth]:
"""Validate and deserialize auth_tools from dictionary."""
if v is None:
return None
if isinstance(v, Auth):
return v
if isinstance(v, dict):
return AuthSerializer().validate_dict(v)
raise ValueError(f"auth_tools must be None, Auth instance, or dict, got {type(v)}")
class HttpCallTemplateSerializer(Serializer[HttpCallTemplate]):
"""REQUIRED
Serializer for HttpCallTemplate."""
def to_dict(self, obj: HttpCallTemplate) -> dict:
"""REQUIRED
Convert HttpCallTemplate to dictionary."""
return obj.model_dump()
def validate_dict(self, obj: dict) -> HttpCallTemplate:
"""REQUIRED
Validate dictionary and convert to HttpCallTemplate."""
try:
return HttpCallTemplate.model_validate(obj)
except Exception as e:
raise UtcpSerializerValidationError("Invalid HttpCallTemplate: " + traceback.format_exc()) from e