@@ -93,6 +93,56 @@ asyncio.run(main())
9393- Using LocalSandboxManager: Uniformly orchestrate lifecycle/cleanup of multiple sandboxes on local machine; suitable for service-oriented, multi-task parallel scenarios
9494- Using HttpSandboxManager: Manage sandboxes uniformly through remote HTTP service; suitable for cross-machine/distributed or stronger isolation deployments
9595
96+ ### 0) Manager Factory: SandboxManagerFactory (Automatic Local/HTTP selection)
97+
98+ When to use:
99+ - You want a single entry point that chooses Local or HTTP manager automatically.
100+ - You prefer central registration and discovery of available manager types.
101+
102+ Key points:
103+ - If manager_type is provided, it is used directly.
104+ - If base_url is provided (in config or kwargs), HTTP manager is created.
105+ - Otherwise, Local manager is created by default.
106+
107+ Example: implicit selection by base_url
108+ ``` python
109+ import asyncio
110+ from ms_enclave.sandbox.manager import SandboxManagerFactory
111+
112+ async def main ():
113+ async with SandboxManagerFactory.create_manager(base_url = ' http://127.0.0.1:8000' ) as m:
114+ # Use exactly like HttpSandboxManager
115+ # e.g., create a DOCKER sandbox and execute a tool
116+ # ... your code ...
117+ pass
118+
119+ asyncio.run(main())
120+ ```
121+
122+ Example: explicit selection + custom config
123+ ``` python
124+ import asyncio
125+ from ms_enclave.sandbox.manager import SandboxManagerFactory
126+ from ms_enclave.sandbox.model import SandboxManagerConfig, SandboxManagerType
127+
128+ async def main ():
129+ cfg = SandboxManagerConfig(cleanup_interval = 600 )
130+ async with SandboxManagerFactory.create_manager(
131+ manager_type = SandboxManagerType.LOCAL , config = cfg
132+ ) as m:
133+ # Use exactly like LocalSandboxManager
134+ # ... your code ...
135+ pass
136+
137+ asyncio.run(main())
138+ ```
139+
140+ Discover registered manager types:
141+ ``` python
142+ from ms_enclave.sandbox.manager import SandboxManagerFactory
143+ print (SandboxManagerFactory.get_registered_types())
144+ ```
145+
96146### 1) Direct Sandbox Creation: SandboxFactory (Lightweight, Temporary)
97147
98148Use Cases:
@@ -189,6 +239,66 @@ async def main():
189239asyncio.run(main())
190240```
191241
242+ ### 4) Pooled Sandboxes: Pre-warmed workers (Sandbox Pool)
243+
244+ Why:
245+ - Amortize container startup by keeping a fixed-size pool of ready sandboxes.
246+ - Each execution borrows a sandbox and returns it; requests queue FIFO when all are busy.
247+
248+ Local pool example:
249+
250+ ``` python
251+ import asyncio
252+ from ms_enclave.sandbox.manager import LocalSandboxManager
253+ from ms_enclave.sandbox.model import DockerSandboxConfig, SandboxType
254+
255+ async def main ():
256+ async with LocalSandboxManager() as m:
257+ cfg = DockerSandboxConfig(
258+ image = ' python:3.11-slim' ,
259+ tools_config = {' python_executor' : {}}
260+ )
261+ # Create a pool of 2 pre-warmed sandboxes
262+ await m.initialize_pool(pool_size = 2 , sandbox_type = SandboxType.DOCKER , config = cfg)
263+
264+ # Execute multiple tasks; sandboxes are reused and queued FIFO when busy
265+ tasks = [
266+ m.execute_tool_in_pool(' python_executor' , {' code' : f ' print("task { i} ") ' , ' timeout' : 30 })
267+ for i in range (5 )
268+ ]
269+ results = await asyncio.gather(* tasks)
270+ print ([r.output.strip() for r in results])
271+
272+ # Pool stats
273+ stats = await m.get_stats()
274+ print (' pool_size =' , stats[' pool_size' ])
275+
276+ asyncio.run(main())
277+ ```
278+
279+ HTTP pool example:
280+
281+ ``` python
282+ import asyncio
283+ from ms_enclave.sandbox.manager import HttpSandboxManager
284+ from ms_enclave.sandbox.model import DockerSandboxConfig, SandboxType
285+
286+ async def main ():
287+ async with HttpSandboxManager(base_url = ' http://127.0.0.1:8000' ) as m:
288+ cfg = DockerSandboxConfig(image = ' python:3.11-slim' , tools_config = {' python_executor' : {}})
289+ await m.initialize_pool(pool_size = 2 , sandbox_type = SandboxType.DOCKER , config = cfg)
290+
291+ r = await m.execute_tool_in_pool(' python_executor' , {' code' : ' print("hello from pool")' , ' timeout' : 30 })
292+ print (r.output)
293+
294+ asyncio.run(main())
295+ ```
296+
297+ Notes:
298+ - Waiting timeout: ` await m.execute_tool_in_pool(..., timeout=1.0) ` raises ` TimeoutError ` if no sandbox is available in time.
299+ - FIFO behavior: pool borrows/returns in FIFO order under load.
300+ - Errors: even if a tool execution fails, the sandbox is returned to the pool.
301+
192302---
193303
194304## Sandbox Types & Tool Support
@@ -233,6 +343,10 @@ DockerNotebookConfig(tools_config={'notebook_executor': {}})
233343- ` network_enabled ` : Whether to enable network (Notebook sandbox requires True)
234344- ` remove_on_exit ` : Whether to delete container on exit (default True)
235345
346+ Manager Config (SandboxManagerConfig):
347+ - ` base_url ` : If set, HttpSandboxManager is selected automatically
348+ - ` cleanup_interval ` : Background cleanup interval in seconds (local manager)
349+
236350** Example of Installing Additional Dependencies in Sandbox**
237351``` python
238352async with SandboxFactory.create_sandbox(SandboxType.DOCKER , config) as sandbox:
0 commit comments