isolate 0.12.3__tar.gz → 0.12.5__tar.gz
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.
Potentially problematic release.
This version of isolate might be problematic. Click here for more details.
- {isolate-0.12.3 → isolate-0.12.5}/PKG-INFO +1 -3
- {isolate-0.12.3 → isolate-0.12.5}/README.md +0 -2
- {isolate-0.12.3 → isolate-0.12.5}/pyproject.toml +1 -1
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/common.py +15 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/conda.py +6 -19
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/virtualenv.py +32 -1
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/server.py +3 -1
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/_base.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/local.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/pyenv.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/remote.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/backends/settings.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/common/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/common/timestamp.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/_local/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/_local/_base.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/_local/agent_startup.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/common.py +1 -1
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/_base.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/agent.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/configuration.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/agent.proto +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/agent_pb2.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/agent_pb2.pyi +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/agent_pb2_grpc.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/common.proto +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/common_pb2.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/common_pb2.pyi +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/common_pb2_grpc.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/interface.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/ipc/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/ipc/_base.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/ipc/agent.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/logs.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/registry.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/definitions/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/definitions/server.proto +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/definitions/server_pb2.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/definitions/server_pb2.pyi +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/definitions/server_pb2_grpc.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health/__init__.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health/health.proto +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health/health_pb2.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health/health_pb2.pyi +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health/health_pb2_grpc.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/health_server.py +0 -0
- {isolate-0.12.3 → isolate-0.12.5}/src/isolate/server/interface.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: isolate
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.5
|
|
4
4
|
Summary: Managed isolated environments for Python
|
|
5
5
|
Author: Features & Labels
|
|
6
6
|
Author-email: hello@fal.ai
|
|
@@ -25,8 +25,6 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
|
|
26
26
|
# Isolate
|
|
27
27
|
|
|
28
|
-
> :warning: **Isolate** is still very young, and none of the APIs should be considered stable.
|
|
29
|
-
|
|
30
28
|
Run any Python function, with any dependencies, in any machine you want. Isolate offers a
|
|
31
29
|
pluggable end-to-end solution for building, managing, and using isolated environments (virtualenv,
|
|
32
30
|
conda, remote, and more).
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Isolate
|
|
2
2
|
|
|
3
|
-
> :warning: **Isolate** is still very young, and none of the APIs should be considered stable.
|
|
4
|
-
|
|
5
3
|
Run any Python function, with any dependencies, in any machine you want. Isolate offers a
|
|
6
4
|
pluggable end-to-end solution for building, managing, and using isolated environments (virtualenv,
|
|
7
5
|
conda, remote, and more).
|
|
@@ -238,3 +238,18 @@ def optional_import(module_name: str) -> ModuleType:
|
|
|
238
238
|
f"accessing {module_name!r} import functionality. Please try: "
|
|
239
239
|
f"'$ pip install \"isolate[build]\"' to install it."
|
|
240
240
|
) from exc
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@lru_cache(4)
|
|
244
|
+
def get_executable(command: str, home: str | None = None) -> Path:
|
|
245
|
+
for path in [home, None]:
|
|
246
|
+
binary_path = shutil.which(command, path=path)
|
|
247
|
+
if binary_path is not None:
|
|
248
|
+
return Path(binary_path)
|
|
249
|
+
else:
|
|
250
|
+
# TODO: we should probably show some instructions on how you
|
|
251
|
+
# can install conda here.
|
|
252
|
+
raise FileNotFoundError(
|
|
253
|
+
f"Could not find {command} executable. If {command} executable is not available by default, please point isolate "
|
|
254
|
+
f" to the path where conda binary is available '{home}'."
|
|
255
|
+
)
|
|
@@ -14,6 +14,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Union
|
|
|
14
14
|
from isolate.backends import BaseEnvironment, EnvironmentCreationError
|
|
15
15
|
from isolate.backends.common import (
|
|
16
16
|
active_python,
|
|
17
|
+
get_executable,
|
|
17
18
|
logged_io,
|
|
18
19
|
optional_import,
|
|
19
20
|
sha256_digest_of,
|
|
@@ -48,7 +49,6 @@ class CondaEnvironment(BaseEnvironment[Path]):
|
|
|
48
49
|
_exec_home: Optional[str] = _ISOLATE_MAMBA_HOME
|
|
49
50
|
_exec_command: Optional[str] = _MAMBA_COMMAND
|
|
50
51
|
|
|
51
|
-
|
|
52
52
|
@classmethod
|
|
53
53
|
def from_config(
|
|
54
54
|
cls,
|
|
@@ -162,15 +162,17 @@ class CondaEnvironment(BaseEnvironment[Path]):
|
|
|
162
162
|
|
|
163
163
|
def _run_create(self, env_path: str, env_name: str) -> None:
|
|
164
164
|
if self._exec_command == "conda":
|
|
165
|
-
self._run_conda(
|
|
165
|
+
self._run_conda(
|
|
166
|
+
"env", "create", "--force", "--prefix", env_path, "-f", env_name
|
|
167
|
+
)
|
|
166
168
|
else:
|
|
167
169
|
self._run_conda("env", "create", "--prefix", env_path, "-f", env_name)
|
|
168
170
|
|
|
169
171
|
def _run_destroy(self, connection_key: str) -> None:
|
|
170
|
-
self._run_conda("remove","--yes","--all","--prefix", connection_key)
|
|
172
|
+
self._run_conda("remove", "--yes", "--all", "--prefix", connection_key)
|
|
171
173
|
|
|
172
174
|
def _run_conda(self, *args: Any) -> None:
|
|
173
|
-
conda_executable =
|
|
175
|
+
conda_executable = get_executable(self._exec_command, self._exec_home)
|
|
174
176
|
with logged_io(partial(self.log, level=LogLevel.INFO)) as (stdout, stderr):
|
|
175
177
|
subprocess.check_call(
|
|
176
178
|
[conda_executable, *args],
|
|
@@ -186,21 +188,6 @@ class CondaEnvironment(BaseEnvironment[Path]):
|
|
|
186
188
|
return PythonIPC(self, connection_key)
|
|
187
189
|
|
|
188
190
|
|
|
189
|
-
@functools.lru_cache(1)
|
|
190
|
-
def _get_executable(command: str, home: str | None = None) -> Path:
|
|
191
|
-
for path in [home, None]:
|
|
192
|
-
conda_path = shutil.which(command, path=path)
|
|
193
|
-
if conda_path is not None:
|
|
194
|
-
return Path(conda_path)
|
|
195
|
-
else:
|
|
196
|
-
# TODO: we should probably show some instructions on how you
|
|
197
|
-
# can install conda here.
|
|
198
|
-
raise FileNotFoundError(
|
|
199
|
-
"Could not find conda executable. If conda executable is not available by default, please point isolate "
|
|
200
|
-
" to the path where conda binary is available 'ISOLATE_CONDA_HOME'."
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
|
|
204
191
|
def _depends_on(
|
|
205
192
|
dependencies: List[Union[str, Dict[str, List[str]]]],
|
|
206
193
|
package_name: str,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import shlex
|
|
4
5
|
import shutil
|
|
5
6
|
import subprocess
|
|
6
7
|
from dataclasses import dataclass, field
|
|
@@ -11,6 +12,7 @@ from typing import Any, ClassVar, Dict, List, Optional, Union
|
|
|
11
12
|
from isolate.backends import BaseEnvironment, EnvironmentCreationError
|
|
12
13
|
from isolate.backends.common import (
|
|
13
14
|
active_python,
|
|
15
|
+
get_executable,
|
|
14
16
|
get_executable_path,
|
|
15
17
|
logged_io,
|
|
16
18
|
optional_import,
|
|
@@ -20,6 +22,9 @@ from isolate.backends.settings import DEFAULT_SETTINGS, IsolateSettings
|
|
|
20
22
|
from isolate.connections import PythonIPC
|
|
21
23
|
from isolate.logs import LogLevel
|
|
22
24
|
|
|
25
|
+
_UV_RESOLVER_EXECUTABLE = os.environ.get("ISOLATE_UV_EXE", "uv")
|
|
26
|
+
_UV_RESOLVER_HOME = os.getenv("ISOLATE_UV_HOME")
|
|
27
|
+
|
|
23
28
|
|
|
24
29
|
@dataclass
|
|
25
30
|
class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
@@ -30,6 +35,7 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
30
35
|
python_version: Optional[str] = None
|
|
31
36
|
extra_index_urls: List[str] = field(default_factory=list)
|
|
32
37
|
tags: List[str] = field(default_factory=list)
|
|
38
|
+
resolver: Optional[str] = None
|
|
33
39
|
|
|
34
40
|
@classmethod
|
|
35
41
|
def from_config(
|
|
@@ -39,6 +45,10 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
39
45
|
) -> BaseEnvironment:
|
|
40
46
|
environment = cls(**config)
|
|
41
47
|
environment.apply_settings(settings)
|
|
48
|
+
if environment.resolver not in ("uv", None):
|
|
49
|
+
raise ValueError(
|
|
50
|
+
"Only 'uv' is supported as a resolver for virtualenv environments."
|
|
51
|
+
)
|
|
42
52
|
return environment
|
|
43
53
|
|
|
44
54
|
@property
|
|
@@ -49,6 +59,10 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
49
59
|
else:
|
|
50
60
|
constraints = []
|
|
51
61
|
|
|
62
|
+
extras = []
|
|
63
|
+
if self.resolver is not None:
|
|
64
|
+
extras.append(f"resolver={self.resolver}")
|
|
65
|
+
|
|
52
66
|
active_python_version = self.python_version or active_python()
|
|
53
67
|
return sha256_digest_of(
|
|
54
68
|
active_python_version,
|
|
@@ -56,6 +70,9 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
56
70
|
*constraints,
|
|
57
71
|
*self.extra_index_urls,
|
|
58
72
|
*sorted(self.tags),
|
|
73
|
+
# This is backwards compatible with environments not using
|
|
74
|
+
# the 'resolver' field.
|
|
75
|
+
*extras,
|
|
59
76
|
)
|
|
60
77
|
|
|
61
78
|
def install_requirements(self, path: Path) -> None:
|
|
@@ -69,9 +86,22 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
69
86
|
return None
|
|
70
87
|
|
|
71
88
|
self.log(f"Installing requirements: {', '.join(self.requirements)}")
|
|
89
|
+
environ = os.environ.copy()
|
|
90
|
+
|
|
91
|
+
if self.resolver == "uv":
|
|
92
|
+
# Set VIRTUAL_ENV to the actual path of the environment since that is
|
|
93
|
+
# how uv discovers the environment. This is necessary when using uv
|
|
94
|
+
# as the resolver.
|
|
95
|
+
environ["VIRTUAL_ENV"] = str(path)
|
|
96
|
+
base_pip_cmd = [
|
|
97
|
+
get_executable(_UV_RESOLVER_EXECUTABLE, _UV_RESOLVER_HOME),
|
|
98
|
+
"pip",
|
|
99
|
+
]
|
|
100
|
+
else:
|
|
101
|
+
base_pip_cmd = [get_executable_path(path, "pip")]
|
|
72
102
|
|
|
73
103
|
pip_cmd: List[Union[str, os.PathLike]] = [
|
|
74
|
-
|
|
104
|
+
*base_pip_cmd, # type: ignore
|
|
75
105
|
"install",
|
|
76
106
|
*self.requirements,
|
|
77
107
|
]
|
|
@@ -87,6 +117,7 @@ class VirtualPythonEnvironment(BaseEnvironment[Path]):
|
|
|
87
117
|
pip_cmd,
|
|
88
118
|
stdout=stdout,
|
|
89
119
|
stderr=stderr,
|
|
120
|
+
env=environ,
|
|
90
121
|
)
|
|
91
122
|
except subprocess.SubprocessError as exc:
|
|
92
123
|
raise EnvironmentCreationError(f"Failure during 'pip install': {exc}")
|
|
@@ -134,7 +134,9 @@ class BridgeManager:
|
|
|
134
134
|
agent.terminate()
|
|
135
135
|
|
|
136
136
|
bound_context = ExitStack()
|
|
137
|
-
stub = bound_context.enter_context(
|
|
137
|
+
stub = bound_context.enter_context(
|
|
138
|
+
connection._establish_bridge(max_wait_timeout=MAX_GRPC_WAIT_TIMEOUT)
|
|
139
|
+
)
|
|
138
140
|
return RunnerAgent(stub, queue, bound_context)
|
|
139
141
|
|
|
140
142
|
def _identify(self, connection: LocalPythonGRPC) -> Tuple[Any, ...]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,8 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
4
|
import os
|
|
5
|
-
from dataclasses import dataclass
|
|
6
5
|
from contextlib import contextmanager
|
|
6
|
+
from dataclasses import dataclass
|
|
7
7
|
from typing import TYPE_CHECKING, Any, Iterator, Optional, cast
|
|
8
8
|
|
|
9
9
|
from tblib import Traceback, TracebackParseError
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/agent_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{isolate-0.12.3 → isolate-0.12.5}/src/isolate/connections/grpc/definitions/common_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|