aisolate-client 0.3.7__tar.gz → 0.3.9__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.
Files changed (37) hide show
  1. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/PKG-INFO +2 -2
  2. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/README.md +1 -1
  3. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/pyproject.toml +1 -1
  4. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/sandbox.py +12 -4
  5. aisolate_client-0.3.9/src/aisolate/client/tests/test_sandbox_context_env.py +52 -0
  6. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate_client.egg-info/PKG-INFO +2 -2
  7. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate_client.egg-info/SOURCES.txt +1 -0
  8. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/setup.cfg +0 -0
  9. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/__init__.py +0 -0
  10. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/__init__.py +0 -0
  11. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/exception.py +0 -0
  12. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/gateway_client.py +0 -0
  13. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/models.py +0 -0
  14. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/remote_executer.py +0 -0
  15. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/sandbox_manager.py +0 -0
  16. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/__init__.py +0 -0
  17. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/integration/__init__.py +0 -0
  18. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/integration/conftest.py +0 -0
  19. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/integration/test_gateway_client.py +0 -0
  20. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/integration/test_sandbox.py +0 -0
  21. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/test_gateway_client_demux.py +0 -0
  22. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/client/tests/test_sandbox_workspace_prefix.py +0 -0
  23. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/__init__.py +0 -0
  24. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/codec.py +0 -0
  25. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/errors.py +0 -0
  26. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/execution_protocol.py +0 -0
  27. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/models.py +0 -0
  28. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/output_window.py +0 -0
  29. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/__init__.py +0 -0
  30. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/fake_vm.py +0 -0
  31. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/fixtures.py +0 -0
  32. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/test_codec_channel.py +0 -0
  33. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/test_output_window.py +0 -0
  34. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate/common/tests/utils.py +0 -0
  35. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate_client.egg-info/dependency_links.txt +0 -0
  36. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate_client.egg-info/requires.txt +0 -0
  37. {aisolate_client-0.3.7 → aisolate_client-0.3.9}/src/aisolate_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisolate-client
3
- Version: 0.3.7
3
+ Version: 0.3.9
4
4
  Summary: Client library for sandbox environments
5
5
  License: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -16,7 +16,7 @@ Client library for sandbox environments
16
16
  ## Local Installation
17
17
 
18
18
  ```bash
19
- pip install path/to/aisolate_client-0.3.7-py3-none-any.whl
19
+ pip install path/to/aisolate_client-0.3.9-py3-none-any.whl
20
20
  ```
21
21
 
22
22
  ## Usage
@@ -5,7 +5,7 @@ Client library for sandbox environments
5
5
  ## Local Installation
6
6
 
7
7
  ```bash
8
- pip install path/to/aisolate_client-0.3.7-py3-none-any.whl
8
+ pip install path/to/aisolate_client-0.3.9-py3-none-any.whl
9
9
  ```
10
10
 
11
11
  ## Usage
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aisolate-client"
7
- version = "0.3.7"
7
+ version = "0.3.9"
8
8
  description = "Client library for sandbox environments"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -682,7 +682,11 @@ class Sandbox:
682
682
  sbx_b.run_code("x = 20; print(x)")
683
683
  ```
684
684
  """
685
- ctx = self.create_context(language=language, cwd=cwd, env=env)
685
+ # The sandbox-wide variables become the context's process environment,
686
+ # set once at kernel start instead of travelling with every request.
687
+ ctx = self.create_context(
688
+ language=language, cwd=cwd, env={**(self._additional_env_vars or {}), **(env or {})}
689
+ )
686
690
 
687
691
  # Create a new Sandbox instance that shares the client and has a default
688
692
  # context; a relative cwd is a workspace subdir the instance is scoped to.
@@ -692,7 +696,7 @@ class Sandbox:
692
696
  context_id=ctx["id"],
693
697
  domain=self._domain,
694
698
  api_key=self._api_key,
695
- additional_env_vars=self._additional_env_vars,
699
+ additional_env_vars={},
696
700
  timeout=self._timeout,
697
701
  ping_interval=self._ping_interval,
698
702
  ping_timeout=self._ping_timeout,
@@ -732,7 +736,11 @@ class Sandbox:
732
736
  await sbx_b.arun_code("x = 20; print(x)")
733
737
  ```
