So, I create a small program that uses flask to receive some requests and do a few things over selenium. All bits that deal with selenium are in another file that I tried to run first using a thread, and when it did not worked, a process. I believe that the problem is because I use a while true to keep my selenium working. The selenium part knows what to do because it keep checking the variable that I update from them flask part...
This is pretty much my main class that runs the selenium and them start flask, but it never start flask. It get locked on the .start().
if __name__ == "__main__":
# Logging
log_format = '%(asctime)s [%(filename)s:%(lineno)d] %(message)s'
logging.basicConfig(format=log_format,
level=logging.INFO,
stream=sys.stdout)
# Start Selenium
browser = Process(target=selenium_file.run_stuff())
browser.start()
print('TEST')
# Flask
app.run(debug=True)
Not really sure how I could solve this problem (if it's a problem)...
Exchange browser = Process(target=selenium_file.run_stuff()) with browser = Process(target=selenium_file.run_stuff)
You don't pass the function run_stuff but you already execute it and hence it blocks your program until run_stuff returns.
By starting the main, I´m starting a thread that keeps a connection to a opcua server alive (and a few things more).
I now want to open a function inside this thread but I don´t want to import everything again (because it takes to long).
In if __name__ == "__main__":
it is working, but when I run a second script goIntoThread.py, it is not working. Obviously because I didn´t import the modules...
What are my options to trigger e.g. thd.doSomethingInThread() without importing everything again?
Thnaks alot!
main.py
import time
def importOnlyMain():
global KeepConnected
from keepConnected import KeepConnected
if __name__ == "__main__":
importOnlyMain()
global thd
thd = KeepConnected()
thd.start()
time.sleep(3)
thd.doSomethingInThread()
def goIntoThread():
print("Going to Thread")
thd.doSomethingInThread()
goIntoThread.py
import main
main.goIntoThread()
Copy Comment: I get the following error:
thd.setBool()
NameError: global name 'thd' is not defined
I have a web application built on bottle(python) frame work and I want to run it in daemon mode.Is there any way to run it in daemon mode
Thanks
Sure you can. Install BottleDaemon 0.1.0 on your OS and than change your router file like so:
from bottledaemon import daemon_run
from bottle import route
#route("/hello")
def hello():
return "Hello World"
# The following lines will call the BottleDaemon script and launch a daemon in the background.
if __name__ == "__main__":
daemon_run()
I am preparing a web service using django in python. When I start web service, I would like to have a main function to run. However, code below did not work in web service. I want to have an initializer function which will fill the structures defined global. I can achieve it by directly defining an init function and call it end of the module but I don't know whether this is the proper way of doing so.
if __name__ == '__main__':
main()
Here similar question was posted. As I understand there is no clear solution for that and I find my way to do this. I defined a dummy function in web service module like:
def warmup(request):
response = HttpResponse()
response.write("ok")
return response
We start application with command sudo python manage.py runserver 0.0.0.0:8081 so I add a piece of code in manage.py such that:
#!/usr/bin/env python
import os
import sys
import requests
import threading
import time
def warmup_request():
print "warmup.."
time.sleep(1)
try:
r = requests.get("http://localhost:8081/warmup/")
if r.content == "ok":
return
except Exception, e:
pass
threading.Timer(0,warmup_request).start()
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
from django.core.management import execute_from_command_line
warmup_request()
execute_from_command_line(sys.argv)
If warmup service API returns ok it means loading initial data process has finished. By defining a global flag, we can block all other service API requests before warming up has finished. Or instead defining global flag we may use request_started signal stated here to block all incoming requests with more little effort.
I have a Django app in which the users can create reports at various places throughout the webapp. As a little nifty feature I would like to make a "send as PDF" feature for these reports, and I'm almost there.
What I do is that before the report is returned as a HttpResponse through Django I send the raw HTML content through a small PySide/QT snippet (as seen below).
The problem is that I can't get the QApplication to quit.
I have tried with the standard QCoreApplication.exit() but with no luck. If I try to convert a new report right after the first one, the console says a "QApplication instance already exists".
I am using Django 1.2.5, Python 2.7, QT 4.8 and PySide 1.1 on OS X 10.7.3 (for testing).
Code:
def makepdf(response,filename):
try:
app = QApplication(sys.argv)
except:
app = QCoreApplication.instance()
web = QWebView()
stylelink = "%s%s" % (media_root,'images/css/reportGenerator.css')
web.settings().setUserStyleSheetUrl(QUrl.fromLocalFile(stylelink))
web.setHtml(response)
printer = QPrinter()
printer.setPageSize(QPrinter.A4)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(filename)
def convertToPdf():
web.print_(printer)
#webresponse = web.close()
#QObject.disconnect()
#print QCoreApplication.instance().children()[0].interrupt()
#qthread = QCoreApplication.instance().thread()#.cleanup()
#qthread.exit()
QCoreApplication.exit()
QObject.connect(web, SIGNAL("loadFinished(bool)"), convertToPdf())
Code comments:
Currently I have made a try/except clause to be able to keep the code running, by using the current QApplication instance (to avoid the 'instance exists error'), but this just doesn't seem right?. I mean, having a QAppliation running for the duration of my Apache server (which will be the case in production) seems a bit off. Shouldn't it be possible to quit it after the PDF conversion is done?
Other than the QCoreApplication.exit() I have tried to use the sys.exit(app.exec_()) method, as is often seen in examples and snippets. This however just causes an error and makes Python crash and the code works perfectly without this. (well it creates the PDF, but won't quit).
All the lines commented out are the previous attempts I have made to quit the QApplication.
In short: I don't know what it is, but it just won't quit. Can anyone suggest why?
Update: After the latest answer I have edited the code to respond to the input. This is how the final part looks now:
def convertToPdf():
web.print_(printer)
app.exit()
web.loadFinished.connect(convertToPdf)
app.exec_()
I do, however, still get an error:
2012-04-30 00:16:10.791 Python[21241:1803] * Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-833.24/Misc.subproj/NSUndoManager.m:324
Qt has caught an exception thrown from an event handler. Throwing exceptions from an event handler is not supported in Qt. You must reimplement QApplication::notify() and catch all exceptions there.
This error only occurs when I implement app.exec_(). However without app.exec_() it is just the normal issue again, with no quitting.
Any ideas?
Update 2: this is the newest code, fixed in accordance with matas latest suggestion:
app = QApplication(sys.argv)
web = QWebView()
printer = QPrinter()
printer.setPageSize(QPrinter.A4)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(filename)
def convertToPdf():
web.print_(printer)
app.exit()
web.loadFinished.connect(convertToPdf)
web.setHtml(response)
I still have the same problem however.
what i can say is this:
QObject.connect(web, SIGNAL("loadFinished(bool)"), convertToPdf())
here you call convertToPdf(), if you want to connect the signal, omit the parenthesis!
you could also use this much clearer syntax:
web.loadFinished.connect(convertToPdf)
you may also want to add a parameter to convertToPdf, as it is called with a boolean indicating wheather loading was successful or not.
And using app.exit() should be enough.
oh, and when you use Gui-Components you need to use a QApplication. A QCoreApplication won't do!
edit: it's important to call web.setHtml after you've connected the loadFinished signal! otherwise if the loading already is finished, your function will never be executed!
edit: this works without any problem for me:
#!/usr/bin/env python
from PySide.QtGui import *
from PySide.QtWebKit import *
import sys
from subprocess import Popen, PIPE
def createPdf(html, filename):
app = QApplication(sys.argv)
web = QWebView()
printer = QPrinter()
printer.setPageSize(QPrinter.A4)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(filename)
def convertToPdf():
web.print_(printer)
app.exit()
app.deleteLater()
web.loadFinished.connect(convertToPdf)
web.setHtml(html)
app.processEvents()
def createPdfInSubprocess(html, filename):
p = Popen(["python", __file__, filename],
stdin=PIPE, stdout=PIPE, stderr=PIPE)
out, err = p.communicate(html)
return (p.returncode, out, err)
if __name__ == '__main__':
if len(sys.argv) > 1:
# read html from stdin, filename from cmdline
html = "\n".join(sys.stdin.readlines())
createPdf(html, sys.argv[1])
# print("done")
else:
# test if it's working
ret = createPdfInSubprocess(
"<html><h1>test</h1>it's working...</html>", "test.pdf")
print(ret)
Even without all the calls to app.exit(), app.deleteLater(), app.processEvents(), it still works... but can't hurt to have that.
One more important thing: QApplications have to be created from the main thread! So if it's running inside a django app it's probably not going to work, that's why i added the subprocess stuff...
PySide is designed such that there is only ever one instance of QCoreApplication within a process. The best reference to this (possibly undocumented fact) that I could find was http://bugs.pyside.org/show_bug.cgi?id=855.
Basically, there may be dangling references to the qapplication that prevent it from being reaped by the garbage collector, so even if you tell the application to exit and you delete your reference, there may still be other references lying around.