1- import 'dart:io' ;
2-
1+ import 'package:flutter/foundation.dart' ;
32import 'package:path/path.dart' as path;
43import 'package:serious_python_platform_interface/serious_python_platform_interface.dart' ;
54
5+ // Conditional import for IO operations
6+ import 'src/io_stub.dart' if (dart.library.io) 'src/io_impl.dart' ;
7+
68export 'package:serious_python_platform_interface/src/utils.dart' ;
79
810/// Provides cross-platform functionality for running Python programs.
@@ -15,56 +17,80 @@ class SeriousPython {
1517 }
1618
1719 /// Runs Python program from an asset.
18- ///
19- /// [assetPath] is the path to an asset which is a zip archive
20- /// with a Python program. When the app starts the archive is unpacked
21- /// to a temporary directory and Serious Python plugin will try to run
22- /// `main.py` in the root of the archive. Current directory is changed to
23- /// a temporary directory.
24- ///
25- /// If a Python app has a different entry point
26- /// it could be specified with [appFileName] parameter.
27- ///
28- /// Environment variables that must be available to a Python program could
29- /// be passed in [environmentVariables] .
30- ///
31- /// By default, Serious Python expects Python dependencies installed into
32- /// `__pypackages__` directory in the root of app directory. Additional paths
33- /// to look for 3rd-party packages can be specified with [modulePaths] parameter.
34- ///
35- /// Set [sync] to `true` to sychronously run Python program; otherwise the
36- /// program starts in a new thread.
3720 static Future <String ?> run (String assetPath,
3821 {String ? appFileName,
39- List <String >? modulePaths,
40- Map <String , String >? environmentVariables,
41- bool ? sync }) async {
42- // unpack app from asset
22+ List <String >? modulePaths,
23+ Map <String , String >? environmentVariables,
24+ bool ? sync }) async {
25+ // Handle web platform differently
26+ if (kIsWeb) {
27+ return _runWeb (assetPath,
28+ appFileName: appFileName,
29+ modulePaths: modulePaths,
30+ environmentVariables: environmentVariables,
31+ sync : sync );
32+ } else {
33+ return _runDesktop (assetPath,
34+ appFileName: appFileName,
35+ modulePaths: modulePaths,
36+ environmentVariables: environmentVariables,
37+ sync : sync );
38+ }
39+ }
40+
41+ /// Web-specific implementation
42+ static Future <String ?> _runWeb (String assetPath,
43+ {String ? appFileName,
44+ List <String >? modulePaths,
45+ Map <String , String >? environmentVariables,
46+ bool ? sync }) async {
47+
48+ String virtualPath;
49+ if (path.extension (assetPath) == ".zip" ) {
50+ virtualPath = assetPath.replaceAll (".zip" , "" );
51+ // TODO Check if path exists and except with unzip hint if not
52+ } else {
53+ virtualPath = assetPath;
54+ }
55+
56+ if (appFileName != null ) {
57+ virtualPath = '$virtualPath /$appFileName ' ;
58+ } else {
59+ virtualPath = '$virtualPath /main.py' ;
60+ }
61+
62+ return runProgram (virtualPath,
63+ modulePaths: modulePaths,
64+ environmentVariables: environmentVariables,
65+ sync : sync );
66+ }
67+
68+ /// Desktop-specific implementation
69+ static Future <String ?> _runDesktop (String assetPath,
70+ {String ? appFileName,
71+ List <String >? modulePaths,
72+ Map <String , String >? environmentVariables,
73+ bool ? sync }) async {
4374 String appPath = "" ;
4475 if (path.extension (assetPath) == ".zip" ) {
4576 appPath = await extractAssetZip (assetPath);
4677 if (appFileName != null ) {
4778 appPath = path.join (appPath, appFileName);
48- } else if (await File (path.join (appPath, "main.pyc" )).exists ()) {
49- appPath = path.join (appPath, "main.pyc" );
50- } else if (await File (path.join (appPath, "main.py" )).exists ()) {
51- appPath = path.join (appPath, "main.py" );
5279 } else {
53- throw Exception (
54- "App archive must contain either `main.py` or `main.pyc`; otherwise `appFileName` must be specified." );
80+ appPath = await FileSystem .findMainFile (appPath);
5581 }
5682 } else {
5783 appPath = await extractAsset (assetPath);
5884 }
5985
6086 // set current directory to app path
61- Directory .current = path.dirname (appPath);
87+ await FileSystem . setCurrentDirectory ( path.dirname (appPath) );
6288
6389 // run python program
6490 return runProgram (appPath,
6591 modulePaths: modulePaths,
6692 environmentVariables: environmentVariables,
67- script: Platform .isWindows ? "" : null ,
93+ script: FileSystem .isWindows ? "" : null ,
6894 sync : sync );
6995 }
7096
@@ -82,14 +108,13 @@ class SeriousPython {
82108 /// `__pypackages__` directory in the root of app directory. Additional paths
83109 /// to look for 3rd-party packages can be specified with [modulePaths] parameter.
84110 ///
85- /// Set [sync] to `true` to sychronously run Python program; otherwise the
111+ /// Set [sync] to `true` to synchronously run Python program; otherwise the
86112 /// program starts in a new thread.
87113 static Future <String ?> runProgram (String appPath,
88114 {String ? script,
89- List <String >? modulePaths,
90- Map <String , String >? environmentVariables,
91- bool ? sync }) async {
92- // run python program
115+ List <String >? modulePaths,
116+ Map <String , String >? environmentVariables,
117+ bool ? sync }) async {
93118 return SeriousPythonPlatform .instance.run (appPath,
94119 script: script,
95120 modulePaths: modulePaths,
@@ -100,4 +125,4 @@ class SeriousPython {
100125 static void terminate () {
101126 SeriousPythonPlatform .instance.terminate ();
102127 }
103- }
128+ }
0 commit comments