![]() |
VOOZH | about |
dotnet add package EASYTools.PythonSharp --version 1.0.2
NuGet\Install-Package EASYTools.PythonSharp -Version 1.0.2
<PackageReference Include="EASYTools.PythonSharp" Version="1.0.2" />
<PackageVersion Include="EASYTools.PythonSharp" Version="1.0.2" />Directory.Packages.props
<PackageReference Include="EASYTools.PythonSharp" />Project file
paket add EASYTools.PythonSharp --version 1.0.2
#r "nuget: EASYTools.PythonSharp, 1.0.2"
#:package EASYTools.PythonSharp@1.0.2
#addin nuget:?package=EASYTools.PythonSharp&version=1.0.2Install as a Cake Addin
#tool nuget:?package=EASYTools.PythonSharp&version=1.0.2Install as a Cake Tool
<img src="https://github.com/jchristn/PythonSharp/blob/main/Assets/logo.png?raw=true" data-canonical-src="https://github.com/jchristn/PythonSharp/blob/main/Assets/logo.png?raw=true" width="128" height="128" />
PythonSharp is a simple library for invoking Python scripts from C# and retrieving their return value.
Why not just use pythonnet? Pythonnet is a fantastic, useful, and well-written library, managed and maintained by an excellent community. However, it is challenged in being able to support multiple concurrent virtual environments. Further, pythonnet provides near seamless integration with the .NET CLR, whereas PythonSharp is a wrapper library that invokes Python scripts using the shell. To summarize, you should use pythonnet in most cases, but consider PythonSharp when you need to support multiple virtual environments concurrently.
If you have any issues or feedback, please file an issue here in Github. We'd love to have you help by contributing code for new features, optimization to the existing codebase, ideas for future releases, or fixes!
Refer to the Test project for exercising the library. Create one instance of the PythonRunner class for each separate invocation.
using PythonSharp;
// Create the environment object.
PythonEnvironment env = new PythonEnvironment();
// Set the base executable and pip command.
env.PythonExecutable = "C:\\Program Files\\Python312\\python.exe";
env.PipCommand = "C:\\Program Files\\Python312\\Scripts\\pip.exe";
// Set up the virtual environment, or skip. If it does not exist, PythonSharp will create it.
env.VirtualEnvironmentPath = "./myscripts/venv/";
// Define path to the directory containing your script.
env.ScriptPath = "./myscripts/";
// Specify the requirements.txt file, or skip.
env.RequirementsFile = "./myscripts/requirements.txt";
// Create the script runner.
PythonRunner runner = new PythonRunner(env);
PythonResult result = runner.RunScript("script.py", "{ \"hello\": \"world\" }");
// {
// "GUID": "[GUID]", // Unique identifier for the execution
// "Success": true, // Success or failure
// "CommandResult": 0, // Result of the shell command to run the script
// "ConsoleOutput": "[Console messages here]", // Console output encountered during execution
// "ErrorOutput": "[Error messages here]", // Error output encountered during execution
// "Data": "{ \"hello\": \"world\" }"; // Data returned from the script
// "Exception": null // Exception, if any
// }
PythonSharp uses the Shelli library to invoke shell commands. Under the hood, shell commands are issued when necessary to create virtual environments, install requirements (inside or outside of a virtual environment), enter and exit virtual environments, and to invoke scripts.
User scripts should be implemented with a def process(req): method. The input req is a dictionary, and the output of this method must also be a dictionary.
Internally, a Guid is assigned for each invocation of a script. This serves as an identifier for temporary files that are created during execution:
The wrapper script is lightweight, and only serves to deserialize the input data supplied to runner.RunScript into a dictionary, and, to serialize the output data from the user function into a JSON object. The user script is imported into the wrapper script, and saved as a temporary file called [Guid].py. This file is deleted after execution.
The result value is stored in a file called [Guid].resp on the filesystem, and PythonSharp will read this file to obtain the results and then delete it.
The wrapper script, with a simple def process(req): integrated within, looks as follows when calling runner.RunScript("script.py", "{ \"hello\": \"world\" }");:
import json
# Begin user code
def process(req):
print("Hello from user code!")
return req
# End user code
_req_obj = json.loads('{ "hello": "world" }')
_resp_obj = process(_req_obj)
_out_file = open('9f786ef-7690-4024-8ec0-e5d699246527.resp', 'w')
_out_file.write(json.dumps(_resp_obj))
def process(req): as the entrypoint for their codereq to this method is a dictionary (deserialized from the JSON string supplied when invoking runner.RunScript)def process(req): method should return a dictionaryRefer to CHANGELOG.md for version history.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 net6.0 is compatible. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.2 | 126 | 3/29/2026 |
Initial release