How to import python package in flutter using Starflut?
Question:
I’m building an app with Flutter and I need to use some Python code. For that I use the Starflut plugin (https://pub.dev/packages/starflut). I succeed to run the Python code, no issue here, but I want to import extra package.
To do so, I created a virtual environment where my app is located, then I downloaded by the pip installer numpy, cv2 and Pillow, still no issue there, the downloading went fine.
But, when I try to import numpy for example, my IDE (Visual Studio Code) tell me that there’s an error :
Unable to import 'numpy'
So here’s my main.dart code (the only dart file, it’s a test app):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:starflut/starflut.dart';
void main() => runApp(Main());
class Main extends StatefulWidget {
@override
_MainState createState() => _MainState();
}
class _MainState extends State<Main> {
var _outputString = '';
StarSrvGroupClass srvGroup;
dynamic python;
_MainState() {
_initStarCore();
}
void showOutput(String info) async {
if (info == null || info.length == 0) return;
_outputString = info;
setState(() {});
}
void _initStarCore() async {
StarCoreFactory starcore = await Starflut.getFactory();
StarServiceClass service =
await starcore.initSimple("test", "123", 0, 0, []);
String resPath = await Starflut.getResourcePath();
await starcore.regMsgCallBackP(
(int serviceGroupID, int uMsg, Object wParam, Object lParam) async {
if (uMsg == Starflut.MSG_DISPMSG || uMsg == Starflut.MSG_DISPLUAMSG) {
showOutput(wParam);
}
print("$serviceGroupID $uMsg $wParam $lParam");
return null;
});
srvGroup = await service["_ServiceGroup"];
bool isAndroid = await Starflut.isAndroid();
if (isAndroid == true) {
String libraryDir = await Starflut.getNativeLibraryDir();
String docPath = await Starflut.getDocumentPath();
if (libraryDir.indexOf("arm64") > 0) {
Starflut.unzipFromAssets("lib-dynload-arm64.zip", docPath, true);
} else if (libraryDir.indexOf("x86_64") > 0) {
Starflut.unzipFromAssets("lib-dynload-x86_64.zip", docPath, true);
} else if (libraryDir.indexOf("arm") > 0) {
Starflut.unzipFromAssets("lib-dynload-armeabi.zip", docPath, true);
} else {
//x86
Starflut.unzipFromAssets("lib-dynload-x86.zip", docPath, true);
}
await Starflut.copyFileFromAssets("python3.6.zip",
"flutter_assets/starfiles", null); //desRelatePath must be null
await Starflut.copyFileFromAssets(
"program.py", "flutter_assets/starfiles", "flutter_assets/starfiles");
}
if (await srvGroup.initRaw("python36", service) == true) {
_outputString = "init starcore and python 3.6 successfully";
} else {
_outputString = "init starcore and python 3.6 failed";
}
await srvGroup.loadRawModule("python", "",
resPath + "/flutter_assets/starfiles/" + "program.py", false);
python = await service.importRawContext("python", "", false, "");
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
//_counter++;
});
}
void runScriptCode() async {
var result = await python.call("multiply", [5, 2]);
_outputString = result.toString();
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: FlatButton(
color: Colors.red,
child: Text(_outputString),
onPressed: () {
runScriptCode();
},
),
),
),
);
}
}
and my Python file:
import numpy as np # (to test)
def multiply(a, b):
return a*b
Here’s my tree structure if it can help:
The tree structure of my Flutter project
Hopping you can help me.
Thanks in advance !
Answers:
If you can, connect python backend to flutter because with that there will be smoothness in your app.
You can use chaquopy plugin for flutter, if you want to integrate python packages inside your android app.
Android Flutter Only: As of last month, Chaquopy is now open-source and has a Flutter plug-in. So that would definitely be easiest way to include python code
I’m building an app with Flutter and I need to use some Python code. For that I use the Starflut plugin (https://pub.dev/packages/starflut). I succeed to run the Python code, no issue here, but I want to import extra package.
To do so, I created a virtual environment where my app is located, then I downloaded by the pip installer numpy, cv2 and Pillow, still no issue there, the downloading went fine.
But, when I try to import numpy for example, my IDE (Visual Studio Code) tell me that there’s an error :
Unable to import 'numpy'
So here’s my main.dart code (the only dart file, it’s a test app):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:starflut/starflut.dart';
void main() => runApp(Main());
class Main extends StatefulWidget {
@override
_MainState createState() => _MainState();
}
class _MainState extends State<Main> {
var _outputString = '';
StarSrvGroupClass srvGroup;
dynamic python;
_MainState() {
_initStarCore();
}
void showOutput(String info) async {
if (info == null || info.length == 0) return;
_outputString = info;
setState(() {});
}
void _initStarCore() async {
StarCoreFactory starcore = await Starflut.getFactory();
StarServiceClass service =
await starcore.initSimple("test", "123", 0, 0, []);
String resPath = await Starflut.getResourcePath();
await starcore.regMsgCallBackP(
(int serviceGroupID, int uMsg, Object wParam, Object lParam) async {
if (uMsg == Starflut.MSG_DISPMSG || uMsg == Starflut.MSG_DISPLUAMSG) {
showOutput(wParam);
}
print("$serviceGroupID $uMsg $wParam $lParam");
return null;
});
srvGroup = await service["_ServiceGroup"];
bool isAndroid = await Starflut.isAndroid();
if (isAndroid == true) {
String libraryDir = await Starflut.getNativeLibraryDir();
String docPath = await Starflut.getDocumentPath();
if (libraryDir.indexOf("arm64") > 0) {
Starflut.unzipFromAssets("lib-dynload-arm64.zip", docPath, true);
} else if (libraryDir.indexOf("x86_64") > 0) {
Starflut.unzipFromAssets("lib-dynload-x86_64.zip", docPath, true);
} else if (libraryDir.indexOf("arm") > 0) {
Starflut.unzipFromAssets("lib-dynload-armeabi.zip", docPath, true);
} else {
//x86
Starflut.unzipFromAssets("lib-dynload-x86.zip", docPath, true);
}
await Starflut.copyFileFromAssets("python3.6.zip",
"flutter_assets/starfiles", null); //desRelatePath must be null
await Starflut.copyFileFromAssets(
"program.py", "flutter_assets/starfiles", "flutter_assets/starfiles");
}
if (await srvGroup.initRaw("python36", service) == true) {
_outputString = "init starcore and python 3.6 successfully";
} else {
_outputString = "init starcore and python 3.6 failed";
}
await srvGroup.loadRawModule("python", "",
resPath + "/flutter_assets/starfiles/" + "program.py", false);
python = await service.importRawContext("python", "", false, "");
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
//_counter++;
});
}
void runScriptCode() async {
var result = await python.call("multiply", [5, 2]);
_outputString = result.toString();
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: FlatButton(
color: Colors.red,
child: Text(_outputString),
onPressed: () {
runScriptCode();
},
),
),
),
);
}
}
and my Python file:
import numpy as np # (to test)
def multiply(a, b):
return a*b
Here’s my tree structure if it can help:
The tree structure of my Flutter project
Hopping you can help me.
Thanks in advance !
If you can, connect python backend to flutter because with that there will be smoothness in your app.
You can use chaquopy plugin for flutter, if you want to integrate python packages inside your android app.
Android Flutter Only: As of last month, Chaquopy is now open-source and has a Flutter plug-in. So that would definitely be easiest way to include python code