onetool-mcp 1.0.0b1__py3-none-any.whl → 1.0.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- onetool/cli.py +63 -4
- onetool_mcp-1.0.0rc2.dist-info/METADATA +266 -0
- onetool_mcp-1.0.0rc2.dist-info/RECORD +129 -0
- {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/licenses/LICENSE.txt +1 -1
- {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/licenses/NOTICE.txt +54 -64
- ot/__main__.py +6 -6
- ot/config/__init__.py +48 -46
- ot/config/global_templates/__init__.py +2 -2
- ot/config/{defaults → global_templates}/diagram-templates/api-flow.mmd +33 -33
- ot/config/{defaults → global_templates}/diagram-templates/c4-context.puml +30 -30
- ot/config/{defaults → global_templates}/diagram-templates/class-diagram.mmd +87 -87
- ot/config/{defaults → global_templates}/diagram-templates/feature-mindmap.mmd +70 -70
- ot/config/{defaults → global_templates}/diagram-templates/microservices.d2 +81 -81
- ot/config/{defaults → global_templates}/diagram-templates/project-gantt.mmd +37 -37
- ot/config/{defaults → global_templates}/diagram-templates/state-machine.mmd +42 -42
- ot/config/global_templates/diagram.yaml +167 -0
- ot/config/global_templates/onetool.yaml +3 -1
- ot/config/{defaults → global_templates}/prompts.yaml +102 -97
- ot/config/global_templates/security.yaml +31 -0
- ot/config/global_templates/servers.yaml +93 -12
- ot/config/global_templates/snippets.yaml +5 -26
- ot/config/{defaults → global_templates}/tool_templates/__init__.py +7 -7
- ot/config/loader.py +221 -105
- ot/config/mcp.py +5 -1
- ot/config/secrets.py +192 -190
- ot/decorators.py +116 -116
- ot/executor/__init__.py +35 -35
- ot/executor/base.py +16 -16
- ot/executor/fence_processor.py +83 -83
- ot/executor/linter.py +142 -142
- ot/executor/pep723.py +288 -288
- ot/executor/runner.py +20 -6
- ot/executor/simple.py +163 -163
- ot/executor/validator.py +603 -164
- ot/http_client.py +145 -145
- ot/logging/__init__.py +37 -37
- ot/logging/entry.py +213 -213
- ot/logging/format.py +191 -188
- ot/logging/span.py +349 -349
- ot/meta.py +236 -14
- ot/paths.py +32 -49
- ot/prompts.py +218 -218
- ot/proxy/manager.py +14 -2
- ot/registry/__init__.py +189 -189
- ot/registry/parser.py +269 -269
- ot/server.py +330 -315
- ot/shortcuts/__init__.py +15 -15
- ot/shortcuts/aliases.py +87 -87
- ot/shortcuts/snippets.py +258 -258
- ot/stats/__init__.py +35 -35
- ot/stats/html.py +2 -2
- ot/stats/reader.py +354 -354
- ot/stats/timing.py +57 -57
- ot/support.py +63 -63
- ot/tools.py +1 -1
- ot/utils/batch.py +161 -161
- ot/utils/cache.py +120 -120
- ot/utils/exceptions.py +23 -23
- ot/utils/factory.py +178 -179
- ot/utils/format.py +65 -65
- ot/utils/http.py +202 -202
- ot/utils/platform.py +45 -45
- ot/utils/truncate.py +69 -69
- ot_tools/__init__.py +4 -4
- ot_tools/_convert/__init__.py +12 -12
- ot_tools/_convert/pdf.py +254 -254
- ot_tools/diagram.yaml +167 -167
- ot_tools/scaffold.py +2 -2
- ot_tools/transform.py +124 -19
- ot_tools/web_fetch.py +94 -43
- onetool_mcp-1.0.0b1.dist-info/METADATA +0 -163
- onetool_mcp-1.0.0b1.dist-info/RECORD +0 -132
- ot/config/defaults/bench.yaml +0 -4
- ot/config/defaults/onetool.yaml +0 -25
- ot/config/defaults/servers.yaml +0 -7
- ot/config/defaults/snippets.yaml +0 -4
- ot_tools/firecrawl.py +0 -732
- {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/WHEEL +0 -0
- {onetool_mcp-1.0.0b1.dist-info → onetool_mcp-1.0.0rc2.dist-info}/entry_points.txt +0 -0
- /ot/config/{defaults → global_templates}/tool_templates/extension.py +0 -0
- /ot/config/{defaults → global_templates}/tool_templates/isolated.py +0 -0
ot/http_client.py
CHANGED
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
"""Shared HTTP client utilities.
|
|
2
|
-
|
|
3
|
-
Provides a unified http_get() function for making HTTP GET requests with:
|
|
4
|
-
- Consistent error handling and message format
|
|
5
|
-
- Optional headers (for auth tokens)
|
|
6
|
-
- Optional timeout (defaults from config)
|
|
7
|
-
- Optional LogSpan integration for observability
|
|
8
|
-
- Content-type aware response parsing (JSON or text)
|
|
9
|
-
- Connection pooling via shared client singleton
|
|
10
|
-
|
|
11
|
-
Usage:
|
|
12
|
-
from ot.http_client import http_get
|
|
13
|
-
|
|
14
|
-
# Basic GET
|
|
15
|
-
success, result = http_get("https://api.example.com/data")
|
|
16
|
-
|
|
17
|
-
# With headers and params
|
|
18
|
-
success, result = http_get(
|
|
19
|
-
"https://api.example.com/search",
|
|
20
|
-
params={"q": "test"},
|
|
21
|
-
headers={"Authorization": "Bearer token"},
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
# With LogSpan for observability
|
|
25
|
-
success, result = http_get(
|
|
26
|
-
url,
|
|
27
|
-
log_span="api.fetch",
|
|
28
|
-
log_data={"query": query},
|
|
29
|
-
)
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
from __future__ import annotations
|
|
33
|
-
|
|
34
|
-
import atexit
|
|
35
|
-
import contextlib
|
|
36
|
-
import threading
|
|
37
|
-
from typing import Any
|
|
38
|
-
|
|
39
|
-
import httpx
|
|
40
|
-
|
|
41
|
-
# Global shared HTTP client with connection pooling
|
|
42
|
-
_client: httpx.Client | None = None
|
|
43
|
-
_client_lock = threading.Lock()
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def _get_shared_client() -> httpx.Client:
|
|
47
|
-
"""Get or create the shared HTTP client with connection pooling."""
|
|
48
|
-
global _client
|
|
49
|
-
if _client is None:
|
|
50
|
-
with _client_lock:
|
|
51
|
-
if _client is None:
|
|
52
|
-
_client = httpx.Client(
|
|
53
|
-
timeout=30.0,
|
|
54
|
-
limits=httpx.Limits(
|
|
55
|
-
max_keepalive_connections=20,
|
|
56
|
-
max_connections=100,
|
|
57
|
-
keepalive_expiry=30.0,
|
|
58
|
-
),
|
|
59
|
-
)
|
|
60
|
-
atexit.register(_shutdown_client)
|
|
61
|
-
return _client
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _shutdown_client() -> None:
|
|
65
|
-
"""Close the shared client on exit."""
|
|
66
|
-
global _client
|
|
67
|
-
if _client is not None:
|
|
68
|
-
with contextlib.suppress(Exception):
|
|
69
|
-
_client.close()
|
|
70
|
-
_client = None
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def http_get(
|
|
74
|
-
url: str,
|
|
75
|
-
*,
|
|
76
|
-
params: dict[str, Any] | None = None,
|
|
77
|
-
headers: dict[str, str] | None = None,
|
|
78
|
-
timeout: float | None = None,
|
|
79
|
-
log_span: str | None = None,
|
|
80
|
-
log_data: dict[str, Any] | None = None,
|
|
81
|
-
) -> tuple[bool, dict[str, Any] | str]:
|
|
82
|
-
"""Make HTTP GET request with unified error handling.
|
|
83
|
-
|
|
84
|
-
Args:
|
|
85
|
-
url: Full URL to request
|
|
86
|
-
params: Optional query parameters
|
|
87
|
-
headers: Optional HTTP headers (e.g., auth tokens)
|
|
88
|
-
timeout: Request timeout in seconds (defaults to 30.0)
|
|
89
|
-
log_span: Optional LogSpan name for observability
|
|
90
|
-
log_data: Optional data to include in LogSpan
|
|
91
|
-
|
|
92
|
-
Returns:
|
|
93
|
-
Tuple of (success, result). If success, result is parsed JSON dict
|
|
94
|
-
or response text. If failure, result is error message string.
|
|
95
|
-
"""
|
|
96
|
-
from ot.logging import LogSpan as LogSpanClass
|
|
97
|
-
|
|
98
|
-
# Default timeout
|
|
99
|
-
if timeout is None:
|
|
100
|
-
timeout = 30.0
|
|
101
|
-
|
|
102
|
-
# Optional LogSpan wrapper
|
|
103
|
-
span: LogSpanClass | None = None
|
|
104
|
-
if log_span:
|
|
105
|
-
span = LogSpanClass(span=log_span, **(log_data or {}))
|
|
106
|
-
span.__enter__()
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
client = _get_shared_client()
|
|
110
|
-
response = client.get(url, params=params, headers=headers, timeout=timeout)
|
|
111
|
-
response.raise_for_status()
|
|
112
|
-
|
|
113
|
-
# Parse based on content type
|
|
114
|
-
content_type = response.headers.get("content-type", "")
|
|
115
|
-
if "application/json" in content_type:
|
|
116
|
-
result = response.json()
|
|
117
|
-
else:
|
|
118
|
-
result = response.text
|
|
119
|
-
|
|
120
|
-
if span:
|
|
121
|
-
span.add("status", response.status_code)
|
|
122
|
-
|
|
123
|
-
return True, result
|
|
124
|
-
|
|
125
|
-
except httpx.HTTPStatusError as e:
|
|
126
|
-
error_msg = f"HTTP error ({e.response.status_code}): {e.response.text[:200]}"
|
|
127
|
-
if span:
|
|
128
|
-
span.add("error", f"HTTP {e.response.status_code}")
|
|
129
|
-
return False, error_msg
|
|
130
|
-
|
|
131
|
-
except httpx.RequestError as e:
|
|
132
|
-
error_msg = f"Request failed: {e}"
|
|
133
|
-
if span:
|
|
134
|
-
span.add("error", str(e))
|
|
135
|
-
return False, error_msg
|
|
136
|
-
|
|
137
|
-
except Exception as e:
|
|
138
|
-
error_msg = f"Error: {e}"
|
|
139
|
-
if span:
|
|
140
|
-
span.add("error", str(e))
|
|
141
|
-
return False, error_msg
|
|
142
|
-
|
|
143
|
-
finally:
|
|
144
|
-
if span:
|
|
145
|
-
span.__exit__(None, None, None)
|
|
1
|
+
"""Shared HTTP client utilities.
|
|
2
|
+
|
|
3
|
+
Provides a unified http_get() function for making HTTP GET requests with:
|
|
4
|
+
- Consistent error handling and message format
|
|
5
|
+
- Optional headers (for auth tokens)
|
|
6
|
+
- Optional timeout (defaults from config)
|
|
7
|
+
- Optional LogSpan integration for observability
|
|
8
|
+
- Content-type aware response parsing (JSON or text)
|
|
9
|
+
- Connection pooling via shared client singleton
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
from ot.http_client import http_get
|
|
13
|
+
|
|
14
|
+
# Basic GET
|
|
15
|
+
success, result = http_get("https://api.example.com/data")
|
|
16
|
+
|
|
17
|
+
# With headers and params
|
|
18
|
+
success, result = http_get(
|
|
19
|
+
"https://api.example.com/search",
|
|
20
|
+
params={"q": "test"},
|
|
21
|
+
headers={"Authorization": "Bearer token"},
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# With LogSpan for observability
|
|
25
|
+
success, result = http_get(
|
|
26
|
+
url,
|
|
27
|
+
log_span="api.fetch",
|
|
28
|
+
log_data={"query": query},
|
|
29
|
+
)
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import atexit
|
|
35
|
+
import contextlib
|
|
36
|
+
import threading
|
|
37
|
+
from typing import Any
|
|
38
|
+
|
|
39
|
+
import httpx
|
|
40
|
+
|
|
41
|
+
# Global shared HTTP client with connection pooling
|
|
42
|
+
_client: httpx.Client | None = None
|
|
43
|
+
_client_lock = threading.Lock()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _get_shared_client() -> httpx.Client:
|
|
47
|
+
"""Get or create the shared HTTP client with connection pooling."""
|
|
48
|
+
global _client
|
|
49
|
+
if _client is None:
|
|
50
|
+
with _client_lock:
|
|
51
|
+
if _client is None:
|
|
52
|
+
_client = httpx.Client(
|
|
53
|
+
timeout=30.0,
|
|
54
|
+
limits=httpx.Limits(
|
|
55
|
+
max_keepalive_connections=20,
|
|
56
|
+
max_connections=100,
|
|
57
|
+
keepalive_expiry=30.0,
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
atexit.register(_shutdown_client)
|
|
61
|
+
return _client
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _shutdown_client() -> None:
|
|
65
|
+
"""Close the shared client on exit."""
|
|
66
|
+
global _client
|
|
67
|
+
if _client is not None:
|
|
68
|
+
with contextlib.suppress(Exception):
|
|
69
|
+
_client.close()
|
|
70
|
+
_client = None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def http_get(
|
|
74
|
+
url: str,
|
|
75
|
+
*,
|
|
76
|
+
params: dict[str, Any] | None = None,
|
|
77
|
+
headers: dict[str, str] | None = None,
|
|
78
|
+
timeout: float | None = None,
|
|
79
|
+
log_span: str | None = None,
|
|
80
|
+
log_data: dict[str, Any] | None = None,
|
|
81
|
+
) -> tuple[bool, dict[str, Any] | str]:
|
|
82
|
+
"""Make HTTP GET request with unified error handling.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
url: Full URL to request
|
|
86
|
+
params: Optional query parameters
|
|
87
|
+
headers: Optional HTTP headers (e.g., auth tokens)
|
|
88
|
+
timeout: Request timeout in seconds (defaults to 30.0)
|
|
89
|
+
log_span: Optional LogSpan name for observability
|
|
90
|
+
log_data: Optional data to include in LogSpan
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Tuple of (success, result). If success, result is parsed JSON dict
|
|
94
|
+
or response text. If failure, result is error message string.
|
|
95
|
+
"""
|
|
96
|
+
from ot.logging import LogSpan as LogSpanClass
|
|
97
|
+
|
|
98
|
+
# Default timeout
|
|
99
|
+
if timeout is None:
|
|
100
|
+
timeout = 30.0
|
|
101
|
+
|
|
102
|
+
# Optional LogSpan wrapper
|
|
103
|
+
span: LogSpanClass | None = None
|
|
104
|
+
if log_span:
|
|
105
|
+
span = LogSpanClass(span=log_span, **(log_data or {}))
|
|
106
|
+
span.__enter__()
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
client = _get_shared_client()
|
|
110
|
+
response = client.get(url, params=params, headers=headers, timeout=timeout)
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
|
|
113
|
+
# Parse based on content type
|
|
114
|
+
content_type = response.headers.get("content-type", "")
|
|
115
|
+
if "application/json" in content_type:
|
|
116
|
+
result = response.json()
|
|
117
|
+
else:
|
|
118
|
+
result = response.text
|
|
119
|
+
|
|
120
|
+
if span:
|
|
121
|
+
span.add("status", response.status_code)
|
|
122
|
+
|
|
123
|
+
return True, result
|
|
124
|
+
|
|
125
|
+
except httpx.HTTPStatusError as e:
|
|
126
|
+
error_msg = f"HTTP error ({e.response.status_code}): {e.response.text[:200]}"
|
|
127
|
+
if span:
|
|
128
|
+
span.add("error", f"HTTP {e.response.status_code}")
|
|
129
|
+
return False, error_msg
|
|
130
|
+
|
|
131
|
+
except httpx.RequestError as e:
|
|
132
|
+
error_msg = f"Request failed: {e}"
|
|
133
|
+
if span:
|
|
134
|
+
span.add("error", str(e))
|
|
135
|
+
return False, error_msg
|
|
136
|
+
|
|
137
|
+
except Exception as e:
|
|
138
|
+
error_msg = f"Error: {e}"
|
|
139
|
+
if span:
|
|
140
|
+
span.add("error", str(e))
|
|
141
|
+
return False, error_msg
|
|
142
|
+
|
|
143
|
+
finally:
|
|
144
|
+
if span:
|
|
145
|
+
span.__exit__(None, None, None)
|
ot/logging/__init__.py
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
"""Structured logging for OneTool MCP server.
|
|
2
|
-
|
|
3
|
-
Provides JSON-structured logging with:
|
|
4
|
-
- LogEntry: Fluent API for building log entries with auto-timing
|
|
5
|
-
- LogSpan: Context manager for auto-logging operations
|
|
6
|
-
- File-only JSON output
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
from loguru import logger
|
|
10
|
-
|
|
11
|
-
# Remove Loguru's default console handler immediately.
|
|
12
|
-
# This prevents logs from appearing on console before configure_logging() is called.
|
|
13
|
-
logger.remove()
|
|
14
|
-
|
|
15
|
-
from ot.logging.config import ( # noqa: E402
|
|
16
|
-
configure_logging,
|
|
17
|
-
configure_test_logging,
|
|
18
|
-
)
|
|
19
|
-
from ot.logging.entry import LogEntry # noqa: E402
|
|
20
|
-
from ot.logging.format import ( # noqa: E402
|
|
21
|
-
format_log_entry,
|
|
22
|
-
format_value,
|
|
23
|
-
sanitize_for_output,
|
|
24
|
-
sanitize_url,
|
|
25
|
-
)
|
|
26
|
-
from ot.logging.span import LogSpan # noqa: E402
|
|
27
|
-
|
|
28
|
-
__all__ = [
|
|
29
|
-
"LogEntry",
|
|
30
|
-
"LogSpan",
|
|
31
|
-
"configure_logging",
|
|
32
|
-
"configure_test_logging",
|
|
33
|
-
"format_log_entry",
|
|
34
|
-
"format_value",
|
|
35
|
-
"sanitize_for_output",
|
|
36
|
-
"sanitize_url",
|
|
37
|
-
]
|
|
1
|
+
"""Structured logging for OneTool MCP server.
|
|
2
|
+
|
|
3
|
+
Provides JSON-structured logging with:
|
|
4
|
+
- LogEntry: Fluent API for building log entries with auto-timing
|
|
5
|
+
- LogSpan: Context manager for auto-logging operations
|
|
6
|
+
- File-only JSON output
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
# Remove Loguru's default console handler immediately.
|
|
12
|
+
# This prevents logs from appearing on console before configure_logging() is called.
|
|
13
|
+
logger.remove()
|
|
14
|
+
|
|
15
|
+
from ot.logging.config import ( # noqa: E402
|
|
16
|
+
configure_logging,
|
|
17
|
+
configure_test_logging,
|
|
18
|
+
)
|
|
19
|
+
from ot.logging.entry import LogEntry # noqa: E402
|
|
20
|
+
from ot.logging.format import ( # noqa: E402
|
|
21
|
+
format_log_entry,
|
|
22
|
+
format_value,
|
|
23
|
+
sanitize_for_output,
|
|
24
|
+
sanitize_url,
|
|
25
|
+
)
|
|
26
|
+
from ot.logging.span import LogSpan # noqa: E402
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"LogEntry",
|
|
30
|
+
"LogSpan",
|
|
31
|
+
"configure_logging",
|
|
32
|
+
"configure_test_logging",
|
|
33
|
+
"format_log_entry",
|
|
34
|
+
"format_value",
|
|
35
|
+
"sanitize_for_output",
|
|
36
|
+
"sanitize_url",
|
|
37
|
+
]
|