I created a Windows Service with python. It works well when I run it with debug mode, but when I start the service it doesn't work. This is the sample of my script:
def run(param):
subprocess.Popen(["C:\\SER\\txt_write.pyw",param], shell=True)
#txt_write is a simple script: put the parameter into b.txt
def add_param():
x="123456"
run(x)
class PythonCornerExample(SMWinservice):
_svc_name_ = "name"
_svc_display_name_ = "name disp"
_svc_description_ = "desc"
def start(self):
self.isrunning = True
def stop(self):
self.isrunning = False
def main(self):
i=0
while self.isrunning:
add_param()
f= open("C:\\SER\\a.txt","a+")
f.write("xyz")
f.close()
time.sleep(25)
if __name__ == '__main__':
PythonCornerExample.parse_command_line()
So, when I run this script in debug mode it put "xyz" text into a.txt, and calls another python script, that put the parameter (123456) into b.txt. This is how I want it to works.
My problem is, installed as Windows Service the a.txt works, but b.txt doesn't.
What is wrong with my script? Why is it OK in debug mode, and why is it wrong as Services?
change last 2 lines with bellow code:
import servicemanager, sys
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(PythonCornerExample)
servicemanager.StartServiceCtrlDispatcher()
else:
PythonCornerExample.parse_command_line()
The arguments passed by the service start are in the args parameter of the constructor method of your class.
class AppServerSvc (win32serviceutil.ServiceFramework):
def __init__(self, **args**):
You want them in sys.argv, where you'd get them if the parameters were coming from a command line.
So I simply did this.
sys.argv = args
And now I'm parsing my service parameters as if it came from the command line.
:)
Related
When i import one of my python scripts and run my current script , it seems to be running and displaying the output of the imported script which is really unusual behaviour. I have just imported this in my script but not really called any of its functions in my main code. How can i avoid from this behaviour happening ?
If i pass the -d flag with my main script it will run the usual code in my main script only
If i pass the -t flag with my main script , it will run the code from the imported python script only
main.py
import os
import argparse
import functions as funcs
import generate_json as gen_json
from test_compare_filesets import tester as imptd_tester
def get_json_location():
path = os.getcwd() + '/Testdata'
return path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--export-date", action="store_true", required=True)
parser.add_argument("-t", "--execute-test", action="store_true", required=False)
args = parser.parse_args()
date = args.export_date
testt = args.execute_test
yml_directory = os.listdir('yaml/')
yml_directory.remove('export_config.yaml')
with open('dates/' + date + '.json', 'w') as start:
start.close()
for yml in yml_directory :
print("Running export for " + yml)
yml_file = os.path.join('yaml/' + yml)
json_path = get_json_location()
yml = funcs.read_config(yml_file)
data_folder = date
gen_json.generate_data_report(json_path , yml , data_folder)
if __name__ == '__main__':
main()
test_files.py
import generate_report as generate_reportt
def compare_filesets(file_names, previous_data, current_data):
for item in file_names:
print(item + generate_reportt.compare(previous_data.get(item), current_data.get(item)) + "\n")
def test_filesets():
'''
Test for scenario 1
'''
dict_1 = generate_reportt.read_file_into_dict("dates/2018-01-01.json")
dict_2 = generate_reportt.read_file_into_dict("dates/2018-01-02.json")
print(" Test 1 ")
compare_filesets(file_names=['a.json', 'b.json', 'c.json'],
previous_data=dict_1,
current_data=dict_2
)
This is why using the statement:
if __name__ == "__main__":
main()
is very important. You will want to add this to the script you're importing, and put all of your code that is being called within a main() function in that script. The variable __name__ of a script changes depending on whether the script is imported or not. If you're not importing the script and running it, then that script's __name__ variable will be "__main__". However, if it is imported, the __name__ variable turns into the script's filename, and therefore everything in main() function of that script will not be run.
For more information: What does if __name__ == "__main__": do?
I am looking to build a daemon process that does some tasks when given some input. 99% of the time it lays silent on the background doing nothing and the tasks are short and few in number. How would I build the interface between two applications one of which constructs the task and the daemon that executes it?
I was thinking that the daemon might have a folder which i periodically checks. If there are some files in there, it reads it and follows instructions from there.
Would that work well or is there a better way?
EDIT: added example daemon code.
#!/usr/bin/python
import time
from daemon import runner
class Daemon():
def __init__(self):
self.stdin_path = '/dev/null'
self.stdout_path = '/dev/tty'
self.stderr_path = '/dev/tty'
self.pidfile_path = '/tmp/foo.pid'
self.pidfile_timeout = 5
self.task_dir = os.path.expanduser("~/.todo/daemon_tasks/")
def run(self):
while not time.sleep(1):
if len(os.listdir(self.task_dir)) == 0:
for task in os.listdir(self.task_dir):
self.process_task(task)
def process_task(self, task):
# input: filename
# output: void
# takes task and executes it according to instructions in the file
pass
if __name__ == '__main__':
app = Daemon()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()
I would look into unix sockets of FIFOs as an option. This eliminates need for polling of some directory. Some SO link for help How to create special files of type socket?
I have a python script that opens up file for me in emacs, and to do that it calls a process in xterm like so
"""AutoEmacs Document"""
# imports
import sys
import os
import psutil
import subprocess
from argparse import ArgumentParser
# constants
xlaunch_config = "C:\\cygwin64\\home\\nalis\\Documents\\experiments\\emacs\\Autoemacs\\config.xlaunch"
script = "xterm -display :0 -e emacs-w32 --visit {0}"
# exception classes
# interface functions
# classes
# internal functions & classes
def xlaunch_check():
# checks if an instance of Xlaunch is running
xlaunch_state = []
for p in psutil.process_iter(): #list all running process
try:
if p.name() == 'xlaunch.exe':# once xlaunch is found make an object
xlaunch_state.append(p)
except psutil.Error: # if xlaunch is not found return false
return False
return xlaunch_state != [] #double checks that xlaunch is running
def xlaunch_run(run):
if run == False:
os.startfile(xlaunch_config)
return 0 #Launched
else:
return 1 #Already Running
def emacs_run(f):
subprocess.Popen(script.format(f))
return 0#Launched Sucessfully
def sysarg():
f = sys.argv[1]
il = f.split()
l = il[0].split('\\')
return l[(len(l) - 1)]
def main():
f = sysarg()
xlaunch_running = xlaunch_check()
xlaunch_run(xlaunch_running)
emacs_run(f)
return 0
if __name__ == '__main__':
status = main()
sys.exit(status)
`
and it works fairly fine with the occasional bug, but I want to make it a little more versatile by having python send the Xterm console it launches commands after it launched like "-e emacs-w32" and such based off of the input it receives. I've already tried something like this:
# A test to send Xterm commands
import subprocess
xterm = subprocess.Popen('xterm -display :0', shell=True)
xterm.communicate('-e emacs')
but that doesn't seem to do anything. besides launch the terminal. I've done some research on the matter but it has only left me confused. Some help would be very much appreciated.
To open emacs in terminal emulator, use this:
Linux;
Popen(['xterm', '-e', 'emacs'])
Windows:
Popen(['cmd', '/K', 'emacs'])
For cygwin use:
Popen(['mintty', '--hold', 'error', '--exec', 'emacs'])
I have a small "Hello World" Flask script that takes an output from a program, called rescuetime_api and puts it on a URL /blog. I wanted to run the script in Debug mode and hard-coded it into the top of my program but I was wondering if there is a way to pass this value through from my Bash shell. Thanks in advance for your help.
#Flask tutorial
import rescuetime_api as api
import os
from flask import Flask
app = Flask(__name__)
DEBUG = True
#app.route("/")
def hello():
return "This is my homepage!"
#app.route("/blog")
def blog():
result = api.download_rescuetime_json()[1][1]
return "%s" % result
if __name__ == "__main__":
if os.environ.get("FLASK_TUTORIAL_DEBUG"):
DEBUG = True
print "Running in debug:", DEBUG
app.run(debug=DEBUG)
Your script already checks for the environment variable FLASK_TUTORIAL_DEBUG.
You could just set it in your shell, before executing the program:
export FLASK_TUTORIAL_DEBUG=1
and then run your program:
python myscript.py
And remember to unset the variable when you don't need it:
unset FLASK_TUTORIAL_DEBUG
I am building a simple pyhon daemon based on Sander Marechal's code. Daemon's whole purpose is to run a php file every second (php file loops through database checking values and updating database). Problem arises on the section
subprocess.call(['php','test.php'])
I can run "php test.php" on shell and it does what it is suppose to do but when it is called periodically from the daemon it doesn't seem to be executed. I also know daemon works on the background via checking running process ps aux | grep "daemon-example" also i included a do_something function which records every time function executed and appends time to a text file.
#!/usr/bin/env python
import sys, time,subprocess
from daemon import Daemon
def runphp():
#subprocess.call(['php ~/pydaemon/test.php'], shell=True)
subprocess.call(['python', 'test.py'])
def do_something():
with open("/tmp/current_time.txt",'a') as f:
f.write("The time is now\n" + time.ctime())
class MyDaemon(Daemon):
def run(self):
while True:
time.sleep(1)
do_something()
subprocess.call(['php','test.php'])
#runphp()
if __name__ == "__main__":
daemon = MyDaemon('/tmp/daemon-example.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)
The script you are trying to run is not executed because the working directory is the root directory ('/') and that's because of this piece of code:
# decouple from parent environment
os.chdir("/")
So actually your code tries to execute: python /test.py(which does not exist) and not 'your_current_directory/test.py'.
To fix it either remove os.chdir("/"), or provide the full path to the file like so:
subprocess.call(['python','my_full_path_to_working_directory/test.py'])