1- using System . Diagnostics ;
1+ using System ;
2+ using System . Diagnostics ;
23using System . IO ;
34using System . Text . Json ;
45using System . Threading ;
@@ -29,10 +30,6 @@ public PythonPlugin(string filename)
2930 _startInfo . EnvironmentVariables [ "FLOW_VERSION" ] = Constant . Version ;
3031 _startInfo . EnvironmentVariables [ "FLOW_PROGRAM_DIRECTORY" ] = Constant . ProgramDirectory ;
3132 _startInfo . EnvironmentVariables [ "FLOW_APPLICATION_DIRECTORY" ] = Constant . ApplicationDirectory ;
32-
33-
34- //Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
35- _startInfo . ArgumentList . Add ( "-B" ) ;
3633 }
3734
3835 protected override Task < Stream > RequestAsync ( JsonRPCRequestModel request , CancellationToken token = default )
@@ -50,10 +47,51 @@ protected override string Request(JsonRPCRequestModel rpcRequest, CancellationTo
5047 // TODO: Async Action
5148 return Execute ( _startInfo ) ;
5249 }
50+
5351 public override async Task InitAsync ( PluginInitContext context )
5452 {
55- _startInfo . ArgumentList . Add ( context . CurrentPluginMetadata . ExecuteFilePath ) ;
56- _startInfo . ArgumentList . Add ( "" ) ;
53+ // Run .py files via `-c <code>`
54+ if ( context . CurrentPluginMetadata . ExecuteFilePath . EndsWith ( ".py" , StringComparison . OrdinalIgnoreCase ) )
55+ {
56+ var rootDirectory = context . CurrentPluginMetadata . PluginDirectory ;
57+ var libDirectory = Path . Combine ( rootDirectory , "lib" ) ;
58+ var pluginDirectory = Path . Combine ( rootDirectory , "plugin" ) ;
59+
60+ // This makes it easier for plugin authors to import their own modules.
61+ // They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
62+ // Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
63+ // This code sets sys.path for the plugin author and then runs the .py file via runpy.
64+ _startInfo . ArgumentList . Add ( "-c" ) ;
65+ _startInfo . ArgumentList . Add (
66+ $ """
67+ import sys
68+ sys.path.append(r'{ rootDirectory } ')
69+ sys.path.append(r'{ libDirectory } ')
70+ sys.path.append(r'{ pluginDirectory } ')
71+
72+ import runpy
73+ runpy.run_path(r'{ context . CurrentPluginMetadata . ExecuteFilePath } ', None, '__main__')
74+ """
75+ ) ;
76+ // Plugins always expect the JSON data to be in the third argument
77+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
78+ _startInfo . ArgumentList . Add ( "" ) ;
79+ // Because plugins always expect the JSON data to be in the third argument, and specifying -c <code>
80+ // takes up two arguments, we have to move `-B` to the end.
81+ _startInfo . ArgumentList . Add ( "-B" ) ;
82+ }
83+ // Run .pyz files as is
84+ else
85+ {
86+ // -B flag is needed to tell python not to write .py[co] files.
87+ // Because .pyc contains location infos which will prevent python portable
88+ _startInfo . ArgumentList . Add ( "-B" ) ;
89+ _startInfo . ArgumentList . Add ( context . CurrentPluginMetadata . ExecuteFilePath ) ;
90+ // Plugins always expect the JSON data to be in the third argument
91+ // (we're always setting it as _startInfo.ArgumentList[2] = ...).
92+ _startInfo . ArgumentList . Add ( "" ) ;
93+ }
94+
5795 await base . InitAsync ( context ) ;
5896 _startInfo . WorkingDirectory = context . CurrentPluginMetadata . PluginDirectory ;
5997 }
0 commit comments