Skip to content

Commit

Permalink
Add ., ./lib, ./plugin directories to path for Python plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Yusyuriv committed Dec 5, 2024
1 parent 14f1a5a commit fa8cd54
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 8 deletions.
52 changes: 45 additions & 7 deletions Flow.Launcher.Core/Plugin/PythonPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
Expand Down Expand Up @@ -29,10 +30,6 @@ public PythonPlugin(string filename)
_startInfo.EnvironmentVariables["FLOW_VERSION"] = Constant.Version;
_startInfo.EnvironmentVariables["FLOW_PROGRAM_DIRECTORY"] = Constant.ProgramDirectory;
_startInfo.EnvironmentVariables["FLOW_APPLICATION_DIRECTORY"] = Constant.ApplicationDirectory;


//Add -B flag to tell python don't write .py[co] files. Because .pyc contains location infos which will prevent python portable
_startInfo.ArgumentList.Add("-B");
}

protected override Task<Stream> RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
Expand All @@ -50,10 +47,51 @@ protected override string Request(JsonRPCRequestModel rpcRequest, CancellationTo
// TODO: Async Action
return Execute(_startInfo);
}

public override async Task InitAsync(PluginInitContext context)
{
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
_startInfo.ArgumentList.Add("");
// Run .py files via `-c <code>`
if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
{
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
var libDirectory = Path.Combine(rootDirectory, "lib");
var pluginDirectory = Path.Combine(rootDirectory, "plugin");

// This makes it easier for plugin authors to import their own modules.
// They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
// Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
// This code sets sys.path for the plugin author and then runs the .py file via runpy.
_startInfo.ArgumentList.Add("-c");
_startInfo.ArgumentList.Add(
$"""
import sys
sys.path.append(r'{rootDirectory}')
sys.path.append(r'{libDirectory}')
sys.path.append(r'{pluginDirectory}')
import runpy
runpy.run_path(r'{context.CurrentPluginMetadata.ExecuteFilePath}', None, '__main__')
"""
);
// Plugins always expect the JSON data to be in the third argument
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
_startInfo.ArgumentList.Add("");
// Because plugins always expect the JSON data to be in the third argument, and specifying -c <code>
// takes up two arguments, we have to move `-B` to the end.
_startInfo.ArgumentList.Add("-B");
}
// Run .pyz files as is
else
{
// -B flag is needed to tell python not to write .py[co] files.
// Because .pyc contains location infos which will prevent python portable
_startInfo.ArgumentList.Add("-B");
_startInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
// Plugins always expect the JSON data to be in the third argument
// (we're always setting it as _startInfo.ArgumentList[2] = ...).
_startInfo.ArgumentList.Add("");
}

await base.InitAsync(context);
_startInfo.WorkingDirectory = context.CurrentPluginMetadata.PluginDirectory;
}
Expand Down
31 changes: 30 additions & 1 deletion Flow.Launcher.Core/Plugin/PythonPluginV2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,36 @@ public PythonPluginV2(string filename)

public override async Task InitAsync(PluginInitContext context)
{
StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
// Run .py files via `-c <code>`
if (context.CurrentPluginMetadata.ExecuteFilePath.EndsWith(".py", StringComparison.OrdinalIgnoreCase))
{
var rootDirectory = context.CurrentPluginMetadata.PluginDirectory;
var libDirectory = Path.Combine(rootDirectory, "lib");
var pluginDirectory = Path.Combine(rootDirectory, "plugin");
var filePath = context.CurrentPluginMetadata.ExecuteFilePath;

// This makes it easier for plugin authors to import their own modules.
// They won't have to add `.`, `./lib`, or `./plugin` to their sys.path manually.
// Instead of running the .py file directly, we pass the code we want to run as a CLI argument.
// This code sets sys.path for the plugin author and then runs the .py file via runpy.
StartInfo.ArgumentList.Add("-c");
StartInfo.ArgumentList.Add(
$"""
import sys
sys.path.append(r'{rootDirectory}')
sys.path.append(r'{libDirectory}')
sys.path.append(r'{pluginDirectory}')
import runpy
runpy.run_path(r'{filePath}', None, '__main__')
"""
);
}
// Run .pyz files as is
else
{
StartInfo.ArgumentList.Add(context.CurrentPluginMetadata.ExecuteFilePath);
}
await base.InitAsync(context);
}

Expand Down

0 comments on commit fa8cd54

Please sign in to comment.