Created
August 31, 2017 23:16
-
-
Save ocomsoft/ea581b172b72b23a1bcede21d9c76ee7 to your computer and use it in GitHub Desktop.
Run Django in pywebview and CherryPy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Inspired by https://gist.github.com/nigma/4349257 and https://github.com/r0x0r/pywebview/blob/master/examples/flask_app/src/backend/main.py | |
import os | |
import webbrowser | |
from time import sleep | |
import django | |
from threading import Timer, Thread | |
import logging | |
import webview | |
os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production" | |
import cherrypy | |
django.setup() | |
from django.conf import settings | |
from django.core.handlers.wsgi import WSGIHandler | |
logger = logging.getLogger(__name__) | |
class DjangoApplication(object): | |
HOST = "127.0.0.1" | |
PORT = 8001 | |
def mount_static(self, url, root): | |
""" | |
:param url: Relative url | |
:param root: Path to static files root | |
""" | |
config = { | |
'tools.staticdir.on': True, | |
'tools.staticdir.dir': root, | |
'tools.expires.on': True, | |
'tools.expires.secs': 86400 | |
} | |
cherrypy.tree.mount(None, url, {'/': config}) | |
def open_browser(self): | |
# Wait for server to be UP! | |
while not self.url_ok(self.HOST, self.PORT): | |
sleep (0.1) | |
#Timer(3, webbrowser.open, ("http://%s:%s" % (self.HOST, self.PORT),)).start() | |
webview.create_window("Ocom App", "http://%s:%s" % (self.HOST, self.PORT), min_size=(800, 600)) | |
def url_ok(self, url, port): | |
# Use httplib on Python 2 | |
try: | |
from http.client import HTTPConnection | |
except ImportError: | |
from httplib import HTTPConnection | |
try: | |
conn = HTTPConnection(url, port) | |
conn.request("GET", "/dockerStatus/") | |
r = conn.getresponse() | |
return r.status == 200 | |
except: | |
logger.exception("Server not started") | |
return False | |
def run(self): | |
cherrypy.config.update({ | |
'server.socket_host': self.HOST, | |
'server.socket_port': self.PORT, | |
'engine.autoreload_on': False, | |
'log.screen': True | |
}) | |
self.mount_static(settings.STATIC_URL, settings.STATIC_ROOT) | |
self.mount_static(settings.MEDIA_URL, settings.MEDIA_ROOT) | |
cherrypy.log("Loading and serving Django application") | |
cherrypy.tree.graft(WSGIHandler()) | |
cherrypy.engine.start() | |
t = Thread(target=self.open_browser) | |
t.daemon = True | |
t.start() | |
cherrypy.engine.block() | |
if __name__ == "__main__": | |
DjangoApplication().run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Add to Requirements.txt | |
pywebview[qt5]==1.7 # On Linux.. | |
CherryPy==11.0.0 |
@rocchidavide I (stole) copied most of that code from here https://gist.github.com/nigma/4349257 not sure why they used that.
I can't remember now but I think based on line 78 it was the WSGI server.. HTH
@ocomsoft Did you manage to get it work in recent versions of Django
@kachmul2004 Sorry I have not tried.
The following works with Django 4.2. In DEBUG mode Django servers the static files. Otherwise one would need CherryPy.
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import webview
from threading import Thread
from time import sleep
from http.client import HTTPConnection
host = "127.0.0.1"
port = 8000
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'playground.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
t = Thread(target=execute_from_command_line, args=(["manage.py", "runserver", "--noreload"],))
t.daemon = True
t.start()
while not url_ok(host, port):
sleep(0.1)
webview.create_window("MyApp", f"http://{host}:{port}", min_size=(980, 1000))
webview.start()
def url_ok(host: str, port: int):
try:
conn = HTTPConnection(host, port)
conn.request("GET", "/")
r = conn.getresponse()
return r.status == 200
except:
# Server not started
return False
if __name__ == '__main__':
main()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great but why use CherryPy with Django? I miss the point