boxlite 0.1.0__cp311-cp311-macosx_11_0_arm64.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.

Potentially problematic release.


This version of boxlite might be problematic. Click here for more details.

Binary file
Binary file
boxlite/__init__.py ADDED
@@ -0,0 +1,25 @@
1
+ """
2
+ BoxLite - Lightweight, secure containerization for any environment.
3
+
4
+ Following SQLite philosophy: "BoxLite" for branding, "boxlite" for code APIs.
5
+ """
6
+
7
+ import os
8
+ from pathlib import Path
9
+
10
+ # Set BOXLITE_BIN_DIR if not already set, to help Rust find binaries
11
+ if "BOXLITE_BIN_DIR" not in os.environ:
12
+ # Check if binaries are bundled with the package
13
+ package_bin_dir = Path(__file__).parent / "bin"
14
+ if package_bin_dir.exists():
15
+ os.environ["BOXLITE_BIN_DIR"] = str(package_bin_dir)
16
+
17
+ from .core.box import Box
18
+ from .boxes import CodeBox
19
+
20
+ # Future specialized containers
21
+ # from .boxes.browser import BrowserBox
22
+ # from .boxes.claude_code import ClaudeCodeBox
23
+
24
+ __version__ = "0.1.0"
25
+ __all__ = ["Box", "CodeBox"]
Binary file
Binary file
@@ -0,0 +1,11 @@
1
+ """
2
+ Specialized BoxLite containers for specific use cases.
3
+ """
4
+
5
+ from .codebox import CodeBox
6
+
7
+ # Future specialized containers
8
+ # from .browser import BrowserBox
9
+ # from .claude_code import ClaudeCodeBox
10
+
11
+ __all__ = ["CodeBox"]
@@ -0,0 +1,126 @@
1
+ """
2
+ CodeBox - Secure Python code execution container.
3
+
4
+ Provides a simple, secure environment for running untrusted Python code.
5
+ """
6
+
7
+ from typing import Optional, Dict, Any, Union
8
+ from ..core.box import Box
9
+
10
+
11
+ class CodeBox(Box):
12
+ """
13
+ Secure container for executing Python code.
14
+
15
+ CodeBox provides an isolated environment for running untrusted Python code
16
+ with built-in safety and result formatting.
17
+
18
+ Example:
19
+ >>> with CodeBox() as codebox:
20
+ ... result = codebox.run("print('Hello, World!')")
21
+ ... print(result)
22
+ """
23
+
24
+ def __init__(
25
+ self,
26
+ image: str = "python:slim",
27
+ memory_mib: Optional[int] = None,
28
+ cpus: Optional[int] = None,
29
+ **kwargs
30
+ ):
31
+ """
32
+ Create a new CodeBox for Python code execution.
33
+
34
+ Args:
35
+ image: Container image with Python (default: python:slim)
36
+ memory_mib: Memory limit in MiB (default: system default)
37
+ cpus: Number of CPU cores (default: system default)
38
+ **kwargs: Additional Box configuration options
39
+ """
40
+ # Set up Python-specific defaults
41
+ config = {
42
+ 'engine': kwargs.get('engine', 'libkrun'),
43
+ 'memory_mib': memory_mib,
44
+ 'cpus': cpus,
45
+ }
46
+
47
+ # Filter out None values
48
+ config = {k: v for k, v in config.items() if v is not None}
49
+
50
+ # Merge with any additional kwargs
51
+ config.update({k: v for k, v in kwargs.items() if k not in config})
52
+
53
+ # Initialize the base Box with Python image
54
+ super().__init__(image=image, **config)
55
+
56
+ async def run(self, code: str, timeout: Optional[int] = None) -> Union[str, Dict[str, Any]]:
57
+ """
58
+ Execute Python code in the secure container.
59
+
60
+ Args:
61
+ code: Python code to execute
62
+ timeout: Execution timeout in seconds (not yet implemented)
63
+
64
+ Returns:
65
+ Execution output as a string
66
+
67
+ Example:
68
+ >>> async with CodeBox() as cb:
69
+ ... result = await cb.run("print('Hello, World!')")
70
+ ... print(result)
71
+ [stdout] Hello, World!
72
+
73
+ Note:
74
+ Uses python3 from the container image.
75
+ For custom Python paths, use execute() directly:
76
+ await cb.execute("/path/to/python", "-c", code)
77
+ """
78
+ # Execute Python code using python3 -c
79
+ return await self.execute("/usr/local/bin/python", "-c", code)
80
+
81
+ async def run_script(self, script_path: str) -> str:
82
+ """
83
+ Execute a Python script file in the container.
84
+
85
+ Args:
86
+ script_path: Path to the Python script on the host
87
+
88
+ Returns:
89
+ Execution output as a string
90
+ """
91
+ with open(script_path, 'r') as f:
92
+ code = f.read()
93
+ return await self.run(code)
94
+
95
+ async def install_package(self, package: str) -> str:
96
+ """
97
+ Install a Python package in the container using pip.
98
+
99
+ Args:
100
+ package: Package name (e.g., 'requests', 'numpy==1.24.0')
101
+
102
+ Returns:
103
+ Installation output
104
+
105
+ Example:
106
+ >>> async with CodeBox() as cb:
107
+ ... await cb.install_package("requests")
108
+ ... result = await cb.run("import requests; print(requests.__version__)")
109
+ """
110
+ return await self.execute("pip", "install", package)
111
+
112
+ async def install_packages(self, *packages: str) -> str:
113
+ """
114
+ Install multiple Python packages.
115
+
116
+ Args:
117
+ *packages: Package names to install
118
+
119
+ Returns:
120
+ Installation output
121
+
122
+ Example:
123
+ >>> async with CodeBox() as cb:
124
+ ... await cb.install_packages("requests", "numpy", "pandas")
125
+ """
126
+ return await self.execute("pip", "install", *packages)
Binary file
@@ -0,0 +1,7 @@
1
+ """
2
+ Core BoxLite functionality.
3
+ """
4
+
5
+ from .box import Box
6
+
7
+ __all__ = ["Box"]
boxlite/core/box.py ADDED
@@ -0,0 +1,93 @@
1
+ """
2
+ Base Box class for BoxLite containers.
3
+
4
+ This is the main user-facing API that wraps the Rust extension.
5
+ """
6
+
7
+ from typing import Optional, Dict, Any, List, Tuple
8
+ import sys
9
+ import os
10
+ import fcntl
11
+
12
+
13
+ class Box:
14
+ """
15
+ Base class for all BoxLite containers.
16
+
17
+ Provides secure, lightweight containerization using VM technology.
18
+ """
19
+
20
+ def __init__(self, image: str = "alpine:latest", **kwargs):
21
+ """
22
+ Create a new BoxLite container.
23
+
24
+ Args:
25
+ image: Container image to use (default: alpine:latest)
26
+ **kwargs: Additional configuration options
27
+ - engine: VM engine to use ('libkrun', 'firecracker')
28
+ - memory_mib: Memory limit in MiB
29
+ - cpus: Number of CPU cores
30
+ - env: Environment variables as list of (key, value) tuples
31
+ """
32
+ # Import the Rust extension - the native Box class
33
+ try:
34
+ from ..boxlite import Box as NativeBox
35
+ # Use the native implementation directly
36
+ self._native_box = NativeBox({
37
+ 'engine': kwargs.get('engine', 'libkrun'),
38
+ 'image': image,
39
+ **{k: v for k, v in kwargs.items() if k != 'engine'}
40
+ })
41
+ self._use_native = True
42
+ return
43
+ except ImportError as e:
44
+ raise ImportError(
45
+ f"BoxLite native extension not found: {e}. "
46
+ "Please install with: pip install boxlite"
47
+ )
48
+
49
+
50
+ async def __aenter__(self):
51
+ """Async context manager entry."""
52
+ if self._use_native:
53
+ self._native_box.__enter__()
54
+ # Tokio runtime sets stdout/stderr to non-blocking mode
55
+ # Restore blocking mode to prevent BlockingIOError when printing
56
+ self._restore_blocking_mode()
57
+ return self
58
+
59
+ def _restore_blocking_mode(self):
60
+ """Restore blocking mode on stdout/stderr after Tokio sets them to non-blocking."""
61
+ for fd in [sys.stdout.fileno(), sys.stderr.fileno()]:
62
+ try:
63
+ flags = fcntl.fcntl(fd, fcntl.F_GETFL)
64
+ if flags & os.O_NONBLOCK:
65
+ fcntl.fcntl(fd, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)
66
+ except (OSError, AttributeError):
67
+ # Ignore errors (e.g., when stdout/stderr is not a real file)
68
+ pass
69
+
70
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
71
+ """Async context manager exit."""
72
+ if self._use_native:
73
+ return self._native_box.__exit__(exc_type, exc_val, exc_tb)
74
+ return None
75
+
76
+ async def execute(self, command: str, *args) -> str:
77
+ """
78
+ Execute a command in the container.
79
+
80
+ Args:
81
+ command: Command to execute
82
+ *args: Command arguments
83
+
84
+ Returns:
85
+ Command output as string
86
+ """
87
+ if self._use_native:
88
+ result = await self._native_box.run_command(command, list(args) if args else None)
89
+ if isinstance(result, list):
90
+ return '\n'.join(f"[{stream}] {text}" for stream, text in result if text.strip())
91
+ return str(result)
92
+
93
+ raise RuntimeError("Container not initialized")
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: boxlite
3
+ Version: 0.1.0
4
+ Summary: Python bindings for Boxlite sandbox runtime
5
+ Author: Boxlite Contributors
6
+ Requires-Python: >=3.9
@@ -0,0 +1,13 @@
1
+ boxlite-0.1.0.dist-info/RECORD,,
2
+ boxlite-0.1.0.dist-info/WHEEL,sha256=dewdenAwp3PDth0u4HpQhcjieEs1_hiwRbm3WvCuoaI,104
3
+ boxlite-0.1.0.dist-info/METADATA,sha256=7-eRZ_Kg6fNA_C3jaVWfJnjKLx1_JRYGkZAQyAEXT6E,156
4
+ boxlite/__init__.py,sha256=uFUVtHBVkjxpx9NxyyRfezBlLDpunNF_J-NCESPg-bg,726
5
+ boxlite/boxlite.cpython-311-darwin.so,sha256=2ersq6_ezNXrYhEgM6n5dR-_vxjWAhtvxRZ9p8x913s,2445664
6
+ boxlite/core/box.py,sha256=XwcevOo0opXWvVbUNL98Ozb7lf13Ucg8pPVrTqBqbzk,3223
7
+ boxlite/core/__init__.py,sha256=gnumx6utojYT12dd4_kGlJmxwMf0Yidnpc3RsLmOFpc,76
8
+ boxlite/bin/boxlite-runner,sha256=Q03LG8X5hDjjiR0fmdUy9Uc7Gv_8CGGaJFkc1LG-G6U,1640672
9
+ boxlite/bin/boxlite-guest,sha256=P8THYIum1PqfB5aDSnw9pnChURGwrUgKi1JSSP4Gjj8,2640464
10
+ boxlite/.dylibs/libkrunfw.4.dylib,sha256=_0skZ63p91-aH5cstSdJIJjAgffWSUjYtOJgOm42Euo,21979472
11
+ boxlite/.dylibs/libkrun.1.15.1.dylib,sha256=SlWoMO0mUm4oQmisLfkaNVmoKZe68KMJeYUgcyZVncc,4176176
12
+ boxlite/boxes/__init__.py,sha256=MYz3-Hgr9Qh2krmyp79amIGn5YovUOspLxZ-7HK7320,223
13
+ boxlite/boxes/codebox.py,sha256=ZBeXNjlRwRN0ywqnqCfqYdHYJmeZA2bqnPDOdeHXR6s,3850
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.9.6)
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-macosx_11_0_arm64