When I run the exact same function from the python3 interpreter vs, apache via mod wsgi, they both run error free but one returns the command text from apache the stout is simply always blank. Again I am running the exact same function.
Backgorund, I want to run svn update on some code to do so I am using subprocess to simply call "svn update /path/to/repo"
def update():
p1=subprocess.Popen(["svn", "update", "/var/www/myrepocode"],stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
(ret, stderr) = p1.communicate(timeout=10)
return (str(ret.decode('utf-8')))
when i run from the python3 shell or another python 3 script called from the shell
from test import update
print(update())
it works fine and i get
"Updating '/var/www/myrepocode':\nAt revision 27.\n"
when I have a wsgi script and execute it from accessing the web page
def application(environ, start_response):
...
output = output + "---"+update() +"---"
...
response_headers = [('Content-type', 'text/html'), ('Content-Length',
str(len(output)))]
start_response(status, response_headers)
return [output.encode('utf-8')]
I get an empty string:
------
I do not have a python virtual environment, just normal python3 and there are no errors thrown either. I suspect this has to do with the user running it but I really don't know. setting shell=True doesn't change anything either. Any help is greatly appreciated.
Your update method does not return nor print stderr . Maybe you should check for errors first by adding the following line in the update method.
print(stderr)
If errors are produced, can you post them?
Related
I've tried every method in the title to run it in the background but here are the issues i got trying to use them:
pythonw and pyw: server doesn't work, going to localhost:8000 error with ERR_EMPTY_RESPONSE.
& arg and START/B: doesn't start script in background and instead output server log
so now I'm short on ideas on how to run this script in the background.
Using pythonw, it should help to explicitly redirect stdout and stderr to a file – maybe this behavior is somehow related to the problem described here (although this seems to be specific to Python 2.7). Not capturing the output by redirecting it to os.devnull seems to work as well.
The following script produces a minimum working server example with pythonw for me (using Python 3.7.9):
import http.server
import os
import sys
if __name__ == "__main__":
sys.stdout = sys.stderr = open(os.devnull, "w")
httpd = http.server.HTTPServer(("localhost", 8000), http.server.SimpleHTTPRequestHandler)
httpd.serve_forever()
test.py
from optparse import OptionParser
class Test(object):
def __init__(self):
pass
def _test1(self, some_val):
print(some_val)
def main(self, some_val):
self._test1(some_val)
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-a", "--abcd", dest="abcd", default=None,help="some_val")
(options, args) = parser.parse_args()
val = options.abcd
mainobj = Test()
mainobj.main(val)
Above script works, when executed python test.py --abcd=wxyz
When I run python -m pylint test.py --abcd=wxyz , doesn't execute.
Error:
strong text Usage: __main__.py [options]
__main__.py: error: no such option: --abcd
How to execute through pylint ?
Can you please help me ?
You cannot send new arguments like that using Pylint
Pylint is a static code analysis tool. It does NOT run your program. Therefore it does not matter what arguments are sent to the main program you want to test. Imagine it tests your code as it was "text" without running it.
Also the syntax you are using in the command line is not right, because after-m pylint the arguments which are sent are actually Pylint's arguments. Pylint has it's own set of options and rules you can set. you can view a summary here
or just type in your command line this:
pylint --help
The error message you get is a Pylint error. if you want to change the options you insert to Pylint you would have to change its source code i reckon...
Hope I understood your question correctly and that it helps.
I am trying to execute an external java program from a python 3.7 program using the java command with classpath. I am using subprocess.Popen module in Python. Somehow I am not able to get it working! Appreciate any assistance!
cmd = ['java',
'-classpath', 'C:/Users/Documents/MqTransfer.jar', 'C:/Users/Documents/com.ibm.mq.commonservices.jar',
'C:/Users/Documents/com.ibm.mq.headers.jar', 'C:/Users/Documents/com.ibm.mq.jar',
'C:/Users/Documents/com.ibm.mq.jmqi.jar', 'C:/Users/Documents/com.ibm.mq.pcf.jar',
'C:/Users/Documents/connector.jar', 'C:/Users/Documents/xerces.jar',
'MyMqTransfer', 'C:/Users/Documents/queueTransfer.properties']
jproc = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
output, errors = jproc.communicate()
print(output, errors)
I am getting the below error
b'' b'Error: Could not find or load main class C:.Users.Documents.com.ibm.mq.commonservices.jar\r\n'
When I try to run the java program from my batch script it runs fine! This is the command I use in my batch script. The issue is with my python code!
java -classpath MqTransfer.jar;com.ibm.mq.commonservices.jar;com.ibm.mq.headers.jar;com.ibm.mq.jar;com.ibm.mq.jmqi.jar;com.ibm.mq.pcf.jar;connector.jar;xerces.jar com.ibm.my.mq.MyMqTransfer C:\Users\Documents\queueTransfer.properties
Based on the error, I believe the process being executed is something like 'java -classpath C:/Users/Documents/MqTransfer.jar c:/Users/Documents/com.ibm.mq.commonServices.jar [followed by the rest of the arguments you are passing to process]' such that java is passed MqTransfer.jar as the entire classpath argument and thinks 'C:.Users.Documents.com.ibm.mq.commonservices.jar' is your class to launch. Try combining your entire intended classpath into the 3rd argument of your launch and I think you will be good. It would look something like this:
cmd = ['java',
'-classpath', 'C:/Users/Documents/MqTransfer.jar;C:/Users/Documents/com.ibm.mq.commonservices.jar;C:/Users/Documents/com.ibm.mq.headers.jar;C:/Users/Documents/com.ibm.mq.jar;C:/Users/Documents/com.ibm.mq.jmqi.jar;C:/Users/Documents/com.ibm.mq.pcf.jar;C:/Users/Documents/connector.jar;C:/Users/Documents/xerces.jar',
'MyMqTransfer', 'C:/Users/Documents/queueTransfer.properties']
I have a Python app that works locally, but on the server something goes wrong. So I have to do some debugging in an SSH session. The server logs tell me that something goes wrong in utils/do_something.py. I have created utils/log (rights 777), where the debugging values are supposed to go.
do_something.py looks like this:
import os
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
def do_something(arg1, arg2):
print('XXX')
f = open(log_file, 'a')
f.write('XXX\n')
stuff = goes.wrong
Loading the page causes do_something to run (as confirmed by the error logs). Locally the expected XXX appears in the console and in the log file. But nothing happens on the server.
I created a second file utils/blah.py:
print('BLAH')
import os
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
f = open(log_file, 'a')
f.write('BLAH\n')
When I run it with python blah.py, the expected BLAH appears in the console and the logfile.
I don't care that much about the difference between local and production server.
But I would like to understand the difference between do_something.py and blah.py.
Is there a better way to debug in an SSH session?
I work in a virtualenv in a mod_wsgi 4.6.5/Python3.7 environment on a Webfaction server. Some details about it can be seen in this question on the Webfaction forum.
Edit 1: On the server print seems to be discouraged anyway.
(See Where do things go when I ‘print’ them from my Django app?)
But what matters to me is f.write(). I just added print for comparison.
Edit 2: It is the same when I use the logging module. It works when I run blah.py, but nothing happens when loading the page runs do_something.
Edit 3: I tried the same with a simpler app, and the result is the same.I added the logging in views.py:
from django.http import HttpResponse
import os
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
def home_view(request):
f = open(log_file, 'a')
f.write('XXX\n')
return HttpResponse("Hello from home view.")
Locally this writes XXX to the log file every time the page is loaded. But not on the server.There are no errors in the server log.
Using the logging module: I am not sure why that did not work, but now it does.
import os
import logging
parent_folder = os.path.dirname(__file__)
log_file = os.path.join(parent_folder, 'log')
logging.basicConfig(filename=log_file, level=logging.DEBUG)
logging.debug('This works.')
Possibly I have used it with filename='log' instead of filename=log_file.
Locally the former creates the log file in the root folder. But on the server it must already exist.
Writing rights: It seems worth mentioning that touch log gave me a file I could not wright to, and lacking sudo I could not use chmod. So I used the trick install -b -m 777 /dev/null log.
It appears that you never explicitly close the file after writing, so the output is probably buffered. Your server and your local machine may have different settings with respect to file buffering, which would explain the differences you're experiencing.
If you want to open, write, and close a file, python's context managers are the best way to do it:
def home_view(request):
with open(log_file, 'a') as f:
f.write('XXX\n')
return HttpResponse("Hello from home view.")
You might check the privileges on the utils folder, and on any parent folders. Many times an http server will be running as user 'nobody', which has practically zip privileges. So unless the utils folder itself also has 0777 privileges, that could create a problem. You also might want to put the f.write in a try ... except block so that you can catch the error specifically and create a more useful / informative message about the error. Best.
I've searched a lot for this and have not yet found a definitive solution. The closest thing I've found is this:
import shutil
from os.path import join
import os
import time
import sys
minecraft_dir = ('server diectory')
world_dir = ('server world driectory')
def server_command(cmd):
os.system('screen -S -X stuff "{}\015"'.format(cmd))
on = "1"
while True:
command=input()
command=command.lower()
if on == "1":
if command==("start"):
os.chdir(minecraft_dir)
os.system('"C:\Program Files\Java\jre1.8.0_111\bin\java.exe" -Xms4G -Xmx4G -jar craftbukkit-1.10.2.jar nogui java')
print("Server started.")
on = "0"
else:
server_command(command)
When I launch this program and type 'start' the CMD flashes up and closes instantly. Instead I want the CMD to stay open with the minecraft sever running from it. I'm not sure why this happens or what the problem is, any help would be greatly appreciated.
p.s. I have edited this to my needs (such as removing a backup script that was unnecessary) but it didn't work before. The original link is: https://github.com/tschuy/minecraft-server-control
os.system will simply run the command then return to your python script with no way to further communicate with it.
On the other hand using subprocess.Popen gives you access to the process while it runs, including writing to it's .stdin which is how you send data to the server:
def server_command(cmd):
process.stdin.write(cmd+"\n") #just write the command to the input stream
process = None
executable = '"C:\Program Files\Java\jre1.8.0_111\bin\java.exe" -Xms4G -Xmx4G -jar craftbukkit-1.10.2.jar nogui java'
while True:
command=input()
command=command.lower()
if process is not None:
if command==("start"):
os.chdir(minecraft_dir)
process = subprocess.Popen(executable, stdin=subprocess.PIPE)
print("Server started.")
else:
server_command(command)
you can also pass stdout=subprocess.PIPE so you can also read it's output and stderr=subprocess.PIPE to read from it's error stream (if any)
As well instead of process.stdin.write(cmd+"\n") you could also use the file optional parameter of the print function, so this:
print(cmd, file=process.stdin)
Will write the data to process.stdin formatted in the same way that print normally does, like ending with newline for you unless passing end= to override it etc.
Both of the above answers do not work in the environment I tried them in.
I think the best way is to use RCON, not sending keys to a window.
RCON is the protocol used by games to run commands.
Many python libraries support Minecraft RCON, and the default server.properties file has an option for RCON.
We will use the python module: MCRON.
Install it. It works for windows, mac, linux.
Type:
pip install mcrcon
Lets configure your server to allow RCON.
In server.properties, find the line 'enable-rcon' and make it look like this:
enable-rcon=true
Restart and stop your server.
Find the line 'rcon.password' and set it to any password you will remember.
You can leave the port default at 25575.
Now, open your terminal and type:
mcron localhost
Or your server ip.
You will be prompted to enter the password you set.
Then you can run commands and will get the result.
But we are doing this with python, not the PYPI MCRON scripts - so do this.
from mcrcon import MCRcon as r
with r('localhost', 'insertyourpasswordhere') as mcr:
resp = mcr.command('/list')
print(resp) #there are 0/20 players online: - This will be different for you.