Apache Django Mod_Wsgi - auto reload - django

I am trying to auto reload my django app which uses apache + mod_wsgi on my local windows machine.
I'd like to know where do I add this code that's referenced in the following article:
http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode
def _restart(path):
_queue.put(True)
prefix = 'monitor (pid=%d):' % os.getpid()
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
print >> sys.stderr, '%s Triggering Apache restart.' % prefix
import ctypes
ctypes.windll.libhttpd.ap_signal_parent(1)

Read:
http://blog.dscpl.com.au/2008/12/using-modwsgi-when-developing-django.html
It tells you exactly where to place the file when using Django. You just need to make the code change that everyone is pointing out to you in the source code reloading documentation section related to Windows. Also read:
http://blog.dscpl.com.au/2009/02/source-code-reloading-with-modwsgi-on.html
which explains the variations on the first related to Windows.

You replace the restart function that is mentioned in the block of code above in the same article.

I use this code on my server
touch site.wsgi
and it work. After reload page in browser I get page with changes.
May be it ugly - but simple and no necessary restart apache.

In your Virtual Host config file add this:
WSGIScriptReloading On
And reload Apache
systemctl reload apache2
Enjoy!
Reference https://flask.palletsprojects.com/en/1.1.x/deploying/mod_wsgi/

You replace the restart function in the following block of code you find on the page:
Monitoring For Code Changes
The use of signals to restart a daemon process could also be employed in a mechanism which automatically detects changes to any Python modules or dependent files. This could be achieved by creating a thread at startup which periodically looks to see if file timestamps have changed and trigger a restart if they have.
Example code for such an automatic restart mechanism which is compatible with how mod_wsgi works is shown below.
import os
import sys
import time
import signal
import threading
import atexit
import Queue
_interval = 1.0
_times = {}
_files = []
_running = False
_queue = Queue.Queue()
_lock = threading.Lock()
def _restart(path):
_queue.put(True)
prefix = 'monitor (pid=%d):' % os.getpid()
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
print >> sys.stderr, '%s Triggering process restart.' % prefix
os.kill(os.getpid(), signal.SIGINT)

I test this with Bitnami DjangoStack http://bitnami.org/stack/djangostack and Windows XP installed on D:\BitNami DjangoStack and C:\Documents and Settings\tsurahman\BitNami DjangoStack projects\myproject as project directory (default install)
as in http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Restarting_Apache_Processes, I added
MaxRequestsPerChild 1
in file D:\BitNami DjangoStack\apps\django\conf\django.conf
see comment by Graham Dumpleton
then I created a file monitor.py in my project directory with content as in http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring_For_Code_Changes and replace the _restart method with http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Restarting_Windows_Apache, here is the part of the script
....
_running = False
_queue = Queue.Queue()
_lock = threading.Lock()
def _restart(path):
_queue.put(True)
prefix = 'monitor (pid=%d):' % os.getpid()
print >> sys.stderr, '%s Change detected to \'%s\'.' % (prefix, path)
print >> sys.stderr, '%s Triggering Apache restart.' % prefix
import ctypes
ctypes.windll.libhttpd.ap_signal_parent(1)
def _modified(path):
try:
....
and in file D:\BitNami DjangoStack\apps\django\scripts\django.wsgi,
....
import django.core.handlers.wsgi
import monitor
monitor.start(interval=1.0)
monitor.track(os.path.join(os.path.dirname(__file__), 'site.cf'))
application = django.core.handlers.wsgi.WSGIHandler()
and then restart the Apache server

Related

Error ALDialog Python Nao

