I have written some code in Python that uses some libraries that are not in Go. I have a web server that I have written in Go and I would like to be able to call a Python program from my Go program and then use the output of the Python program as input in my Go program. Is there anyway to do this?
It's actually relatively easy. All you need to do is use the os/exec library. Here is an example below.
Go Code:
package main
import (
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("python", "python.py", "foo", "bar")
fmt.Println(cmd.Args)
out, err := cmd.CombinedOutput()
if err != nil { fmt.Println(err); }
fmt.Println(string(out))
}
Python Code:
import sys
for i in range(len(sys.argv)):
print str(i) + ": " + sys.argv[i]
Output From Go Code:
[python python.py foo bar]
0: python.py
1: foo
2: bar
Related
I am creating a vscode extension where I need machine learning tasks to be performed. I have python files that have code that is required in vscode extension. I don't want things to be done using request-response on any python server. What I want is to perform the ML tasks on device (integrated with the vsix).
We have child-process available in js to run basic python file using spawn. It is running fine on both, extension host window and external vscode editor after packaging, with the python code that has basic imports like import sys. But if I try to import some other libraries like numpy, pygments, it is working only on extension host environment, not on other vs window after packaging it. How can I run the typical python code with the vsix?
Below are both the codes that is working fine and not working at all-
TS file (MLOps.ts)-
import { ChildProcessWithoutNullStreams, spawn } from "child_process";
import { join } from "path";
import * as vscode from 'vscode'
export async function pythonOps(): Promise<string> {
var result = "testt"
var promise = await new Promise((resolve, reject) => {
var p = __dirname.split('\\')
p.pop()
var path = p.join('\\')
var pyPath = join(path, 'src', 'py_operations.py')
var result = "blank result"
var arg1 = "arg one"
var arg2 = "arg two"
var py_process = spawn('python', [pyPath, arg1, arg2])
py_process.stdout.on('data', (data: any) => {
vscode.window.showInformationMessage(data.toString())
result = data.toString()
})
})
}
Working Python code (py_operations.py)- This code is working on both, on extension host window and after packaging the extension and installing the vsix on other system.
import sys
print("Some text with: ",sys.argv[0], sys.argv[1], sys.argv[2])
sys.stdout.flush()
Not working Python code- This code is working only on extension host window, and not working after packaging this and isntalling on other system.
import sys
from pygments.lexers.javascript import TypeScriptLexer
lexer = TypeScriptLexer()
src = "alert('text here')"
lexer_tokens = lexer.get_tokens(src)
l = []
for t in lexer_tokens:
l.append(t[1])
print("list: ",l)
sys.stdout.flush()
How can I run the second python code with packaged vsix?
I have searched and searched and searched but have not found and answer to my particular situation, or if I had I don't know how to implement it. I'm trying to create a script using python and bash to automate my project creation process. Whereas I would run the testing.py "as it is called now because I'm testing" with 1 command line argument which would be the name of the project folder, then it would ask "where I would like to create the project" with two options for paths to store the project and store the path using an if statement into the path variable. then I would like to pass that variable in the bash script to navigate to it and create the project directory there. here is what I have so far:
so the command that I would run is like:
python testing.py newProject
in the .test.sh
#!/bin/bash
function testing() {
cd
desktop
python testing.py $1
}
and in the testing.py
import sys
import os
school = "/Users/albert/Open/Microverse/"
personal = "/Users/albert/Open/code/Projects/"
path = " "
userInput = input("What type of project would you like to create? Personal or School? ")
if userInput.lower() == "personal":
path = personal
elif userInput.lower() == "school":
path = school
def testing():
folderName = str(sys.argv[1])
os.makedirs(path + str(folderName))
print(folderName)
if __name__ == "__main__":
testing()
Use "$1" instead of $1 as shown below
python testing.py "$1"
You have to run your bash function like this
testing $1
The whole script
#!/bin/bash
function testing() {
cd
desktop
python test.py $1
}
testing $1
And change input() to raw_input() in your python part. Input() function returns will actually evaluate the input string and try to run it as Python code. And if i try to input Personal this give me an error
What type of project would you like to create? Personal or School? Personal
Traceback (most recent call last):
File "test.py", line 9, in <module>
userInput = input("What type of project would you like to create? Personal or School? ")
File "<string>", line 1, in <module>
NameError: name 'Personal' is not defined
And if you input personal than userInput will be /Users/albert/Open/code/Projects/ wich is not wat you want right?
I'm guessing desktop is not actually a valid command, and that you really want
testing () {
cd ~/Desktop
python test.py "$1"
]
A better design might be to not force all projects to be created inside your desktop folder, though.
testing () {
python ~/Desktop/test.py "$1"
}
will let you run the script in any directory.
A still better design would be to give the script a proper shebang, mark it executable, call it testing, and save it in your PATH; then you don't need a shell function at all.
A different and IMHO more usable approach would be to allow the user to specify "personal" or "school" as part of the command line, instead of forcing the script to use interactive input. Requiring interactive I/O makes the script harder to use as a building block in further automation, and robs the user of the ability to use the shell's history and completion features.
The following refactoring hard-codes a very crude option parser, and uses a dict to map the project type to a specific folder name.
#!/usr/bin/env python3
import sys
import os
paths = {
"school": "/Users/albert/Open/Microverse/"
"personal": "/Users/albert/Open/code/Projects/"
}
def makeproject(type, folder):
os.makedirs(os.path.join(path, folder))
def gettype():
while True:
userInput = input("What type of project would you like to create? Personal or School? ")
if userInput in paths:
return paths[userInput]
print("Not a valid option: {} -- try again".format(userInput))
def testing():
idx = 1
if sys.argv[idx] == "--school":
type = paths["school"]
idx = 1
elif sys.argv[idx] == "--personal":
type = paths["personal"
idx = 2
else:
type = gettype()
folderName = sys.argv[idx]
makeproject(type, folderName)
print(folderName)
if __name__ == "__main__":
testing()
Notice that sys.argv and the value returned by input are already strings; there is no need to call str() on them.
I am trying to call go lang function from python
when I call my python program I am seeing the following error.
I am referring to the Go to pythn link.
Python Program
from ctypes import *
def call_go_function():
lib = cdll.LoadLibrary("./awesome.so")
lib.Add.argtypes = [c_longlong, c_longlong]
print( lib.Add(12,99))
call_go_function()
Go Program
package main
import "C"
import (
"sync"
)
var count int
var mtx sync.Mutex
//export Add
func Add(a, b int) int { return a + b }
func main() {}
From the Python path it looks like this is a 32-bit Python version. You cannot mix 32-bit and 64-bit user-space code.
So I guess you need to either:
Rebuild your Go code as a 32-bit DLL (see GOARCH=386) or
Install and run a 64-bit Python version.
Maybe it's an environment. Try running a simple program.
from ctypes import *
lib = cdll.LoadLibrary("./func.so")
r=lib.fun(10,20)
print(r)
package main
import "C"
//export fun
func fun(x int,y int) int{
return x+y
}
func main(){}
>go build -o func.so -buildmode=c-shared func.go
>python test.py
30
I want to use syslog-ng to receive netgear log, and use python script process.
But syslog-ng didn't run the python script.
syslog-ng.config
#version:3.2
options {
flush_lines (0);
time_reopen (10);
log_fifo_size (1000);
long_hostnames (off);
use_dns (no);
use_fqdn (no);
create_dirs (no);
keep_hostname (yes);
};
source s_sys {
udp(ip(0.0.0.0) port(514));
};
destination d_python{
program("/usr/local/bin/python /opt/syslog.py");
#program("/bin/echo 'haha' >> /tmp/test");
};
log { source(s_sys); destination(d_python);};
and python script like this
#!/usr/local/bin/python
#coding:utf8
import os
import sys
import datetime
f = open('/var/log/pnet.log', 'a')
f.write('\nstart\n')
f.write('args\n')
f.write('%s\n' % sys.argv)
if not sys.stdin.isatty():
f.write('stdin\n')
f.write('%s\n' % date.date.now().isoformat() )
tty_read = sys.stdin.read()
f.write("'''\n")
f.write(tty_read)
f.write("\n'''\n")
f.write('end\n')
f.close()
The script is already 777
Even I change my config to use 'echo' directly pipe into a file, didn't write a word too...
So...why?
silly question, but do you have incoming logs? If you use a simple file destination instead of the program, do you receive logs? If not, the problem is not in the program destination.
Also, try changing the flush_lines (0); option to 1 to see if it helps.
Regards,
Robert Fekete
I could show you my code for reference:
my syslog-ng.conf :
source s_test{
file("/home/test/in.log" follow-freq(1) flags(no-parse));
};
destination d_test{
program ("/home/test/out.py" flush_lines(1) flags(no_multi_line));
};
log {
source(s_test);
destination(d_test);
flags(flow-control);
};
my out.py:
#!/usr/bin/env python
# encoding: utf-8
import sys
while True:
line = sys.stdin.readline()
file = open("/home/test/out_from_python.log","a")
file.write(line)
file.close()
when you type echo "something" >> /home/test/in.log , there would be a new log lie in /home/test/out_from_python.log
I'm trying to write a vim plugin that uses a Python code block inside of it. I would like to get the full path of myvim.vim (/home/myusername/.vim/bundle/myvim/plugin/myvim.vim) inside of my python code block. Unfortunately you can't get the path by using __file__ as in a .py file. I can't use vim.command(':pwd') either because that just prints the path of the location where the plugin function is called from.
myvim.vim
function! Myvim()
python << EOF
import vim
vim_path = "full myvim.vim path here"
print vim_path
EOF
endfunction
EDIT
#actionshrimp, I'm trying this:
myvim.vim
function! Myvim()
let s:curfile = expand("<sfile>")
let s:curfiledir = fnamemodify(s:curfile, ":h")
python << EOF
import vim
py vim_path = vim.eval('expand("<sfile>")')
print vim_path
EOF
endfunction
You can use <sfile> to get the path of the currently executing vimscript, like so:
let s:curfile = expand("<sfile>")
let s:curfiledir = fnamemodify(s:curfile, ":h")
To pass that to python you should be able to use:
py vim_path = vim.eval('expand("<sfile>")')
or if you've set the variable:
py vim_path = vim.eval('s:curfile')
For clarity here's a full example (saved as 'D:\tmp\test.vim'):
python << EOF
import vim
vim_path = vim.eval('expand("<sfile>")')
print vim_path
EOF
When I have it open and type :so % it shows 'D:\tmp\test.vim' at the bottom.