734
738
  """
735
- ctx = await self.acreate_context(language=language, cwd=cwd, env=env)
739
+ # The sandbox-wide variables become the context's process environment,
740
+ # set once at kernel start instead of travelling with every request.
741
+ ctx = await self.acreate_context(
742
+ language=language, cwd=cwd, env={**(self._additional_env_vars or {}), **(env or {})}
743
+ )
736
744
 
737
745
  # Create a new Sandbox instance that shares the client and has a default
738
746
  # context; a relative cwd is a workspace subdir the instance is scoped to.
@@ -743,7 +751,7 @@ class Sandbox:
743
751
  context_id=ctx["id"],
744
752
  domain=self._domain,
745
753
  api_key=self._api_key,
746
- additional_env_vars=self._additional_env_vars,
754
+ additional_env_vars={},
747
755
  timeout=self._timeout,
748
756
  ping_interval=self._ping_interval,
749
757
  ping_timeout=self._ping_timeout,
@@ -0,0 +1,52 @@
1
+ """Sandbox-wide variables travel once, as the bound context's environment.
2
+
3
+ ``additional_env_vars`` carry credentials. A context-bound Sandbox hands them
4
+ to the new context at creation (they become the kernel process environment)
5
+ and stops attaching them to every execute request.
6
+ """
7
+
8
+ from aisolate.client.sandbox import Sandbox
9
+
10
+
11
+ class _RecordingClient:
12
+ def __init__(self):
13
+ self.context_env = None
14
+ self.execute_env_vars = []
15
+
16
+ async def create_context(self, sandbox_id, language, *, cwd=None, env=None):
17
+ self.context_env = env
18
+ return {"id": "ctx-1", "language": language, "cwd": cwd}
19
+
20
+ async def execute_code(self, sandbox_id, code, *, language, env_vars, context_id):
21
+ self.execute_env_vars.append(env_vars)
22
+ return
23
+ yield # an empty async event stream
24
+
25
+
26
+ def _parent(client):
27
+ sandbox = Sandbox(
28
+ sandbox_id="sbx-1",
29
+ gateway_client=client,
30
+ additional_env_vars={"API_KEY": "secret", "HOST": "example"},
31
+ )
32
+ sandbox._is_active = True
33
+ return sandbox
34
+
35
+
36
+ async def test_bound_sandbox_sets_variables_once_as_context_env():
37
+ client = _RecordingClient()
38
+
39
+ bound = await _parent(client).acreate_context_bound_sandbox("python3", cwd="agent-1", env={"WINDOW": "4000"})
40
+ await bound.arun_code("1")
41
+ await bound.arun_code("2")
42
+
43
+ assert client.context_env == {"API_KEY": "secret", "HOST": "example", "WINDOW": "4000"}
44
+ assert client.execute_env_vars == [{}, {}]
45
+
46
+
47
+ async def test_explicit_context_env_wins_over_sandbox_wide_value():
48
+ client = _RecordingClient()
49
+
50
+ await _parent(client).acreate_context_bound_sandbox("python3", env={"HOST": "override"})
51
+
52
+ assert client.context_env["HOST"] == "override"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisolate-client
3
- Version: 0.3.7
3
+ Version: 0.3.9
4
4
  Summary: Client library for sandbox environments
5
5
  License: Apache-2.0
6
6
  Requires-Python: >=3.10
@@ -16,7 +16,7 @@ Client library for sandbox environments
16
16
  ## Local Installation
17
17
 
18
18
  ```bash
19
- pip install path/to/aisolate_client-0.3.7-py3-none-any.whl
19
+ pip install path/to/aisolate_client-0.3.9-py3-none-any.whl
20
20
  ```
21
21
 
22
22
  ## Usage
@@ -10,6 +10,7 @@ src/aisolate/client/sandbox.py
10
10
  src/aisolate/client/sandbox_manager.py
11
11
  src/aisolate/client/tests/__init__.py
12
12
  src/aisolate/client/tests/test_gateway_client_demux.py
13
+ src/aisolate/client/tests/test_sandbox_context_env.py
13
14
  src/aisolate/client/tests/test_sandbox_workspace_prefix.py
14
15
  src/aisolate/client/tests/integration/__init__.py
15
16
  src/aisolate/client/tests/integration/conftest.py