I have a problem when using the ALDialog module on Python IDE and to load on Nao. I tried in different ways to load a dialogue but I always fall back on the same error.Runtimeerror LoadTopic::ALDialogIncorrect file myDialog.topIn the first case I write directly the text that I save in a. top file but at the time of LoadTopic () I have an error.In the second case I want to load the. top file by giving it the path. I come back to the same mistake again.Do you have a solution to my problem?Thank you very much.
import qi
import argparse
import os
import sys
from naoqi import ALProxy
def main(robot_ip, robot_port):
dialog = """
topic: ~myTopic() \n
language: enu \n
u:(test) hello \n """
file = open("myDialog.top","w")
file.write(dialog)
file.close()
# load topic
proxy = ALProxy("ALDialog",robot_ip,robot_port)
proxy.setLanguage("English")
self.topic = proxy.loadTopic("myDialog.top")
# start dialog
proxy.subscribe("myModule")
# activate dialog
proxy.activateTopic(self.topic)
if name == "main":
parser = argparse.ArgumentParser()
parser.add_argument("--ip", type=str,
default="169.254.245.164",help="Robot's IP address : '169.254.245.164'")
parser.add_argument("--port", type=int, default=9559,help="port number, the default value is OK in most cases")
args = parser.parse_args()
main(args.ip, args.port)
ALDialog.loadTopic expects an absolute filepath on the robot - it doesn't know anything about the context from which you're calling it (it could be from another computer, in which case of course it can't open that file). You need to be sure that your .top is indeed on the robot, and pass it's absolute path to ALDialog.
Once installed on the robot this path will be something like /home/nao/.local/share/PackageManager/apps/your-package-id/your-dialog-name/your-dialog-name_enu.top

Running script with fixed internal commands arguments to include Qwebengine pepflashplayer

I made a PyQt5 QWebengine app i wanna make portable.
I found out that flash weren't working in the app.
After a lot of reading i found out that having pepflashplayer64_*.dll & manifest.json in folder
C:\Windows\System32\Macromed\Flash\ is working.
However i wanna ship the pepflashplayer with app, and
adding custom flash folder to PATH env var, do not have effect , or
sys.path.insert()
the command
myapp.py --ppapi-flash-path=C:\Flash\pepflashplayer64_27_0_0_187.dll
works , but how to pass extra augments internally when script is launched ?
i tried dirty hack to run sys.arg[0] script with extra command but no success.
if __name__ == "__main__":
# print sys.argv
flash = (' --ppapi-flash-path=C:\Flash\pepflashplayer64_27_0_0_187.dll').split()
# print flash
noooo = (sys.argv[0] + flash[0]).split()
import sys
app = QtWidgets.QApplication(noooo)
# ... the rest of your handling: `sys.exit(app.exec_())`, etc.
okay i got it to work so i can make app the app with browser portable , and solution was simpler than i thought.
Parsing second internal argument like this.
if __name__ == "__main__":
programname = os.path.dirname(sys.argv[0]) #get current script full folder path
pepperpflash = ' --ppapi-flash-path=' + programname + '/Flash/pepflashplayer64_27_0_0_187.dll'
try:
app = QtWidgets.QApplication(sys.argv + [pepperpflash])
except:
app = QtWidgets.QApplication(sys.argv)
# ... the rest of your handling: `sys.exit(app.exec_())`, etc.

P4Python Perforce API does not honor P4_TRUST when running as a Collectd Python (2.7) Plugin

Using Collectd Python Plugin to collect Graphite Metrics from Perforce using their P4Python API. All is good with the exception of ssl based connections which require a P4_TRUST command to assert the fingerprint for the given server prior to the login() command.
Specifically:
import collectd
from P4 import P4
def configer(configobj):
collectd.info('Configuring Perforce Plugin')
def initer():
collectd.info('Initializing Perforce Plugin')
def reader():
p4 = P4()
p4.port = "ssl:perforce1.lab.dell.com:1666"
p4.user = "perforce"
p4.charset = 'utf8'
p4.password = "Password"
p4.connect()
p4.run_trust("-i", '60:27:3E:E0:A6:58:8E:13:4F:9E:8C:C8:BF:C3:26:C2:91:2F:78:33')
p4.run_login()
result = p4.run('license', '-u')
collectd.info("User limit is :" + result[0].get('userLimit'))
#
p4.disconnect()
# -- Hook Callbacks, Order is important! ==#
collectd.register_config(configer)
collectd.register_init(initer)
collectd.register_read(reader)
will result in the following run time errors noted in collectd.log
`[2017-04-27 11:33:58] Unhandled python exception in read callback: P4Exception: [P4#run] Errors during command execution( "p4 login" )
[Error]: "The authenticity of '10.99.248.42:1666' can't be established,\nthis may be your first attempt to connect to this P4PORT.\nThe fingerprint for the key sent to your client is\n60:27:3E:E0:A6:58:8E:13:4F:9E:8C:C8:BF:C3:26:C2:91:2F:78:33\nTo allow connection use the 'p4 trust' command."
[2017-04-27 11:33:58] read-function of plugin `python.PerforceMetrics' failed. Will suspend it for 20.000 seconds.
`
The same code run outside the collectd context runs as expected.
from P4 import P4
import logging
FORMAT = '%(asctime)-15s: %(name)s: %(levelname)s : %(message)s'
logging.basicConfig(format=FORMAT, filename='/var/log/pytest.log', level=logging.INFO)
def reader():
p4 = P4()
p4.port = "ssl:perforce1.cec.lab.emc.com:1666"
p4.user = "perforce"
p4.charset = 'utf8'
p4.password = "Password"
p4.connect()
p4.run_trust("-i", '80:25:3E:E0:A6:58:8E:13:4F:9E:8C:C8:BF:C3:26:C2:91:2F:78:33')
p4.run_login()
result = p4.run('license', '-u')
logging.info ("User limit is :" + result[0].get('userLimit'))
#
p4.disconnect()
reader()
NOTE: None SSL connections that do not require "P4 Trust" work correctly under collectd.
Any clues, idea's or how to approach this?
Okay so worked with Perforce support and while they struggled with getting collectd running they did point me in the right direction. Specifically P4TRUST as an environment variable can be defined that points to the .p4trust file that is typically used and by default created with the application of the p4.run_trust p4Python API call.
So the trick is to define the environment P4TRUST environment variable with in your python plugin:
import collectd
import os
from P4 import P4
def configer(configobj):
collectd.info('Configuring Perforce Plugin')
def initer():
collectd.info('Initializing Perforce Plugin')
def reader():
os.environ["P4TRUST"]="/root/.p4trust"
p4 = P4()
p4.port = "ssl:perforce1.lab.dell.com:1666"
p4.user = "perforce"
p4.charset = 'utf8'
p4.password = "Password"
p4.connect()
p4.run_trust("-i", '60:27:3E:E0:A6:58:8E:13:4F:9E:8C:C8:BF:C3:26:C2:91:2F:78:33')
p4.run_login()
result = p4.run('license', '-u')
collectd.info("User limit is :" + result[0].get('userLimit'))
#
p4.disconnect()
# -- Hook Callbacks, Order is important! ==#
collectd.register_config(configer)
collectd.register_init(initer)
collectd.register_read(reader)
Note: the inclusion of the os library and the use of
os.environ["P4TRUST"]="/root/.p4trust"
That's the ticker!

Why is python-pdfkit hanging on printing page with OpenLayers3 content when run with uWSGI and NGINX?

I'm using Django served by uWSGI and NGINX.
Ubuntu 14.04.1 LTS 64-bit
Python 3.4
Django 1.7.4
uWSGI 1.9.17.1-debian (64bit)
NGINX 1.4.6
python-pdfkit 0.5.0
wkhtmltopdf 0.12.2.1
OpenLayers v3.0.0
When I try running pdfkit.from_url(...) to print a map to pdf the request times out.
More specifically it hangs in python's subprocess.py communicate, self._communicate:
with _PopenSelector() as selector:
if self.stdin and input:
selector.register(self.stdin, selectors.EVENT_WRITE)
if self.stdout:
selector.register(self.stdout, selectors.EVENT_READ)
if self.stderr:
selector.register(self.stderr, selectors.EVENT_READ)
while selector.get_map():
...
selector.get_map() always returns a valid result, ensuring an infinite loop.
If I run this in the Django development server (instead of uWSGI+NGINX) everything runs fine.
in my view:
wkhtmltopdfBinLocationString = '/usr/local/bin/wkhtmltopdf'
wkhtmltopdfBinLocationBytes = wkhtmltopdfBinLocationString.encode('utf-8')
#this fixes some leftover python2 assumptions about strings
config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdfBinLocationBytes)
pdfkit.from_url(reportPdfUrl, reportPdfFile, configuration=config, options={
'javascript-delay': 1500
})
Several places I have seen answers along the line of "set the close-on-exec flag on the socket" solving similar issues.
Is this something I can set from my "from_url" options (wkhtmltopdf does not accept it by that name) or can I configure uWSGI to assume 'close-on-exec'? I have not been able to make either of these work, but maybe I just need help with changing my uWSGI customization file:
[uwsgi]
workers = 1
chdir = [...]
plugins = python34
wsgi-file = [...]/wsgi.py
pythonpath = [...]
I tried something like
close-on-exec = true
but that didn't seem to do anything.
NOTE: the wsgi.py file is simple:
"""
WSGI config for dst project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "[my_project].settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Any thoughts?

django with twisted web - wgi and vhost

I have a project which has a directory setup like:
myproject
someapp
sites
foo
settings.py - site specific
settings.py - global
I am using twisted web.wsgi to serve this project. The problem am I running into is setting up the correct environment.
import sys
import os
from twisted.application import internet, service
from twisted.web import server, resource, wsgi, static, vhost
from twisted.python import threadpool
from twisted.internet import reactor
from django.core.handlers.wsgi import WSGIHandler
from django.core.management import setup_environ,ManagementUtility
sys.path.append(os.path.abspath("."))
sys.path.append(os.path.abspath("../"))
DIRNAME= os.path.dirname(__file__)
SITE_OVERLOADS = os.path.join(DIRNAME,'sites')
def import_module(name):
mod = __import__(name)
components = name.split('.')
for comp in components[1:]:
mod = getattr(mod,comp)
return mod
def buildServer():
hosts = [d for d in os.listdir(SITE_OVERLOADS) if not os.path.isfile(d) and d != ".svn"]
root = vhost.NameVirtualHost()
pool = threadpool.ThreadPool()
pool.start()
reactor.addSystemEventTrigger('after', 'shutdown', pool.stop)
for host in hosts:
settings = os.path.join(SITE_OVERLOADS,"%s/settings.py" % host)
if os.path.exists(settings):
sm = "myproject.sites.%s.settings" % host
settings_module = import_module(sm)
domain = settings_module.DOMAIN
setup_environ(settings_module)
utility = ManagementUtility()
command = utility.fetch_command('runserver')
command.validate()
wsgi_resource = wsgi.WSGIResource(reactor,pool,WSGIHandler())
root.addHost(domain,wsgi_resource)
return root
root = buildServer()
site = server.Site(root)
application = service.Application('MyProject')
sc = service.IServiceCollection(application)
i = internet.TCPServer(8001, site)
i.setServiceParent(sc)
I am trying to setup vhosts for each site which has a settings module in the subdirectory "sites". However, it appears that the settings are being shared for each site.
Django projects within the same Python process will share the same settings. You will need to spawn them as separate processes in order for them to use separate settings modules.
Since your goal is a bunch of shared-nothing virtual hosts, you probably won't benefit from trying to set up your processes in anything but the simplest way. So, how about changing your .tac file to just launch a server for a single virtual host, starting up a lot of instances (manually, with a shell script, with another simple Python script, etc), and then putting a reverse proxy (nginx, Apache, even another Twisted Web process) in front of all of those processes?
You could do this all with Twisted, and it might even confer some advantages, but for just getting started you would probably rather focus on your site than on minor tweaks to your deployment process. If it becomes a problem that things aren't more integrated, then that would be the time to revisit the issue and try to improve on your solution.