fix(python): export SecurityOptions from top-level boxlite module#247
Conversation
SecurityOptions was defined in the Rust PyO3 layer (lib.rs) but not re-exported in __init__.py, causing: ImportError: cannot import name 'SecurityOptions' from 'boxlite' Users had to use the undocumented internal path: from boxlite.boxlite import SecurityOptions Fix: add SecurityOptions to the import list and __all__ so the documented `from boxlite import SecurityOptions` works. Note: the strict() preset referenced in some docs does not exist. Only development(), standard(), and maximum() are available. Documentation referencing strict() should be updated separately. Closes #230 Closes #236 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes issues #230 and #236 by exporting SecurityOptions from the top-level boxlite module, making it accessible via from boxlite import SecurityOptions as documented. Previously, users had to import it via the internal path from boxlite.boxlite import SecurityOptions.
Changes:
- Added
SecurityOptionsto the import list from the Rust extension module - Added
SecurityOptionsto the__all__list for proper public API exposure
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -39,6 +40,7 @@ | |||
| "BoxMetrics", | |||
| "CopyOptions", | |||
| "RootfsSpec", | |||
| "SecurityOptions", | |||
There was a problem hiding this comment.
Consider adding test coverage for the SecurityOptions export. The codebase has a pattern where Python convenience wrappers (SimpleBox, CodeBox, errors) have dedicated export tests (e.g., TestSimpleBoxExports, TestCodeBoxExports), though core Rust API types don't currently have this coverage. Adding a test would help prevent regressions and match the pattern used for Python wrapper exports.
|
Self-review: This PR looks correct. The bug: The fix adds it to both the import block and |
Long-running / repeated-op leak detection: - stability-churn — 50 create+start+stop cycles, per-cycle latency + host fd delta. Catches per-cycle leaks (fd / tempfile / DB row accounting) - stability-soak — keep one box alive for BOXLITE_BENCH_SOAK_SECS (default 30 s), sample RSS/COW/fd every 2 s, report first→last deltas. Catches steady-state idle leaks churn misses - stability-soak-load — soak with continuous in-box fio random reads. Catches under-load leaks (gvproxy goroutine pools, libkrun dirty-page buffers) that idle soak misses - stability-exec-loop — 500 sequential execs on one box. Tolerant of partial completion: reports `exec_completed_count` and a per-iter failure-index marker. Documents the historical ~exec boxlite-ai#247 InitReady/IntermediateReady mismatch in alpine x86_64 so future regressions show as the failure boundary moving down - stability-exec-parallel — 20 concurrent execs via tokio::spawn fan-out, batch wall + per-exec p99 under contention. Tests gRPC fairness and the guest's exec state-map lock - stability-restart-loop — 20 stop+start cycles on the SAME box (distinct from churn's create-each-time). Re-fetches the LiteBox handle via `rt.get(id)` between cycles because `stop` invalidates the previous handle (would otherwise abort cycle 0) - stability-snapshot-loop — 20 sequential SnapshotHandle::create calls. Headline is per-create mean/max + COW byte delta. Remove omitted: creating snapshot N moves the current overlay's parent to N, so remove(N) fails until N+1 exists; mixing the two ops would couple latencies Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
SecurityOptionsto the import list and__all__in__init__.pysofrom boxlite import SecurityOptionsworks as documentedTest plan
from boxlite import SecurityOptionssucceedsSecurityOptions.development(),.standard(),.maximum()all workCloses #230
Closes #236
🤖 Generated with Claude Code