nodepyx 1.0.0
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.
- package/LICENSE +22 -0
- package/README.md +399 -0
- package/binding.gyp +73 -0
- package/dist/core/PyCallable.d.ts +65 -0
- package/dist/core/PyCallable.d.ts.map +1 -0
- package/dist/core/PyCallable.js +109 -0
- package/dist/core/PyCallable.js.map +1 -0
- package/dist/core/PyContext.d.ts +76 -0
- package/dist/core/PyContext.d.ts.map +1 -0
- package/dist/core/PyContext.js +228 -0
- package/dist/core/PyContext.js.map +1 -0
- package/dist/core/PyIterator.d.ts +84 -0
- package/dist/core/PyIterator.d.ts.map +1 -0
- package/dist/core/PyIterator.js +243 -0
- package/dist/core/PyIterator.js.map +1 -0
- package/dist/core/PyModule.d.ts +55 -0
- package/dist/core/PyModule.d.ts.map +1 -0
- package/dist/core/PyModule.js +172 -0
- package/dist/core/PyModule.js.map +1 -0
- package/dist/core/PyProxy.d.ts +65 -0
- package/dist/core/PyProxy.d.ts.map +1 -0
- package/dist/core/PyProxy.js +483 -0
- package/dist/core/PyProxy.js.map +1 -0
- package/dist/core/PyRuntime.d.ts +105 -0
- package/dist/core/PyRuntime.d.ts.map +1 -0
- package/dist/core/PyRuntime.js +438 -0
- package/dist/core/PyRuntime.js.map +1 -0
- package/dist/env/CondaManager.d.ts +118 -0
- package/dist/env/CondaManager.d.ts.map +1 -0
- package/dist/env/CondaManager.js +401 -0
- package/dist/env/CondaManager.js.map +1 -0
- package/dist/env/PackageInstaller.d.ts +233 -0
- package/dist/env/PackageInstaller.d.ts.map +1 -0
- package/dist/env/PackageInstaller.js +609 -0
- package/dist/env/PackageInstaller.js.map +1 -0
- package/dist/env/PythonDetector.d.ts +103 -0
- package/dist/env/PythonDetector.d.ts.map +1 -0
- package/dist/env/PythonDetector.js +381 -0
- package/dist/env/PythonDetector.js.map +1 -0
- package/dist/env/VenvManager.d.ts +117 -0
- package/dist/env/VenvManager.d.ts.map +1 -0
- package/dist/env/VenvManager.js +331 -0
- package/dist/env/VenvManager.js.map +1 -0
- package/dist/index.d.ts +169 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +393 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/Plugin.interface.d.ts +41 -0
- package/dist/plugins/Plugin.interface.d.ts.map +1 -0
- package/dist/plugins/Plugin.interface.js +12 -0
- package/dist/plugins/Plugin.interface.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +26 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +174 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts +17 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.js +41 -0
- package/dist/plugins/builtin/NumpyPlugin.js.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts +19 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.js +57 -0
- package/dist/plugins/builtin/PandasPlugin.js.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts +23 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.js +50 -0
- package/dist/plugins/builtin/TorchPlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +12 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/serialization/DataFrameBridge.d.ts +141 -0
- package/dist/serialization/DataFrameBridge.d.ts.map +1 -0
- package/dist/serialization/DataFrameBridge.js +355 -0
- package/dist/serialization/DataFrameBridge.js.map +1 -0
- package/dist/serialization/MsgPackSerializer.d.ts +45 -0
- package/dist/serialization/MsgPackSerializer.d.ts.map +1 -0
- package/dist/serialization/MsgPackSerializer.js +242 -0
- package/dist/serialization/MsgPackSerializer.js.map +1 -0
- package/dist/serialization/NumpyBridge.d.ts +96 -0
- package/dist/serialization/NumpyBridge.d.ts.map +1 -0
- package/dist/serialization/NumpyBridge.js +323 -0
- package/dist/serialization/NumpyBridge.js.map +1 -0
- package/dist/serialization/Serializer.d.ts +78 -0
- package/dist/serialization/Serializer.d.ts.map +1 -0
- package/dist/serialization/Serializer.js +281 -0
- package/dist/serialization/Serializer.js.map +1 -0
- package/dist/types/PythonTypeMapper.d.ts +87 -0
- package/dist/types/PythonTypeMapper.d.ts.map +1 -0
- package/dist/types/PythonTypeMapper.js +449 -0
- package/dist/types/PythonTypeMapper.js.map +1 -0
- package/dist/types/StubCache.d.ts +109 -0
- package/dist/types/StubCache.d.ts.map +1 -0
- package/dist/types/StubCache.js +333 -0
- package/dist/types/StubCache.js.map +1 -0
- package/dist/types/TypeGenerator.d.ts +139 -0
- package/dist/types/TypeGenerator.d.ts.map +1 -0
- package/dist/types/TypeGenerator.js +372 -0
- package/dist/types/TypeGenerator.js.map +1 -0
- package/dist/types/addon.d.ts +114 -0
- package/dist/types/addon.d.ts.map +1 -0
- package/dist/types/addon.js +32 -0
- package/dist/types/addon.js.map +1 -0
- package/dist/types/config.d.ts +175 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +35 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/python.d.ts +235 -0
- package/dist/types/python.d.ts.map +1 -0
- package/dist/types/python.js +7 -0
- package/dist/types/python.js.map +1 -0
- package/dist/utils/ErrorTranslator.d.ts +83 -0
- package/dist/utils/ErrorTranslator.d.ts.map +1 -0
- package/dist/utils/ErrorTranslator.js +210 -0
- package/dist/utils/ErrorTranslator.js.map +1 -0
- package/dist/utils/Logger.d.ts +27 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +115 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/MemoryMonitor.d.ts +44 -0
- package/dist/utils/MemoryMonitor.d.ts.map +1 -0
- package/dist/utils/MemoryMonitor.js +143 -0
- package/dist/utils/MemoryMonitor.js.map +1 -0
- package/package.json +177 -0
- package/python/error_handler.py +433 -0
- package/python/nodepyx_runtime.py +575 -0
- package/python/serializer.py +379 -0
- package/python/type_inspector.py +288 -0
- package/scripts/build-native.js +68 -0
- package/scripts/download-prebuilds.js +99 -0
- package/scripts/generate-stubs.js +405 -0
- package/scripts/install.js +260 -0
- package/src/core/PyCallable.ts +137 -0
- package/src/core/PyContext.ts +296 -0
- package/src/core/PyIterator.ts +294 -0
- package/src/core/PyModule.ts +194 -0
- package/src/core/PyProxy.ts +605 -0
- package/src/core/PyRuntime.ts +504 -0
- package/src/env/CondaManager.ts +451 -0
- package/src/env/PackageInstaller.ts +738 -0
- package/src/env/PythonDetector.ts +414 -0
- package/src/env/VenvManager.ts +396 -0
- package/src/index.ts +425 -0
- package/src/native/gil_guard.cpp +26 -0
- package/src/native/gil_guard.h +175 -0
- package/src/native/nodepyx_addon.cpp +886 -0
- package/src/native/python_bridge.cpp +790 -0
- package/src/native/python_bridge.h +257 -0
- package/src/native/thread_pool.cpp +336 -0
- package/src/native/thread_pool.h +175 -0
- package/src/native/type_converter.cpp +901 -0
- package/src/native/type_converter.h +272 -0
- package/src/nextjs/PyProvider.tsx +123 -0
- package/src/nextjs/index.ts +21 -0
- package/src/nextjs/usePython.ts +106 -0
- package/src/nextjs/withnodepyx.ts +88 -0
- package/src/plugins/Plugin.interface.ts +51 -0
- package/src/plugins/PluginManager.ts +155 -0
- package/src/plugins/builtin/NumpyPlugin.ts +36 -0
- package/src/plugins/builtin/PandasPlugin.ts +49 -0
- package/src/plugins/builtin/TorchPlugin.ts +56 -0
- package/src/plugins/index.ts +7 -0
- package/src/serialization/DataFrameBridge.ts +398 -0
- package/src/serialization/MsgPackSerializer.ts +220 -0
- package/src/serialization/NumpyBridge.ts +332 -0
- package/src/serialization/Serializer.ts +320 -0
- package/src/types/PythonTypeMapper.ts +495 -0
- package/src/types/StubCache.ts +340 -0
- package/src/types/TypeGenerator.ts +491 -0
- package/src/types/addon.ts +170 -0
- package/src/types/config.ts +226 -0
- package/src/types/index.ts +55 -0
- package/src/types/python.ts +309 -0
- package/src/types/stubs/numpy.d.ts +441 -0
- package/src/types/stubs/pandas.d.ts +575 -0
- package/src/types/stubs/sklearn.d.ts +728 -0
- package/src/types/stubs/torch.d.ts +694 -0
- package/src/utils/ErrorTranslator.ts +220 -0
- package/src/utils/Logger.ts +119 -0
- package/src/utils/MemoryMonitor.ts +175 -0
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* nodepyx — PyRuntime
|
|
4
|
+
* The central manager for the Python interpreter lifecycle.
|
|
5
|
+
* Creates, configures, and shuts down the embedded CPython instance.
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.PyRuntime = void 0;
|
|
45
|
+
const path_1 = __importDefault(require("path"));
|
|
46
|
+
const addon_1 = require("../types/addon");
|
|
47
|
+
const config_1 = require("../types/config");
|
|
48
|
+
const PyProxy_1 = require("./PyProxy");
|
|
49
|
+
const PyModule_1 = require("./PyModule");
|
|
50
|
+
const PyContext_1 = require("./PyContext");
|
|
51
|
+
const Serializer_1 = require("../serialization/Serializer");
|
|
52
|
+
const TypeGenerator_1 = require("../types/TypeGenerator");
|
|
53
|
+
const PluginManager_1 = require("../plugins/PluginManager");
|
|
54
|
+
const VenvManager_1 = require("../env/VenvManager");
|
|
55
|
+
const PythonDetector_1 = require("../env/PythonDetector");
|
|
56
|
+
const PackageInstaller_1 = require("../env/PackageInstaller");
|
|
57
|
+
const MemoryMonitor_1 = require("../utils/MemoryMonitor");
|
|
58
|
+
const Logger_1 = require("../utils/Logger");
|
|
59
|
+
const ErrorTranslator_1 = require("../utils/ErrorTranslator");
|
|
60
|
+
const logger = new Logger_1.Logger('PyRuntime');
|
|
61
|
+
/**
|
|
62
|
+
* PyRuntime — manages the lifecycle of the embedded Python interpreter.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const runtime = await PyRuntime.create({
|
|
67
|
+
* virtualenv: { path: '.venv', packages: ['pandas'], autoInstall: true },
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* const pd = await runtime.import('pandas');
|
|
71
|
+
* const df = await pd.read_csv('data.csv');
|
|
72
|
+
* const result = await df.to_dict('records');
|
|
73
|
+
*
|
|
74
|
+
* await runtime.shutdown();
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
class PyRuntime {
|
|
78
|
+
_config;
|
|
79
|
+
_addon;
|
|
80
|
+
_serializer;
|
|
81
|
+
_typeGenerator;
|
|
82
|
+
_pluginManager;
|
|
83
|
+
_memoryMonitor;
|
|
84
|
+
_moduleCache = new Map();
|
|
85
|
+
_running = false;
|
|
86
|
+
constructor(config, addon) {
|
|
87
|
+
this._config = config;
|
|
88
|
+
this._addon = addon;
|
|
89
|
+
this._serializer = Serializer_1.Serializer.getInstance();
|
|
90
|
+
this._typeGenerator = new TypeGenerator_1.TypeGenerator({ stubsDir: config.stubsDir });
|
|
91
|
+
this._pluginManager = new PluginManager_1.PluginManager();
|
|
92
|
+
this._memoryMonitor = new MemoryMonitor_1.MemoryMonitor({
|
|
93
|
+
gcThreshold: this._parseBytes(config.gcThreshold),
|
|
94
|
+
});
|
|
95
|
+
this._memoryMonitor.attach(addon);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Create and initialize a PyRuntime instance.
|
|
99
|
+
*/
|
|
100
|
+
static async create(config = {}) {
|
|
101
|
+
const resolved = (0, config_1.resolveConfig)(config);
|
|
102
|
+
// Set log level
|
|
103
|
+
Logger_1.Logger.setGlobalLevel(resolved.logLevel);
|
|
104
|
+
logger.info('Creating PyRuntime...');
|
|
105
|
+
// Load the native addon
|
|
106
|
+
let addon;
|
|
107
|
+
try {
|
|
108
|
+
addon = (0, addon_1.loadNativeAddon)();
|
|
109
|
+
logger.debug('Native addon loaded');
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
logger.error('Failed to load native addon. Make sure nodepyx is built.', err);
|
|
113
|
+
throw new Error('nodepyx native addon not found. Run "npm install" or "npm run build:native".\n' +
|
|
114
|
+
`Original error: ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
const runtime = new PyRuntime(resolved, addon);
|
|
117
|
+
await runtime._initialize(config);
|
|
118
|
+
return runtime;
|
|
119
|
+
}
|
|
120
|
+
// ─── Initialization ────────────────────────────────────────────────────────
|
|
121
|
+
async _initialize(config) {
|
|
122
|
+
const startTime = performance.now();
|
|
123
|
+
// 1. Detect/setup Python environment
|
|
124
|
+
const pythonExecutable = await this._setupPythonEnvironment(config);
|
|
125
|
+
// 2. Initialize Python interpreter via C++ addon
|
|
126
|
+
logger.debug(`Initializing Python interpreter: ${pythonExecutable}`);
|
|
127
|
+
await this._addon.initializePython({
|
|
128
|
+
pythonHome: this._config.pythonHome || '',
|
|
129
|
+
pythonExecutable,
|
|
130
|
+
threadPoolSize: this._config.threadPoolSize,
|
|
131
|
+
maxQueueSize: this._config.maxQueueSize,
|
|
132
|
+
gilReleaseInterval: this._config.gil.releaseInterval,
|
|
133
|
+
callTimeout: this._config.callTimeout,
|
|
134
|
+
pythonPathExtra: [
|
|
135
|
+
path_1.default.join(__dirname, '..', '..', 'python'),
|
|
136
|
+
...this._config.pythonPathExtra,
|
|
137
|
+
],
|
|
138
|
+
env: this._config.env,
|
|
139
|
+
enableProfiling: this._config.profilingEnabled,
|
|
140
|
+
});
|
|
141
|
+
logger.debug('Python interpreter initialized');
|
|
142
|
+
// 3. Bootstrap Python runtime helpers
|
|
143
|
+
await this._bootstrapPythonRuntime();
|
|
144
|
+
// 4. Register built-in plugins
|
|
145
|
+
await this._pluginManager.registerBuiltins();
|
|
146
|
+
// 5. Start memory monitoring
|
|
147
|
+
this._memoryMonitor.startMonitoring(10000);
|
|
148
|
+
this._running = true;
|
|
149
|
+
const elapsed = (performance.now() - startTime).toFixed(0);
|
|
150
|
+
logger.success(`PyRuntime ready in ${elapsed}ms (Python: ${pythonExecutable})`);
|
|
151
|
+
}
|
|
152
|
+
async _setupPythonEnvironment(config) {
|
|
153
|
+
let pythonExecutable = this._config.pythonExecutable;
|
|
154
|
+
if (config.conda) {
|
|
155
|
+
// Conda environment
|
|
156
|
+
const { CondaManager } = await Promise.resolve().then(() => __importStar(require('../env/CondaManager')));
|
|
157
|
+
const condaManager = new CondaManager({ conda: config.conda });
|
|
158
|
+
pythonExecutable = await condaManager.getPythonExecutable(config.conda.envName) ?? pythonExecutable;
|
|
159
|
+
logger.info(`Using conda environment: ${config.conda.envName}`);
|
|
160
|
+
}
|
|
161
|
+
else if (config.virtualenv) {
|
|
162
|
+
// Virtualenv
|
|
163
|
+
const venvManager = new VenvManager_1.VenvManager({ virtualenv: config.virtualenv });
|
|
164
|
+
const venvResult = await venvManager.setup();
|
|
165
|
+
pythonExecutable = typeof venvResult === 'string' ? venvResult : venvResult.pythonExecutable ?? pythonExecutable;
|
|
166
|
+
logger.info(`Using virtualenv: ${config.virtualenv.path}`);
|
|
167
|
+
}
|
|
168
|
+
else if (config.pythonPath) {
|
|
169
|
+
// Explicit Python path
|
|
170
|
+
pythonExecutable = config.pythonPath;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// Auto-detect
|
|
174
|
+
const detector = new PythonDetector_1.PythonDetector();
|
|
175
|
+
try {
|
|
176
|
+
const detected = await detector.detect();
|
|
177
|
+
pythonExecutable = detected.executable;
|
|
178
|
+
logger.info(`Auto-detected Python: ${detected.executable} (${detected.version})`);
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
logger.warn('No Python detected — using system default "python3"');
|
|
182
|
+
pythonExecutable = 'python3';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return pythonExecutable;
|
|
186
|
+
}
|
|
187
|
+
async _bootstrapPythonRuntime() {
|
|
188
|
+
try {
|
|
189
|
+
// Initialize nodepyx Python runtime helpers
|
|
190
|
+
const bootstrapCode = `
|
|
191
|
+
import sys
|
|
192
|
+
import os
|
|
193
|
+
|
|
194
|
+
# Add nodepyx runtime to path
|
|
195
|
+
_nodepyx_runtime_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'python')
|
|
196
|
+
if _nodepyx_runtime_dir not in sys.path:
|
|
197
|
+
sys.path.insert(0, _nodepyx_runtime_dir)
|
|
198
|
+
|
|
199
|
+
# Initialize runtime
|
|
200
|
+
try:
|
|
201
|
+
import nodepyx_runtime
|
|
202
|
+
nodepyx_runtime.initialize()
|
|
203
|
+
except ImportError:
|
|
204
|
+
pass # Runtime helpers not available, basic operation only
|
|
205
|
+
`;
|
|
206
|
+
await this._addon.runPythonCode(bootstrapCode);
|
|
207
|
+
logger.debug('Python runtime helpers bootstrapped');
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
// Non-fatal — runtime helpers are optional
|
|
211
|
+
logger.warn('Failed to bootstrap Python runtime helpers', err);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ─── Module Import ──────────────────────────────────────────────────────────
|
|
215
|
+
/**
|
|
216
|
+
* Import a Python module and return a PyProxy.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const pd = await runtime.import('pandas');
|
|
221
|
+
* const df = await pd.read_csv('data.csv');
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
async import(moduleName) {
|
|
225
|
+
this._ensureRunning();
|
|
226
|
+
// Check cache
|
|
227
|
+
if (this._moduleCache.has(moduleName)) {
|
|
228
|
+
return this._moduleCache.get(moduleName);
|
|
229
|
+
}
|
|
230
|
+
logger.debug(`Importing Python module: ${moduleName}`);
|
|
231
|
+
const result = await this._addon.importModule(moduleName);
|
|
232
|
+
if (!result.success) {
|
|
233
|
+
if (result.error) {
|
|
234
|
+
throw (0, ErrorTranslator_1.translatePythonError)({
|
|
235
|
+
type: result.error.type,
|
|
236
|
+
message: result.error.message,
|
|
237
|
+
traceback: result.error.traceback || '',
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
throw new Error(`Failed to import Python module '${moduleName}'`);
|
|
241
|
+
}
|
|
242
|
+
if (!result.objectId) {
|
|
243
|
+
throw new Error(`Module '${moduleName}' imported but no object ID returned`);
|
|
244
|
+
}
|
|
245
|
+
// Run plugin hooks
|
|
246
|
+
await this._pluginManager.onModuleImported(moduleName, result.objectId);
|
|
247
|
+
// Create PyModule
|
|
248
|
+
const module = PyModule_1.PyModule.fromRef(result.objectId, moduleName, this._addon, this._config.callTimeout);
|
|
249
|
+
// Generate TypeScript stubs (background, non-blocking)
|
|
250
|
+
// TypeScript stub generation (non-blocking, background)
|
|
251
|
+
if (this._config.proxyCache) {
|
|
252
|
+
this._typeGenerator.generateStub(moduleName, { name: moduleName, functions: [], classes: [], constants: [], submodules: [] }).catch((err) => {
|
|
253
|
+
logger.debug(`Stub generation for ${moduleName} failed (non-fatal)`, err);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
// Cache
|
|
257
|
+
this._moduleCache.set(moduleName, module);
|
|
258
|
+
logger.debug(`Module '${moduleName}' imported (id=${result.objectId})`);
|
|
259
|
+
return module;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Import multiple modules at once (concurrent).
|
|
263
|
+
*/
|
|
264
|
+
async importAll(moduleNames) {
|
|
265
|
+
const modules = await Promise.all(moduleNames.map(async (name) => [name, await this.import(name)]));
|
|
266
|
+
return Object.fromEntries(modules);
|
|
267
|
+
}
|
|
268
|
+
// ─── Code Execution ────────────────────────────────────────────────────────
|
|
269
|
+
/**
|
|
270
|
+
* Evaluate a Python expression.
|
|
271
|
+
*/
|
|
272
|
+
async eval(expression) {
|
|
273
|
+
this._ensureRunning();
|
|
274
|
+
const result = await this._addon.evalPython(expression);
|
|
275
|
+
if (!result.success) {
|
|
276
|
+
if (result.error) {
|
|
277
|
+
throw (0, ErrorTranslator_1.translatePythonError)({
|
|
278
|
+
type: result.error.type,
|
|
279
|
+
message: result.error.message,
|
|
280
|
+
traceback: result.error.traceback || '',
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
throw new Error('Python eval failed');
|
|
284
|
+
}
|
|
285
|
+
if (result.isObject && result.objectId) {
|
|
286
|
+
return PyProxy_1.PyProxy._createFromObjectId(result.objectId, [], this._addon, this._config.callTimeout);
|
|
287
|
+
}
|
|
288
|
+
if (result.resultJson !== undefined) {
|
|
289
|
+
try {
|
|
290
|
+
return JSON.parse(result.resultJson);
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return result.resultJson;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Execute Python statements.
|
|
300
|
+
*/
|
|
301
|
+
async exec(code) {
|
|
302
|
+
this._ensureRunning();
|
|
303
|
+
const result = await this._addon.runPythonCode(code);
|
|
304
|
+
if (!result.success && result.error) {
|
|
305
|
+
throw (0, ErrorTranslator_1.translatePythonError)({
|
|
306
|
+
type: result.error.type,
|
|
307
|
+
message: result.error.message,
|
|
308
|
+
traceback: result.error.traceback || '',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Run a Python script file.
|
|
314
|
+
*/
|
|
315
|
+
async runFile(filePath) {
|
|
316
|
+
this._ensureRunning();
|
|
317
|
+
const result = await this._addon.runPythonFile(filePath);
|
|
318
|
+
if (!result.success) {
|
|
319
|
+
if (result.error) {
|
|
320
|
+
throw (0, ErrorTranslator_1.translatePythonError)({
|
|
321
|
+
type: result.error.type,
|
|
322
|
+
message: result.error.message,
|
|
323
|
+
traceback: result.error.traceback || '',
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
throw new Error('Failed to run Python file');
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
// ─── Context Management ─────────────────────────────────────────────────────
|
|
331
|
+
/**
|
|
332
|
+
* Create an isolated Python execution context.
|
|
333
|
+
*/
|
|
334
|
+
async createContext() {
|
|
335
|
+
this._ensureRunning();
|
|
336
|
+
return PyContext_1.PyContext.create(this._addon);
|
|
337
|
+
}
|
|
338
|
+
// ─── Package Management ────────────────────────────────────────────────────
|
|
339
|
+
/**
|
|
340
|
+
* Install Python packages into the active environment.
|
|
341
|
+
*/
|
|
342
|
+
async installPackages(packages) {
|
|
343
|
+
this._ensureRunning();
|
|
344
|
+
const installer = new PackageInstaller_1.PackageInstaller({ pythonExecutable: this._config.pythonExecutable });
|
|
345
|
+
await installer.install(packages);
|
|
346
|
+
// Clear module cache so re-imports work
|
|
347
|
+
this._moduleCache.clear();
|
|
348
|
+
}
|
|
349
|
+
// ─── Memory Management ─────────────────────────────────────────────────────
|
|
350
|
+
/**
|
|
351
|
+
* Get current memory statistics.
|
|
352
|
+
*/
|
|
353
|
+
getMemoryStats() {
|
|
354
|
+
this._ensureRunning();
|
|
355
|
+
return this._addon.getMemoryStats();
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Trigger Python garbage collection.
|
|
359
|
+
*/
|
|
360
|
+
async collectGarbage() {
|
|
361
|
+
this._ensureRunning();
|
|
362
|
+
await this._addon.collectGarbage();
|
|
363
|
+
}
|
|
364
|
+
// ─── Direct Addon Access ───────────────────────────────────────────────────
|
|
365
|
+
/**
|
|
366
|
+
* Get the underlying native addon.
|
|
367
|
+
* Advanced use only.
|
|
368
|
+
*/
|
|
369
|
+
getAddon() {
|
|
370
|
+
return this._addon;
|
|
371
|
+
}
|
|
372
|
+
// ─── State ─────────────────────────────────────────────────────────────────
|
|
373
|
+
isRunning() {
|
|
374
|
+
return this._running;
|
|
375
|
+
}
|
|
376
|
+
getConfig() {
|
|
377
|
+
return { ...this._config };
|
|
378
|
+
}
|
|
379
|
+
// ─── Shutdown ──────────────────────────────────────────────────────────────
|
|
380
|
+
/**
|
|
381
|
+
* Gracefully shut down the Python runtime.
|
|
382
|
+
* Releases all Python objects and finalizes the interpreter.
|
|
383
|
+
*/
|
|
384
|
+
async shutdown() {
|
|
385
|
+
if (!this._running) {
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
logger.info('Shutting down PyRuntime...');
|
|
389
|
+
this._running = false;
|
|
390
|
+
// Stop memory monitoring
|
|
391
|
+
this._memoryMonitor.stopMonitoring();
|
|
392
|
+
// Clear caches
|
|
393
|
+
this._moduleCache.clear();
|
|
394
|
+
// Finalize Python interpreter
|
|
395
|
+
try {
|
|
396
|
+
await this._addon.finalizePython();
|
|
397
|
+
logger.success('PyRuntime shut down');
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
logger.error('Error during Python finalization', err);
|
|
401
|
+
throw err;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Synchronous shutdown (for process.on('exit') handler).
|
|
406
|
+
* Best-effort only — may not complete all cleanup.
|
|
407
|
+
*/
|
|
408
|
+
shutdownSync() {
|
|
409
|
+
if (!this._running) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
this._running = false;
|
|
413
|
+
this._memoryMonitor.stopMonitoring();
|
|
414
|
+
this._moduleCache.clear();
|
|
415
|
+
// Cannot await here — best effort
|
|
416
|
+
logger.debug('Synchronous shutdown initiated');
|
|
417
|
+
}
|
|
418
|
+
// ─── Private Helpers ───────────────────────────────────────────────────────
|
|
419
|
+
_ensureRunning() {
|
|
420
|
+
if (!this._running) {
|
|
421
|
+
throw new ErrorTranslator_1.nodepyxShutdownError('PyRuntime has been shut down. Create a new runtime with PyRuntime.create().');
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
_parseBytes(str) {
|
|
425
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)?$/i);
|
|
426
|
+
if (!match) {
|
|
427
|
+
return 1_073_741_824;
|
|
428
|
+
}
|
|
429
|
+
const value = parseFloat(match[1]);
|
|
430
|
+
const unit = (match[2] ?? 'B').toUpperCase();
|
|
431
|
+
const units = {
|
|
432
|
+
B: 1, KB: 1024, MB: 1024 ** 2, GB: 1024 ** 3, TB: 1024 ** 4,
|
|
433
|
+
};
|
|
434
|
+
return Math.floor(value * (units[unit] ?? 1));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
exports.PyRuntime = PyRuntime;
|
|
438
|
+
//# sourceMappingURL=PyRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PyRuntime.js","sourceRoot":"","sources":["../../src/core/PyRuntime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodepyx — CondaManager
|
|
3
|
+
* Manages Conda environments for Python package isolation.
|
|
4
|
+
*
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Detecting an existing conda environment by name
|
|
7
|
+
* - Creating new conda environments
|
|
8
|
+
* - Installing packages into a conda environment (conda + pip fallback)
|
|
9
|
+
* - Returning the Python executable path inside a conda env
|
|
10
|
+
*
|
|
11
|
+
* Detection order for conda executable:
|
|
12
|
+
* 1. CONDA_EXE environment variable
|
|
13
|
+
* 2. MAMBA_EXE (uses mamba as a drop-in replacement)
|
|
14
|
+
* 3. condaPath from config
|
|
15
|
+
* 4. 'conda' on PATH
|
|
16
|
+
* 5. Common installation locations
|
|
17
|
+
*/
|
|
18
|
+
import type { CondaConfig } from '../types/config';
|
|
19
|
+
export interface CondaEnvInfo {
|
|
20
|
+
/** Environment name */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Absolute prefix path of the environment */
|
|
23
|
+
prefix: string;
|
|
24
|
+
/** Python executable inside the env */
|
|
25
|
+
pythonExecutable: string;
|
|
26
|
+
/** Whether this is the currently active environment */
|
|
27
|
+
isActive: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface CondaSetupResult {
|
|
30
|
+
/** Absolute path to Python executable */
|
|
31
|
+
pythonExecutable: string;
|
|
32
|
+
/** Whether the env was newly created */
|
|
33
|
+
created: boolean;
|
|
34
|
+
/** Whether packages were installed */
|
|
35
|
+
packagesInstalled: boolean;
|
|
36
|
+
/** Environment info */
|
|
37
|
+
envInfo: CondaEnvInfo;
|
|
38
|
+
}
|
|
39
|
+
export interface CondaManagerOptions {
|
|
40
|
+
/** Conda config from nodepyxConfig */
|
|
41
|
+
conda: CondaConfig;
|
|
42
|
+
/** Timeout for conda operations (ms). Default: 300000 (5 min) */
|
|
43
|
+
timeout?: number;
|
|
44
|
+
/** Use mamba instead of conda if available. Default: true */
|
|
45
|
+
preferMamba?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* CondaManager — manages Conda environments.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const manager = new CondaManager({
|
|
53
|
+
* conda: {
|
|
54
|
+
* envName: 'my-ml-env',
|
|
55
|
+
* packages: ['numpy', 'pandas', 'scikit-learn'],
|
|
56
|
+
* channels: ['conda-forge', 'defaults'],
|
|
57
|
+
* }
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* const result = await manager.setup();
|
|
61
|
+
* console.log(result.pythonExecutable); // /opt/conda/envs/my-ml-env/bin/python3
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare class CondaManager {
|
|
65
|
+
private readonly _config;
|
|
66
|
+
private readonly _timeout;
|
|
67
|
+
private readonly _preferMamba;
|
|
68
|
+
private _condaExec;
|
|
69
|
+
constructor(options: CondaManagerOptions);
|
|
70
|
+
/**
|
|
71
|
+
* Set up the Conda environment.
|
|
72
|
+
* Creates the environment if it doesn't exist, then installs packages.
|
|
73
|
+
*/
|
|
74
|
+
setup(): Promise<CondaSetupResult>;
|
|
75
|
+
/**
|
|
76
|
+
* List all conda environments.
|
|
77
|
+
*/
|
|
78
|
+
listEnvironments(): Promise<CondaEnvInfo[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if a conda environment exists.
|
|
81
|
+
*/
|
|
82
|
+
environmentExists(envName: string): Promise<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Get the Python executable for a conda environment.
|
|
85
|
+
*/
|
|
86
|
+
getPythonExecutable(envName: string): Promise<string | null>;
|
|
87
|
+
/**
|
|
88
|
+
* Install packages into an existing environment.
|
|
89
|
+
*/
|
|
90
|
+
installPackages(envName: string, packages: string[]): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Remove a conda environment.
|
|
93
|
+
*/
|
|
94
|
+
removeEnvironment(envName: string): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Return the conda executable path (or null if not found).
|
|
97
|
+
*/
|
|
98
|
+
get condaExecutable(): string | null;
|
|
99
|
+
private _findCondaExecutable;
|
|
100
|
+
private _ensureCondaExec;
|
|
101
|
+
private _findEnv;
|
|
102
|
+
private _getEnvInfo;
|
|
103
|
+
private _createEnv;
|
|
104
|
+
private _installPackages;
|
|
105
|
+
private _pythonInPrefix;
|
|
106
|
+
private _which;
|
|
107
|
+
}
|
|
108
|
+
export declare class CondaNotFoundError extends Error {
|
|
109
|
+
constructor(message: string);
|
|
110
|
+
}
|
|
111
|
+
export declare class CondaEnvError extends Error {
|
|
112
|
+
constructor(message: string);
|
|
113
|
+
}
|
|
114
|
+
export declare class CondaPackageInstallError extends Error {
|
|
115
|
+
readonly packages: string[];
|
|
116
|
+
constructor(packages: string[], detail: string);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=CondaManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CondaManager.d.ts","sourceRoot":"","sources":["../../src/env/CondaManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAMnD,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB;IACvB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,KAAK,EAAE,WAAW,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,UAAU,CAAuB;gBAE7B,OAAO,EAAE,mBAAmB;IAQxC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA6CxC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAmCjD;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1D;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKlE;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzE;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAevD;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,GAAG,IAAI,CAEnC;IAID,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,gBAAgB;YAMV,QAAQ;YAUR,WAAW;YASX,UAAU;YA8BV,gBAAgB;IAmE9B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,MAAM;CASf;AAID,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAChB,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM;CAK/C"}
|