init static method

Future<void> init({
  1. String pythonExecutable = 'python',
  2. String scriptPath = 'dart_python_bridge/example_worker.py',
  3. Duration startupTimeout = const Duration(seconds: 5),
  4. Map<String, String>? environment,
  5. String? workingDirectory,
})

Start the Python worker process.

Implementation

static Future<void> init({
  String pythonExecutable = 'python',
  String scriptPath = 'dart_python_bridge/example_worker.py',
  Duration startupTimeout = const Duration(seconds: 5),
  Map<String, String>? environment,
  String? workingDirectory,
}) async {
  _ensureDefaults();
  if (_initialized) {
    return;
  }

  _process = await Process.start(
    pythonExecutable,
    [scriptPath],
    environment: environment,
    workingDirectory: workingDirectory,
    runInShell: false,
  );

  final handshakeCompleter = Completer<Map<String, dynamic>>();
  final handshakeBuffer = <int>[];
  var handshakeComplete = false;
  _stdoutBytesSub = _process!.stdout.listen((chunk) {
    if (!handshakeComplete) {
      final newlineIndex = chunk.indexOf(0x0A);
      if (newlineIndex == -1) {
        handshakeBuffer.addAll(chunk);
        return;
      }
      handshakeBuffer.addAll(chunk.sublist(0, newlineIndex));
      final handshakeLine = utf8.decode(_trimCarriageReturn(handshakeBuffer));
      final handshake = jsonDecode(handshakeLine) as Map<String, dynamic>;
      handshakeCompleter.complete(handshake);
      handshakeComplete = true;
      final remaining = chunk.sublist(newlineIndex + 1);
      if (remaining.isNotEmpty) {
        _stdoutBuffer.addAll(remaining);
        _drainFrames();
      }
      return;
    }

    _stdoutBuffer.addAll(chunk);
    _drainFrames();
  }, onDone: () {
    _failAll(BridgeException('Python worker stdout closed unexpectedly'));
  }, onError: (Object error, StackTrace stackTrace) {
    _stderrController.sink.add('Bridge stdout error: $error\n$stackTrace');
    _failAll(BridgeException('Python worker stdout error', details: {
      'error': error.toString(),
    }));
  });

  _stderrSub = _process!.stderr
      .transform(utf8.decoder)
      .transform(const LineSplitter())
      .listen(_stderrController.sink.add);

  final handshake = await handshakeCompleter.future.timeout(startupTimeout);
  _handshake = handshake;
  _selectCodec(handshake);

  _process!.exitCode.then((code) {
    _stderrController.sink.add('Python worker exited with code $code');
    _failAll(
        BridgeException('Python worker exited', details: {'code': code}));
    _initialized = false;
  });

  _initialized = true;
}