Im calling Python script from a C# app to execute with the code below
string srCommandName = "customWhisper.py D:\Tas\Monitor\Stemme_226.m4a 41f850e7-455e-4f84-b1eb-a5cccea49046.txt"
ProcessStartInfo psInfo = new ProcessStartInfo(srCommandName);
psInfo.UseShellExecute= false;
psInfo.RedirectStandardOutput = true;
using (Process process = Process.Start(psInfo))
{
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
if (result=="")
{ }
}
}
My Python code is:
try:
if len(sys.argv)==3:
mediaPath = sys.argv[1]
textFilePath = sys.argv[2]
model = whisper.load_model("tiny")
isExist = os.path.exists(mediaPath)
if isExist:
results = model.transcribe(mediaPath, language = "da")
stab_segments = results['segments']
text_file = open(textFilePath, "w",encoding="utf-8")
for i in stab_segments:
text_file.write(i["text"] + '\n')
text_file.close()
print(0)
else:
print(1)
else:
print(len(sys.argv))
except Exception as er:
print(er)
The desired output from string result = reader.ReadToEnd(); should had been 0 (print 0) on success or one of the other prints. But its the srCommandName
Is there any way to get Python to return a value when called from C#
I use the below method to call python script from c# and get the result from python standard output back as a string. The FileName property of ProcessStartInfo should point to the python interpreter to use - not the python script. The python script should be sent as first argument.
private (string output, int exitCode) RunPythonScript(string pathToPythonFile, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\MyPathToPythonInterpreter\Scripts\python.exe";
start.Arguments = string.Format("{0} {1}", pathToPythonFile, args);
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
using (Process process = Process.Start(start))
{
process.WaitForExit();
using (StreamReader reader = process.StandardOutput)
{
string result = reader.ReadToEnd();
return (result, process.ExitCode);
}
}
}
Related
So, I have a code in C# that converts the Image to base64 and vice versa. Now, I want to send the generated base64 to python.
Here's my existing code.
var startProcess = new ProcessStartInfo
{
FileName = pythonInterpreter,
Arguments = string.Format($"\"{pythonPathAndCode}\" {b64stringCSharp}"),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = true,
};
using (Process process = Process.Start(startProcess))
{
error = process.StandardError.ReadToEnd();
testResult = process.StandardOutput.ReadToEnd();
lblTestOutput.Text = testResult;
lblError.Text = error;
}
This code is working just fine when I'm trying to send a small value of string to python. But when it comes in sending base64 value, an exception error appeared.
System.ComponentModel.Win32Exception: 'The filename or extension is too long'
Take note that the code is working perfectly fine when I'm sending only 32,000 string and less but base64 consist of exactly 98,260.
Is there a way to minimize this base64?
This is my python code:
import sys
inputFromC = sys.stdin
print("Python Recevied: ", inputFromC)
The maximum length for a command + arguments in Windows is 32767 characters (link). This is consistent with that you're seeing.
I recommend sending the image over the process's standard input instead. Something like:
var startProcess = new ProcessStartInfo
{
FileName = pythonInterpreter,
Arguments = string.Format($"\"{pythonPathAndCode}\""),
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
CreateNoWindow = true,
};
using (Process process = Process.Start(startProcess))
{
process.StandardInput.Write(b64stringCSharp);
process.StandardInput.Close();
error = process.StandardError.ReadToEnd();
testResult = process.StandardOutput.ReadToEnd();
lblTestOutput.Text = testResult;
lblError.Text = error;
}
Obviously, modify your Python script to read from standard input, rather than a command-line argument.
I am new to child_process and I want to experiment with its capabilities.
Is there any way to pass a function and arguments to a python file, using spawn (or exec or execFile is spawn cannot do it)?
I want to do something like (pseudocode)
spawnORexecORexefile (python path/to/python/file function [argument1, argument2] )
or maybe
spawnORexecORexefile (python path/to/python/file function(argument1, argument2) )
Please explain and maybe give an example, because I am a newbie
How I am doing it now?
in node
var process = spawn('python', [path/to/pythonFile.py, 50, 60] );
in pythonFile.py
import sys
import awesomeFile
hoodie = int(sys.argv[1])
shoe = int(sys.argv[2])
awesomeFile.doYourMagic().anotherThing(hoodie, shoe)
as you can see, from node, I send data to pythonFile and then to awesomeFile, to a specific function
I would like to "cut the middle man" and remove the pythonFile and send data from node directly to the awesomeFile file, to a specific function. This is why I am asking
Thanks
You can run a specific Python function from the command-line using the form python -c 'import foo; print foo.hello()' (from https://stackoverflow.com/a/3987113/5666087).
Place both the files below in the same directory, and run with node index.js. You should see the following output:
Hoodie: 10
Shoe: 15
awesomeFile.py
def myfunc(hoodie, shoe):
hoodie = int(hoodie)
shoe = int(shoe)
print("Hoodie:", hoodie)
print("Shoe:", shoe)
index.js
const { spawn } = require('child_process');
let hoodie = 10,
shoe = 15;
const result = spawn("python",
["-c", `import awesomeFile; awesomeFile.myfunc(${hoodie}, ${shoe})`])
result.stdout.pipe(process.stdout)
You can group all the relevant functions you want to call to class and make a dictionary out of a class that maps to the class function. You can directly call awesome.py without an intermediate index.py. You can extend the class AwesomeFile with your methods
The follow program will take user input -
which python file to run
which method to run
method arguments
Number of arguments mismatch
What if unknown methods are given
awesomeFile.py
import sys
class AwesomeFile:
def __init__(self):
pass
def doYourMagic(self):
return self
def anotherThing(self, hoodie, shoe):
print(int(hoodie))
print(int(shoe))
awesomeFile = AwesomeFile()
methods = {m:getattr(awesomeFile, m) for m in dir(AwesomeFile) if not m.startswith('__')}
def run():
method_name = sys.argv[1]
if method_name not in methods:
print(f"Unknown Method {method_name}")
return
methodArgCount = methods[method_name].__code__.co_argcount
if methodArgCount - 1 != len(sys.argv[2:]):
print(f"Method {method_name} takes {methodArgCount - 1} arguments but you have given {len(sys.argv[2:])}")
return
methods[method_name](*sys.argv[2:])
if __name__ == "__main__":
run()
index.js
Note** - You would to install prompt - npm i prompt
'use strict';
var prompt = require('prompt');
const { spawn } = require( 'child_process' );
var prompt_attributes = [
{
name: 'pythonFilePath'
},
{
name: 'cmdLineArgs'
}
];
prompt.start();
prompt.get(prompt_attributes, function (err, result) {
if (err) {
console.log(err);
return 1;
}else {
console.log('Command-line received data:');
var filePath = result.pythonFilePath;
var cmdLineArgs = result.cmdLineArgs;
var args = cmdLineArgs.split(" ");
args.unshift(filePath);
const pythonProgram = spawn( 'python' , args);
pythonProgram.stdout.on( 'data', data => {
console.log( `stdout:\n\n ${data}` );
} );
pythonProgram.stderr.on( 'data', data => {
console.log( `stderr: ${data.data}` );
} );
pythonProgram.on( 'close', code => {
console.log( `child process exited with code ${code}` );
} );
}
});
To run the program -
I/O:
Argument Mistmatch -
prompt: Python File Path. Give absolute or relative path: ../python_files/awesomeFile.py # python file can be any location in the system
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2): anotherThing 1
Command-line received data:
stdout:
Method anotherThing takes 2 arguments but you have given 1
child process exited with code 0
Function Not found
prompt: Python File Path. Give absolute or relative path: ../python_files/awesomeFile.py
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2): helloworld 1 2
Command-line received data:
stdout:
Unknown Method helloworld
child process exited with code 0
Success Case:
prompt: Python File Path. Give absolute or relative path: ../python_files/awesomeFile.py
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2): anotherThing 50 60
Command-line received data:
stdout:
50
60
child process exited with code 0
If I send second request by hand, it works fine, but if I try to do that by python, it is failing. No errors in apache log. File remains the same and is not overwritten.
Code:
def fen_actions(mode,fen):
global url
if mode: # 1-> Read 2-> Write
params = {'mode':'readFen'}
else:
params = {'mode':'putFen','fen':fen}
r = requests.get(url,params)
return r.text
fen_actions(2,chess.STARTING_BOARD_FEN) #This is not working. Starting fen is just a string
temp_readed_fen = fen_actions(1,0) # This works
php code:
<?php
$f = fopen("tempfen.txt","r+") or die("Unable to open a file");
if (strval($_GET["mode"]) === strval("putFen"))
{
if(strval($_GET['fen']) != strval(fread($f,filesize("tempfen.txt"))))
{
file_put_contents("tempfen.txt","");
fwrite($f,$_GET['fen']);
}
}
else if ($_GET["mode"] === strval("readFen"))
{
echo(fread($f,filesize("tempfen.txt")));
}
ini_set('display_errors',1);
?>
If I understand what you're trying to do, I think your if statements aren't actually checking what you want. According to your comment, it should be:
if mode == 1: # 1-> Read 2-> Write
params = {'mode':'readFen'}
elif mode == 2:
params = {'mode':'putFen','fen':fen}
I have the following named pipe created in Windows Powershell.
# .NET 3.5 is required to use the System.IO.Pipes namespace
[reflection.Assembly]::LoadWithPartialName("system.core") | Out-Null
$pipeName = "pipename"
$pipeDir = [System.IO.Pipes.PipeDirection]::InOut
$pipe = New-Object system.IO.Pipes.NamedPipeServerStream( $pipeName, $pipeDir )
Now, what i need is some Python code snippet to read from the above named pipe created. Can Python do that ?
Thanks in advance !
Courtesy :http://jonathonreinhart.blogspot.com/2012/12/named-pipes-between-c-and-python.html
Here's the C# Code
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
class PipeServer
{
static void Main()
{
var server = new NamedPipeServerStream("NPtest");
Console.WriteLine("Waiting for connection...");
server.WaitForConnection();
Console.WriteLine("Connected.");
var br = new BinaryReader(server);
var bw = new BinaryWriter(server);
while (true)
{
try
{
var len = (int)br.ReadUInt32(); // Read string length
var str = new string(br.ReadChars(len)); // Read string
Console.WriteLine("Read: \"{0}\"", str);
//str = new string(str.Reverse().ToArray()); // Aravind's edit: since Reverse() is not working, might require some import. Felt it as irrelevant
var buf = Encoding.ASCII.GetBytes(str); // Get ASCII byte array
bw.Write((uint)buf.Length); // Write string length
bw.Write(buf); // Write string
Console.WriteLine("Wrote: \"{0}\"", str);
}
catch (EndOfStreamException)
{
break; // When client disconnects
}
}
}
}
And here's the Python code:
import time
import struct
f = open(r'\\.\pipe\NPtest', 'r+b', 0)
i = 1
while True:
s = 'Message[{0}]'.format(i)
i += 1
f.write(struct.pack('I', len(s)) + s) # Write str length and str
f.seek(0) # EDIT: This is also necessary
print 'Wrote:', s
n = struct.unpack('I', f.read(4))[0] # Read str length
s = f.read(n) # Read str
f.seek(0) # Important!!!
print 'Read:', s
time.sleep(2)
Convert the C# code into a .ps1 file.
I want to rewrite yEnc code to make it compilable on Win32 with Visual Studio 2008.
The issue is that yEnc uses unistd.h (UNIX) functions fcntl to check if a file is readable or writable. It is of course not compatible with MS Visual Studio.
Here's what I want to be remove:
static Bool writable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_WRONLY) || (mode == O_RDWR);
}
static Bool readable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_RDONLY) || (mode == O_RDWR);
}
And here is how it is called:
FILE* infile = PyFile_AsFile(Py_infile);
FILE* outfile = PyFile_AsFile(Py_outfile);
if(!readable(infile) || !writable(outfile) ) {
return PyErr_Format(PyExc_ValueError, "file objects not writeable/readable");
}
/* File stuff including */
fread(&read_buffer, 1, in_ind, infile);
if(ferror(infile) || ferror(outfile)) {
return PyErr_Format(PyExc_IOError, "I/O Error while encoding");
}
fputc(CR, outfile);
fputc(LF, outfile);
fflush(outfile);
/* End of file stuff */
Can someone help me converting this readable/writable check (with equivalent of try {} catch {} instead) ?
I believe it is easier to handle errors on file read/write than trying to know if a Windows file is readable/writable, because there doesn't seem to be simple Windows equivalents to fcntl/F_GETFL.
The solution doesn't seem complicated but as I'm new to C and Python, I don't want to take the risk of making a buggy exception handler.
Thanks for your help.
You don't have to convert it just install windows POSIX.
http://www.cygwin.com/
Finally, I think the following checks will be sufficient:
infile == NULL
outfile == NULL
fread != read_count
fwrite != write_count
ferror
This should be sufficient. Moreover, the file have been opened in Python first and I presume this file open has been tested for exceptions.
{
public string writepath;
public string readpath;
public string line;
public List<Reciepient> reciepients = new List<Reciepient>();//linking my ist from my rec class
public int index;
public Form1()
{
InitializeComponent();
writebutton.Enabled = false;//disables write button
}
public void createbutton_Click(object sender, EventArgs e)
{
writebutton.Enabled = true;//enables write button
folderBrowserDialog1.ShowDialog();//open folder browser
writepath = folderBrowserDialog1.SelectedPath+ #"\test.txt";//generate path
StreamWriter sw = new StreamWriter(writepath);//open new sw
textBox1.Text = writepath;//write path to textbox1
sw.Close();//close my sw
}
public void readbutton_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();//open my file browser
readpath = openFileDialog1.FileName;//grabbing file name
StreamReader sr = new StreamReader(readpath);//creating new sr
textBox2.Text = readpath;//putting readpath in textbox2
while(sr.Peek()!= -1)//will stop reading if noo more lines
{
line = sr.ReadLine();//tells to read lines listed
Console.WriteLine(line);
/*if (line.Length > 0)
continue; messing up!!
else
MessageBox.Show("Line Cannot be Read");
*/
string fname = line.Substring(0, 5);
string lname = line.Substring(6, 6);
int loccode = Int32.Parse(line.Substring(13, 1));
int wcode = Int32.Parse(line.Substring(15, 1));
double itemcost = double.Parse(line.Substring(17, 5));
int acode = Int32.Parse(line.Substring(23, 1));
Reciepient file = new Reciepient(fname, lname, loccode, wcode, itemcost,
acode);
reciepients.Add(file);//add to list
}
sr.Close();//closes streamreader
}
public void writebutton_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(writepath);
Console.WriteLine(reciepients.Count);
for (int index = 0; index < reciepients.Count(); index++)
{
Reciepient file = reciepients.ElementAt(index);
sw.WriteLine(file.fname + " " + file.lname +" "+ "="+ file.totalcost);
}
sw.Close();
}