Usage
Dartpy is a library that allows dart to call out to python code
by using the Python C-API embedding and dart:ffi
.
As such it is a fairly low level interface where you have to manage reference counts of python objects to help the python garbage collector.
However, there are a few high level functions that I've provided to automatically marshal the arguments to python and back and manage the reference counts for you.
Here are a few examples:
For a simple python script inline you can do the following:
(Uses the low level C-API that is wrapped by dart:ffi
).
void main(List<String> args) {
dartpyc.Py_Initialize();
final python = '''
from time import time, ctime
print("Today is", ctime(time()))
''';
final pystring = python.toNativeUtf8();
dartpyc.PyRun_SimpleString(pystring.cast<Int8>());
malloc.free(pystring);
print(dartpyc.Py_FinalizeEx());
}
For a more complex script that you don't want inline you can do this: (Uses a few higher level helper methods)
void main() {
// initializes the python runtime
pyStart();
try {
// imports a python module
final pyModule = pyimport('multiply');
// gets a function within that module
final pFunc = pyModule.getFunction('multiply');
// calls the function and gets the result
final result = pFunc([1, 2]);
print(result); // Should print 3
} on DartPyException catch (e) {
print(e);
// Cleans up memory
pyCleanup();
exit(1);
}
// Cleans up memory
pyCleanup();
exit(0);
}
Feel free to contribute! This is a best effort project that I develop in my spare time.
Limitations
This library assumes that you have the python dynamic library in the following locations:
- (MacOS) /usr/local/Frameworks/Python.framework/Versions/3.8/lib/libpython3.8.dylib
- (Linux) /usr/lib/x86_64-linux-gnu/libpython3.8.so
- (Windows) -- I don't know the default location, please submit a pull request!
To override this default location, put the following at the beginning of your script:
void main() {
pyLibLocation = '/path/to/your/dynamic_library';
// The rest of your code...
}
Eventually, maybe I will create a flutter package that bundles the dynamic library in the assets for each of the platforms, but currently I'm not doing that.
Not all objects are automatically marshalled back and forth, currently just supporting basic objects (int, double, String, num).
I'm working on an annotation and code generation library so that you can just annotate and call functions like so:
import 'package:dartpy/dartpy.dart';
import 'package:dartpy/dartpy_annotations.dart';
part 'gen_dartpy_example.g.dart';
@PyFunction(module: 'multiply')
int multiply(int a, int b) => pymultiply(a, b);
@PyFunction(module: 'multiply', name: 'multiply')
double mult_double(double a, double b) => pymultiplydouble(a, b);
@PyFunction(module: 'multiply', name: 'multiply')
num mult_num(num a, num b) => pymultiplynum(a, b);
void main() {
try {
print(multiply(6, 4));
print(mult_double(6.13, 5.2));
print(mult_num(6, 5.2));
print(mult_num(6, 2));
} on DartPyException catch (e) {
if (pyErrOccurred()) {
dartpyc.PyErr_Print();
}
print(e.message);
}
}
"Python" is a registered trademark of the Python Software Foundation
Libraries
- dartpy
- dartpy is a library that allows dart to call out to python code
- dartpy_annotations