provide-foundation 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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.
- provide/foundation/__init__.py +36 -10
- provide/foundation/archive/__init__.py +1 -1
- provide/foundation/archive/base.py +15 -14
- provide/foundation/archive/bzip2.py +40 -40
- provide/foundation/archive/gzip.py +42 -42
- provide/foundation/archive/operations.py +93 -96
- provide/foundation/archive/tar.py +33 -31
- provide/foundation/archive/zip.py +52 -50
- provide/foundation/asynctools/__init__.py +20 -0
- provide/foundation/asynctools/core.py +126 -0
- provide/foundation/cli/__init__.py +2 -2
- provide/foundation/cli/commands/deps.py +15 -9
- provide/foundation/cli/commands/logs/__init__.py +3 -3
- provide/foundation/cli/commands/logs/generate.py +2 -2
- provide/foundation/cli/commands/logs/query.py +4 -4
- provide/foundation/cli/commands/logs/send.py +3 -3
- provide/foundation/cli/commands/logs/tail.py +3 -3
- provide/foundation/cli/decorators.py +11 -11
- provide/foundation/cli/main.py +1 -1
- provide/foundation/cli/testing.py +2 -40
- provide/foundation/cli/utils.py +21 -18
- provide/foundation/config/__init__.py +35 -2
- provide/foundation/config/base.py +2 -2
- provide/foundation/config/converters.py +477 -0
- provide/foundation/config/defaults.py +67 -0
- provide/foundation/config/env.py +6 -20
- provide/foundation/config/loader.py +10 -4
- provide/foundation/config/sync.py +8 -6
- provide/foundation/config/types.py +5 -5
- provide/foundation/config/validators.py +4 -4
- provide/foundation/console/input.py +5 -5
- provide/foundation/console/output.py +36 -14
- provide/foundation/context/__init__.py +8 -4
- provide/foundation/context/core.py +88 -110
- provide/foundation/crypto/certificates/__init__.py +9 -5
- provide/foundation/crypto/certificates/base.py +2 -2
- provide/foundation/crypto/certificates/certificate.py +48 -19
- provide/foundation/crypto/certificates/factory.py +26 -18
- provide/foundation/crypto/certificates/generator.py +24 -23
- provide/foundation/crypto/certificates/loader.py +24 -16
- provide/foundation/crypto/certificates/operations.py +17 -10
- provide/foundation/crypto/certificates/trust.py +21 -21
- provide/foundation/env/__init__.py +28 -0
- provide/foundation/env/core.py +218 -0
- provide/foundation/errors/__init__.py +3 -3
- provide/foundation/errors/decorators.py +0 -234
- provide/foundation/errors/types.py +0 -98
- provide/foundation/eventsets/display.py +13 -14
- provide/foundation/eventsets/registry.py +61 -31
- provide/foundation/eventsets/resolver.py +50 -46
- provide/foundation/eventsets/sets/das.py +8 -8
- provide/foundation/eventsets/sets/database.py +14 -14
- provide/foundation/eventsets/sets/http.py +21 -21
- provide/foundation/eventsets/sets/llm.py +16 -16
- provide/foundation/eventsets/sets/task_queue.py +13 -13
- provide/foundation/eventsets/types.py +7 -7
- provide/foundation/file/directory.py +14 -23
- provide/foundation/file/lock.py +4 -3
- provide/foundation/hub/components.py +75 -389
- provide/foundation/hub/config.py +157 -0
- provide/foundation/hub/discovery.py +63 -0
- provide/foundation/hub/handlers.py +89 -0
- provide/foundation/hub/lifecycle.py +195 -0
- provide/foundation/hub/manager.py +7 -4
- provide/foundation/hub/processors.py +49 -0
- provide/foundation/integrations/__init__.py +11 -0
- provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
- provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/client.py +14 -14
- provide/foundation/{observability → integrations}/openobserve/commands.py +12 -12
- provide/foundation/integrations/openobserve/config.py +37 -0
- provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
- provide/foundation/{observability → integrations}/openobserve/otlp.py +2 -2
- provide/foundation/{observability → integrations}/openobserve/search.py +2 -3
- provide/foundation/{observability → integrations}/openobserve/streaming.py +5 -5
- provide/foundation/logger/__init__.py +0 -1
- provide/foundation/logger/config/base.py +1 -1
- provide/foundation/logger/config/logging.py +69 -299
- provide/foundation/logger/config/telemetry.py +39 -121
- provide/foundation/logger/factories.py +2 -2
- provide/foundation/logger/processors/main.py +12 -10
- provide/foundation/logger/ratelimit/limiters.py +4 -4
- provide/foundation/logger/ratelimit/processor.py +1 -1
- provide/foundation/logger/setup/coordinator.py +39 -25
- provide/foundation/logger/setup/processors.py +3 -3
- provide/foundation/logger/setup/testing.py +14 -0
- provide/foundation/logger/trace.py +5 -5
- provide/foundation/metrics/__init__.py +1 -1
- provide/foundation/metrics/otel.py +3 -1
- provide/foundation/observability/__init__.py +3 -3
- provide/foundation/process/__init__.py +9 -0
- provide/foundation/process/exit.py +48 -0
- provide/foundation/process/lifecycle.py +69 -46
- provide/foundation/resilience/__init__.py +36 -0
- provide/foundation/resilience/circuit.py +166 -0
- provide/foundation/resilience/decorators.py +236 -0
- provide/foundation/resilience/fallback.py +208 -0
- provide/foundation/resilience/retry.py +327 -0
- provide/foundation/serialization/__init__.py +16 -0
- provide/foundation/serialization/core.py +70 -0
- provide/foundation/streams/config.py +78 -0
- provide/foundation/streams/console.py +4 -5
- provide/foundation/streams/core.py +5 -2
- provide/foundation/streams/file.py +12 -2
- provide/foundation/testing/__init__.py +29 -9
- provide/foundation/testing/archive/__init__.py +7 -7
- provide/foundation/testing/archive/fixtures.py +58 -54
- provide/foundation/testing/cli.py +30 -20
- provide/foundation/testing/common/__init__.py +13 -15
- provide/foundation/testing/common/fixtures.py +27 -57
- provide/foundation/testing/file/__init__.py +15 -15
- provide/foundation/testing/file/content_fixtures.py +289 -0
- provide/foundation/testing/file/directory_fixtures.py +107 -0
- provide/foundation/testing/file/fixtures.py +42 -516
- provide/foundation/testing/file/special_fixtures.py +145 -0
- provide/foundation/testing/logger.py +89 -8
- provide/foundation/testing/mocking/__init__.py +21 -21
- provide/foundation/testing/mocking/fixtures.py +80 -67
- provide/foundation/testing/process/__init__.py +23 -23
- provide/foundation/testing/process/async_fixtures.py +414 -0
- provide/foundation/testing/process/fixtures.py +48 -571
- provide/foundation/testing/process/subprocess_fixtures.py +210 -0
- provide/foundation/testing/threading/__init__.py +17 -17
- provide/foundation/testing/threading/basic_fixtures.py +105 -0
- provide/foundation/testing/threading/data_fixtures.py +101 -0
- provide/foundation/testing/threading/execution_fixtures.py +278 -0
- provide/foundation/testing/threading/fixtures.py +32 -502
- provide/foundation/testing/threading/sync_fixtures.py +100 -0
- provide/foundation/testing/time/__init__.py +11 -11
- provide/foundation/testing/time/fixtures.py +95 -83
- provide/foundation/testing/transport/__init__.py +9 -9
- provide/foundation/testing/transport/fixtures.py +54 -54
- provide/foundation/time/__init__.py +18 -0
- provide/foundation/time/core.py +63 -0
- provide/foundation/tools/__init__.py +2 -2
- provide/foundation/tools/base.py +68 -67
- provide/foundation/tools/cache.py +69 -74
- provide/foundation/tools/downloader.py +68 -62
- provide/foundation/tools/installer.py +51 -57
- provide/foundation/tools/registry.py +38 -45
- provide/foundation/tools/resolver.py +70 -68
- provide/foundation/tools/verifier.py +39 -50
- provide/foundation/tracer/spans.py +2 -14
- provide/foundation/transport/__init__.py +26 -33
- provide/foundation/transport/base.py +32 -30
- provide/foundation/transport/client.py +44 -49
- provide/foundation/transport/config.py +36 -107
- provide/foundation/transport/errors.py +13 -27
- provide/foundation/transport/http.py +69 -55
- provide/foundation/transport/middleware.py +113 -114
- provide/foundation/transport/registry.py +29 -27
- provide/foundation/transport/types.py +6 -6
- provide/foundation/utils/deps.py +17 -14
- provide/foundation/utils/parsing.py +49 -4
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
- provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
- provide_foundation-0.0.0.dev1.dist-info/RECORD +0 -200
- /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
- /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
- {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -5,11 +5,11 @@ Fixtures and helpers for testing network operations, including
|
|
5
5
|
mock servers, free port allocation, and HTTP client mocking.
|
6
6
|
"""
|
7
7
|
|
8
|
+
from collections.abc import Generator
|
9
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
8
10
|
import socket
|
9
11
|
import threading
|
10
|
-
from http.server import HTTPServer, BaseHTTPRequestHandler
|
11
12
|
from typing import Any
|
12
|
-
from collections.abc import Generator
|
13
13
|
|
14
14
|
import pytest
|
15
15
|
|
@@ -18,12 +18,12 @@ import pytest
|
|
18
18
|
def free_port() -> int:
|
19
19
|
"""
|
20
20
|
Get a free port for testing.
|
21
|
-
|
21
|
+
|
22
22
|
Returns:
|
23
23
|
An available port number on localhost.
|
24
24
|
"""
|
25
25
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
26
|
-
s.bind((
|
26
|
+
s.bind(("", 0))
|
27
27
|
s.listen(1)
|
28
28
|
port = s.getsockname()[1]
|
29
29
|
return port
|
@@ -33,62 +33,62 @@ def free_port() -> int:
|
|
33
33
|
def mock_server(free_port) -> Generator[dict[str, Any], None, None]:
|
34
34
|
"""
|
35
35
|
Create a simple mock HTTP server for testing.
|
36
|
-
|
36
|
+
|
37
37
|
Args:
|
38
38
|
free_port: Free port number from fixture.
|
39
|
-
|
39
|
+
|
40
40
|
Yields:
|
41
41
|
Dict with server info including url, port, and server instance.
|
42
42
|
"""
|
43
43
|
responses = {}
|
44
44
|
requests_received = []
|
45
|
-
|
45
|
+
|
46
46
|
class MockHandler(BaseHTTPRequestHandler):
|
47
47
|
"""Handler for mock HTTP server."""
|
48
|
-
|
48
|
+
|
49
49
|
def do_GET(self):
|
50
50
|
"""Handle GET requests."""
|
51
|
-
requests_received.append(
|
52
|
-
"method": "GET",
|
53
|
-
|
54
|
-
|
55
|
-
})
|
56
|
-
|
51
|
+
requests_received.append(
|
52
|
+
{"method": "GET", "path": self.path, "headers": dict(self.headers)}
|
53
|
+
)
|
54
|
+
|
57
55
|
response = responses.get(self.path, {"status": 404, "body": b"Not Found"})
|
58
56
|
self.send_response(response["status"])
|
59
57
|
for header, value in response.get("headers", {}).items():
|
60
58
|
self.send_header(header, value)
|
61
59
|
self.end_headers()
|
62
60
|
self.wfile.write(response["body"])
|
63
|
-
|
61
|
+
|
64
62
|
def do_POST(self):
|
65
63
|
"""Handle POST requests."""
|
66
|
-
content_length = int(self.headers.get(
|
64
|
+
content_length = int(self.headers.get("Content-Length", 0))
|
67
65
|
body = self.rfile.read(content_length) if content_length else b""
|
68
|
-
|
69
|
-
requests_received.append(
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
66
|
+
|
67
|
+
requests_received.append(
|
68
|
+
{
|
69
|
+
"method": "POST",
|
70
|
+
"path": self.path,
|
71
|
+
"headers": dict(self.headers),
|
72
|
+
"body": body,
|
73
|
+
}
|
74
|
+
)
|
75
|
+
|
76
76
|
response = responses.get(self.path, {"status": 200, "body": b"OK"})
|
77
77
|
self.send_response(response["status"])
|
78
78
|
for header, value in response.get("headers", {}).items():
|
79
79
|
self.send_header(header, value)
|
80
80
|
self.end_headers()
|
81
81
|
self.wfile.write(response["body"])
|
82
|
-
|
82
|
+
|
83
83
|
def log_message(self, format, *args):
|
84
84
|
"""Suppress log messages."""
|
85
85
|
pass
|
86
|
-
|
87
|
-
server = HTTPServer((
|
86
|
+
|
87
|
+
server = HTTPServer(("localhost", free_port), MockHandler)
|
88
88
|
server_thread = threading.Thread(target=server.serve_forever)
|
89
89
|
server_thread.daemon = True
|
90
90
|
server_thread.start()
|
91
|
-
|
91
|
+
|
92
92
|
yield {
|
93
93
|
"url": f"http://localhost:{free_port}",
|
94
94
|
"port": free_port,
|
@@ -96,7 +96,7 @@ def mock_server(free_port) -> Generator[dict[str, Any], None, None]:
|
|
96
96
|
"responses": responses,
|
97
97
|
"requests": requests_received,
|
98
98
|
}
|
99
|
-
|
99
|
+
|
100
100
|
server.shutdown()
|
101
101
|
server.server_close()
|
102
102
|
|
@@ -105,7 +105,7 @@ def mock_server(free_port) -> Generator[dict[str, Any], None, None]:
|
|
105
105
|
def httpx_mock_responses():
|
106
106
|
"""
|
107
107
|
Pre-configured responses for HTTPX mocking.
|
108
|
-
|
108
|
+
|
109
109
|
Returns:
|
110
110
|
Dict of common mock responses.
|
111
111
|
"""
|
@@ -142,12 +142,12 @@ def httpx_mock_responses():
|
|
142
142
|
def mock_websocket():
|
143
143
|
"""
|
144
144
|
Mock WebSocket connection for testing.
|
145
|
-
|
145
|
+
|
146
146
|
Returns:
|
147
147
|
Mock WebSocket with send, receive, close methods.
|
148
148
|
"""
|
149
|
-
from unittest.mock import
|
150
|
-
|
149
|
+
from unittest.mock import AsyncMock, Mock
|
150
|
+
|
151
151
|
ws = Mock()
|
152
152
|
ws.send = AsyncMock()
|
153
153
|
ws.receive = AsyncMock(return_value={"type": "text", "data": "message"})
|
@@ -155,11 +155,11 @@ def mock_websocket():
|
|
155
155
|
ws.accept = AsyncMock()
|
156
156
|
ws.ping = AsyncMock()
|
157
157
|
ws.pong = AsyncMock()
|
158
|
-
|
158
|
+
|
159
159
|
# State properties
|
160
160
|
ws.closed = False
|
161
161
|
ws.url = "ws://localhost:8000/ws"
|
162
|
-
|
162
|
+
|
163
163
|
return ws
|
164
164
|
|
165
165
|
|
@@ -167,17 +167,17 @@ def mock_websocket():
|
|
167
167
|
def mock_dns_resolver():
|
168
168
|
"""
|
169
169
|
Mock DNS resolver for testing.
|
170
|
-
|
170
|
+
|
171
171
|
Returns:
|
172
172
|
Mock resolver with resolve method.
|
173
173
|
"""
|
174
174
|
from unittest.mock import Mock
|
175
|
-
|
175
|
+
|
176
176
|
resolver = Mock()
|
177
177
|
resolver.resolve = Mock(return_value=["127.0.0.1", "::1"])
|
178
178
|
resolver.reverse = Mock(return_value="localhost")
|
179
179
|
resolver.clear_cache = Mock()
|
180
|
-
|
180
|
+
|
181
181
|
return resolver
|
182
182
|
|
183
183
|
|
@@ -185,39 +185,39 @@ def mock_dns_resolver():
|
|
185
185
|
def tcp_client_server(free_port) -> Generator[dict[str, Any], None, None]:
|
186
186
|
"""
|
187
187
|
Create a TCP client-server pair for testing.
|
188
|
-
|
188
|
+
|
189
189
|
Yields:
|
190
190
|
Dict with client socket, server socket, and port info.
|
191
191
|
"""
|
192
192
|
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
193
193
|
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
194
|
-
server_socket.bind((
|
194
|
+
server_socket.bind(("localhost", free_port))
|
195
195
|
server_socket.listen(1)
|
196
|
-
|
196
|
+
|
197
197
|
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
198
|
-
|
198
|
+
|
199
199
|
# Run server accept in thread
|
200
200
|
connection = None
|
201
|
-
|
201
|
+
|
202
202
|
def accept_connection():
|
203
203
|
nonlocal connection
|
204
204
|
connection, _ = server_socket.accept()
|
205
|
-
|
205
|
+
|
206
206
|
accept_thread = threading.Thread(target=accept_connection)
|
207
207
|
accept_thread.daemon = True
|
208
208
|
accept_thread.start()
|
209
|
-
|
209
|
+
|
210
210
|
# Connect client
|
211
|
-
client_socket.connect((
|
211
|
+
client_socket.connect(("localhost", free_port))
|
212
212
|
accept_thread.join(timeout=1)
|
213
|
-
|
213
|
+
|
214
214
|
yield {
|
215
215
|
"client": client_socket,
|
216
216
|
"server": connection,
|
217
217
|
"server_socket": server_socket,
|
218
218
|
"port": free_port,
|
219
219
|
}
|
220
|
-
|
220
|
+
|
221
221
|
# Cleanup
|
222
222
|
client_socket.close()
|
223
223
|
if connection:
|
@@ -229,12 +229,12 @@ def tcp_client_server(free_port) -> Generator[dict[str, Any], None, None]:
|
|
229
229
|
def mock_ssl_context():
|
230
230
|
"""
|
231
231
|
Mock SSL context for testing secure connections.
|
232
|
-
|
232
|
+
|
233
233
|
Returns:
|
234
234
|
Mock SSL context with common methods.
|
235
235
|
"""
|
236
236
|
from unittest.mock import Mock
|
237
|
-
|
237
|
+
|
238
238
|
context = Mock()
|
239
239
|
context.load_cert_chain = Mock()
|
240
240
|
context.load_verify_locations = Mock()
|
@@ -242,7 +242,7 @@ def mock_ssl_context():
|
|
242
242
|
context.wrap_socket = Mock()
|
243
243
|
context.check_hostname = True
|
244
244
|
context.verify_mode = 2 # ssl.CERT_REQUIRED
|
245
|
-
|
245
|
+
|
246
246
|
return context
|
247
247
|
|
248
248
|
|
@@ -250,7 +250,7 @@ def mock_ssl_context():
|
|
250
250
|
def network_timeout():
|
251
251
|
"""
|
252
252
|
Provide network timeout configuration for tests.
|
253
|
-
|
253
|
+
|
254
254
|
Returns:
|
255
255
|
Dict with timeout values for different operations.
|
256
256
|
"""
|
@@ -266,7 +266,7 @@ def network_timeout():
|
|
266
266
|
def mock_http_headers():
|
267
267
|
"""
|
268
268
|
Common HTTP headers for testing.
|
269
|
-
|
269
|
+
|
270
270
|
Returns:
|
271
271
|
Dict of typical HTTP headers.
|
272
272
|
"""
|
@@ -277,4 +277,4 @@ def mock_http_headers():
|
|
277
277
|
"Authorization": "Bearer test_token",
|
278
278
|
"X-Request-ID": "test-request-123",
|
279
279
|
"X-Correlation-ID": "test-correlation-456",
|
280
|
-
}
|
280
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
"""
|
2
|
+
Production time utilities for Foundation.
|
3
|
+
|
4
|
+
Provides consistent time handling with Foundation integration,
|
5
|
+
better testability, and timezone awareness.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from provide.foundation.time.core import (
|
9
|
+
provide_now,
|
10
|
+
provide_sleep,
|
11
|
+
provide_time,
|
12
|
+
)
|
13
|
+
|
14
|
+
__all__ = [
|
15
|
+
"provide_now",
|
16
|
+
"provide_sleep",
|
17
|
+
"provide_time",
|
18
|
+
]
|
@@ -0,0 +1,63 @@
|
|
1
|
+
"""Core time utilities for Foundation."""
|
2
|
+
|
3
|
+
from datetime import datetime
|
4
|
+
import time
|
5
|
+
from zoneinfo import ZoneInfo
|
6
|
+
|
7
|
+
|
8
|
+
def provide_time() -> float:
|
9
|
+
"""
|
10
|
+
Get current time with Foundation tracking.
|
11
|
+
|
12
|
+
Returns:
|
13
|
+
Current time as seconds since epoch
|
14
|
+
|
15
|
+
Example:
|
16
|
+
>>> current_time = provide_time()
|
17
|
+
>>> isinstance(current_time, float)
|
18
|
+
True
|
19
|
+
"""
|
20
|
+
return time.time()
|
21
|
+
|
22
|
+
|
23
|
+
def provide_sleep(seconds: float) -> None:
|
24
|
+
"""
|
25
|
+
Sleep with Foundation tracking and interruption support.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
seconds: Number of seconds to sleep
|
29
|
+
|
30
|
+
Example:
|
31
|
+
>>> provide_sleep(0.1) # Sleep for 100ms
|
32
|
+
"""
|
33
|
+
if seconds < 0:
|
34
|
+
raise ValueError("Sleep duration must be non-negative")
|
35
|
+
time.sleep(seconds)
|
36
|
+
|
37
|
+
|
38
|
+
def provide_now(tz: str | ZoneInfo | None = None) -> datetime:
|
39
|
+
"""
|
40
|
+
Get current datetime with timezone awareness.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
tz: Timezone (string name, ZoneInfo object, or None for local)
|
44
|
+
|
45
|
+
Returns:
|
46
|
+
Current datetime with timezone information
|
47
|
+
|
48
|
+
Example:
|
49
|
+
>>> now = provide_now()
|
50
|
+
>>> now.tzinfo is not None
|
51
|
+
True
|
52
|
+
>>> utc_now = provide_now("UTC")
|
53
|
+
>>> utc_now.tzinfo.key
|
54
|
+
'UTC'
|
55
|
+
"""
|
56
|
+
if tz is None:
|
57
|
+
return datetime.now()
|
58
|
+
elif isinstance(tz, str):
|
59
|
+
zone = ZoneInfo(tz)
|
60
|
+
else:
|
61
|
+
zone = tz
|
62
|
+
|
63
|
+
return datetime.now(zone)
|
@@ -26,8 +26,8 @@ Example:
|
|
26
26
|
|
27
27
|
from provide.foundation.tools.base import (
|
28
28
|
BaseToolManager,
|
29
|
-
ToolMetadata,
|
30
29
|
ToolError,
|
30
|
+
ToolMetadata,
|
31
31
|
)
|
32
32
|
from provide.foundation.tools.cache import ToolCache
|
33
33
|
from provide.foundation.tools.downloader import ToolDownloader
|
@@ -55,4 +55,4 @@ __all__ = [
|
|
55
55
|
"get_tool_manager",
|
56
56
|
"get_tool_registry",
|
57
57
|
"register_tool_manager",
|
58
|
-
]
|
58
|
+
]
|