Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions example/python_shell_example.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import "package:python_shell/python_shell.dart";

void main() async {
// 현재 스타일
// 현재 스타일
// var shell = PythonShell(shellConfig: PythonShellConfig(
// pythonRequires: [ "PySide6" ],
// defaultWorkingDirectory: "example"
Expand All @@ -20,17 +20,20 @@ void main() async {
// }
// ));

var shell = PythonShell(PythonShellConfig());
await shell.initialize();
var shell = PythonShell(PythonShellConfig());
await shell.initialize();

var instance = ShellManager.getInstance("default");
instance.installRequires([ "PySide6" ]);
await instance.runString("""
var instance = ShellManager.getInstance("default");
instance.installRequires(["PySide6"]);
await instance.runString(
"""
import os, PySide6

print("in python: ", os.getcwd())
print("in python: ", PySide6)
""", echo: true);
""",
echo: true,
);

print("finished");
print("finished");
}
48 changes: 23 additions & 25 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@

import "dart:io";
import "package:path/path.dart" as path;

import "package:path/path.dart" as path;

String appDir = path.join(Platform.environment[Platform.isWindows ? "USERPROFILE" : "HOME"]!, ".python_shell.dart");
String appDir = path.join(
Platform.environment[Platform.isWindows ? "USERPROFILE" : "HOME"]!,
".python_shell.dart");
String tempDir = path.join(appDir, "temp");
String instanceDir = path.join(appDir, "instances");

String defaultPythonVersion = "3.9.13";
String defaultPythonPath = "python3";

String checkPythonVersion(String rawPythonVersion) {
String realPythonVersion = "3.9.13";
String realPythonVersion = "3.9.13";

var versions = rawPythonVersion.split(".");
if (versions.length == 3) {
if (rawPythonVersion.endsWith(".")) {
if (versions.last != "") {
versions.removeLast();
realPythonVersion = versions.join(".");
}
}
else {
realPythonVersion = rawPythonVersion;
}
var versions = rawPythonVersion.split(".");
if (versions.length == 3) {
if (rawPythonVersion.endsWith(".")) {
if (versions.last != "") {
versions.removeLast();
realPythonVersion = versions.join(".");
}
} else {
realPythonVersion = rawPythonVersion;
}
else if (versions.length == 2) {
if (rawPythonVersion.endsWith(".")) {
if (versions.last != "") {
realPythonVersion = "${versions.join(".")}.0";
}
}
else {
realPythonVersion = "$rawPythonVersion.0";
}
} else if (versions.length == 2) {
if (rawPythonVersion.endsWith(".")) {
if (versions.last != "") {
realPythonVersion = "${versions.join(".")}.0";
}
} else {
realPythonVersion = "$rawPythonVersion.0";
}
}

return realPythonVersion;
return realPythonVersion;
}
192 changes: 118 additions & 74 deletions lib/src/python_shell.dart
Original file line number Diff line number Diff line change
@@ -1,98 +1,142 @@

import "dart:io";

import "package:path/path.dart" as path;
import "package:dio/dio.dart";
import "package:archive/archive_io.dart";
import "package:dio/dio.dart";
import "package:path/path.dart" as path;

import "config.dart" as config;
import "listener.dart";
import "shell/manager.dart";
import "shell/instance.dart";

import "shell/manager.dart";

/// PythonShell Class
class PythonShell {
PythonShell(PythonShellConfig shellConfig);

void clear() => ShellManager.clear();

Future<void> initialize() async {
print("Initializing shell...");
config.defaultPythonVersion = config.checkPythonVersion(config.defaultPythonVersion);
if (!Directory(config.appDir).existsSync()) Directory(config.appDir).createSync();
if (!Directory(config.instanceDir).existsSync()) Directory(config.instanceDir).createSync();
if (!Directory(config.tempDir).existsSync()) Directory(config.tempDir).createSync();

String pythonDir = "";
if (Platform.isWindows) {
print("Check default python binary files...");
pythonDir = path.join(config.appDir, "python");
if (!Directory(pythonDir).existsSync()) {
String pythonBinaryFile = path.join(config.tempDir, "python.zip");
await Dio().download("https://www.python.org/ftp/python/${config.defaultPythonVersion}/python-${config.defaultPythonVersion}-embed-amd64.zip", pythonBinaryFile);
await extractFileToDisk(pythonBinaryFile, pythonDir);
File(pythonBinaryFile).deleteSync();

String pythonPthFile = path.join(pythonDir, "python${config.defaultPythonVersion.replaceAll(".${config.defaultPythonVersion.split(".").last}", "").replaceAll(".", "")}._pth");
File(pythonPthFile).writeAsStringSync(File(pythonPthFile).readAsStringSync().replaceAll("#import site", "import site"));
}
print("Python check finished.");

config.defaultPythonPath = path.join(pythonDir, "python.exe");
}

if (File(config.defaultPythonPath).existsSync()) {
print("Default settings for virtualenv...");
var result = Process.runSync(config.defaultPythonPath, [ "-m", "pip", "install", "pip", "--upgrade" ]);
if (result.stderr.toString().trim() != "") {
String pipInstallFile = path.join(config.tempDir, "get-pip.py");
await Dio().download("https://bootstrap.pypa.io/pip/get-pip.py", pipInstallFile);
Process.runSync(config.defaultPythonPath, [ pipInstallFile ]);
File(pipInstallFile).deleteSync();
}

Process.runSync(config.defaultPythonPath, [ "-m", "pip", "install", "virtualenv", "--upgrade" ]);
print("Virtualenv settings finished.");
}
PythonShell(PythonShellConfig shellConfig);

void clear() => ShellManager.clear();

Future<void> initialize() async {
print("Initializing shell...");
config.defaultPythonVersion =
config.checkPythonVersion(config.defaultPythonVersion);
if (!Directory(config.appDir).existsSync())
Directory(config.appDir).createSync();
if (!Directory(config.instanceDir).existsSync())
Directory(config.instanceDir).createSync();
if (!Directory(config.tempDir).existsSync())
Directory(config.tempDir).createSync();

String pythonDir = "";
if (Platform.isWindows) {
print("Check default python binary files...");
pythonDir = path.join(config.appDir, "python");
if (!Directory(pythonDir).existsSync()) {
String pythonBinaryFile = path.join(config.tempDir, "python.zip");
await Dio().download(
"https://www.python.org/ftp/python/${config.defaultPythonVersion}/python-${config.defaultPythonVersion}-embed-amd64.zip",
pythonBinaryFile);
await extractFileToDisk(pythonBinaryFile, pythonDir);
File(pythonBinaryFile).deleteSync();

String pythonPthFile = path.join(pythonDir,
"python${config.defaultPythonVersion.replaceAll(".${config.defaultPythonVersion.split(".").last}", "").replaceAll(".", "")}._pth");
File(pythonPthFile).writeAsStringSync(File(pythonPthFile)
.readAsStringSync()
.replaceAll("#import site", "import site"));
}
print("Python check finished.");

config.defaultPythonPath = path.join(pythonDir, "python.exe");
}

String defaultEnvDir = path.join(config.instanceDir, "default");
if (!Directory(defaultEnvDir).existsSync()) {
print("Creating default env...");
ShellManager.createInstance(instanceName: "default");
print("Default env created.");
if (File(config.defaultPythonPath).existsSync()) {
print("Default settings for virtualenv...");
var result = Process.runSync(config.defaultPythonPath,
["-m", "pip", "install", "pip", "--upgrade"]);
if (result.exitCode != 0) {
print('Error for result, exist code ${result.exitCode}\n'
'Stdout: ${result.stdout}\nStderr: ${result.stderr}');
}

if (result.stderr.toString().trim() != "") {
String pipInstallFile = path.join(config.tempDir, "get-pip.py");
await Dio().download(
"https://bootstrap.pypa.io/pip/get-pip.py", pipInstallFile);
ProcessResult pipInstallFileProcess =
Process.runSync(config.defaultPythonPath, [pipInstallFile]);
if (pipInstallFileProcess.exitCode != 0) {
print(
'Error for pipInstallFile, exist code ${pipInstallFileProcess.exitCode}\n'
'Stdout: ${pipInstallFileProcess.stdout}\nStderr: ${pipInstallFileProcess.stderr}');
}

print("Shell initialized.");
File(pipInstallFile).deleteSync();
}

ProcessResult virtualEnvUpgrade = Process.runSync(
config.defaultPythonPath,
["-m", "pip", "install", "virtualenv", "--upgrade"]);
if (virtualEnvUpgrade.exitCode != 0) {
print(
'Error for virtualEnvUpgrade, exist code ${virtualEnvUpgrade.exitCode}\n'
'Stdout: ${virtualEnvUpgrade.stdout}\nStderr: ${virtualEnvUpgrade.stderr}');
}

print("Virtualenv settings finished.");
}

Future<void> runFile(String pythonFile, { ShellInstance? instance, String? workingDirectory, ShellListener? listener, bool echo = true }) async {
instance = instance ?? ShellManager.getInstance("default");
await instance.runFile(pythonFile, workingDirectory: workingDirectory, listener: listener, echo: echo);
String defaultEnvDir = path.join(config.instanceDir, "default");
if (!Directory(defaultEnvDir).existsSync()) {
print("Creating default env...");
ShellManager.createInstance(instanceName: "default");
print("Default env created.");
}

Future<void> runString(String pythonCode, { ShellInstance? instance, String? workingDirectory, ShellListener? listener, bool echo = true }) async {
instance = instance ?? ShellManager.getInstance("default");
await instance.runString(pythonCode, workingDirectory: workingDirectory, listener: listener, echo: echo);
}
print("Shell initialized.");
}

Future<void> runFile(
String pythonFile, {
ShellInstance? instance,
String? workingDirectory,
ShellListener? listener,
bool echo = true,
}) async {
instance = instance ?? ShellManager.getInstance("default");
await instance.runFile(pythonFile,
workingDirectory: workingDirectory, listener: listener, echo: echo);
}

Future<void> runString(
String pythonCode, {
List<String> arguments = const [],
ShellInstance? instance,
String? workingDirectory,
ShellListener? listener,
bool echo = true,
}) async {
instance = instance ?? ShellManager.getInstance("default");
await instance.runString(pythonCode,
arguments: arguments,
workingDirectory: workingDirectory,
listener: listener,
echo: echo);
}
}

/// PythonShell Configuration Class
/// * [defaultPythonPath]: Default python path to use
/// * [defaultPythonVersion]: Default python version to use
class PythonShellConfig {

PythonShellConfig({
defaultPythonPath = "python3",
defaultPythonVersion = "3.9.13",
}) {
if ((Platform.isLinux || Platform.isMacOS)) {
if (["python", "python2", "python3"].contains(defaultPythonPath)) {
config.defaultPythonPath = "/usr/bin/$defaultPythonPath";
}
else if (!File(defaultPythonPath).existsSync()) {
config.defaultPythonPath = "/usr/bin/python3";
}
}
PythonShellConfig({
defaultPythonPath = "python3",
defaultPythonVersion = "3.9.13",
}) {
if ((Platform.isLinux || Platform.isMacOS)) {
if (["python", "python2", "python3"].contains(defaultPythonPath)) {
config.defaultPythonPath = "/usr/bin/$defaultPythonPath";
} else if (!File(defaultPythonPath).existsSync()) {
config.defaultPythonPath = "/usr/bin/python3";
}
}
}
}
Loading