فهرست منبع

Merge branch 'main' into debug_timer

Falko Schindler 4 سال پیش
والد
کامیت
c11971c0f9
8فایلهای تغییر یافته به همراه143 افزوده شده و 17 حذف شده
  1. 1 1
      Dockerfile
  2. 23 0
      README.md
  3. 3 1
      main.py
  4. 1 1
      nice_gui/__init__.py
  5. 16 13
      nice_gui/nice_gui.py
  6. 56 0
      nicegui
  7. 42 1
      poetry.lock
  8. 1 0
      pyproject.toml

+ 1 - 1
Dockerfile

@@ -13,4 +13,4 @@ WORKDIR /app
 COPY ./pyproject.toml ./poetry.lock* main.py ./
 RUN poetry install --no-root
 
-CMD uvicorn --reload --host 0.0.0.0 --port 80 main:ui
+CMD ./nicegui main.py

+ 23 - 0
README.md

@@ -0,0 +1,23 @@
+# Nice GUI
+
+# Usage
+
+Write your nice GUI in a file `main.py`:
+
+    import nice_gui
+
+    ui = nice_gui.Ui()
+    ui.label('Hello Nice GUI!')
+    ui.Button('BUTTON', on_click: lambda: print('button was pressed'))
+
+Launch it with
+
+    python3 main.py
+
+Or use with autoreloading by calling
+
+    nicegui main.py
+
+# Full Example
+
+See [main.py](https://github.com/zauberzeug/nice_gui/blob/main/main.py)

+ 3 - 1
main.py

@@ -1,9 +1,11 @@
 #!/usr/bin/env python3
-from nice_gui import ui
+import nice_gui
 from datetime import datetime
 from matplotlib import pyplot as plt
 import numpy as np
 
+ui = nice_gui.Ui()
+
 with ui.row():
     with ui.card():
         ui.label('Interactive elements', 'h5')

+ 1 - 1
nice_gui/__init__.py

@@ -1 +1 @@
-from nice_gui.nice_gui import ui
+from nice_gui.nice_gui import Ui

+ 16 - 13
nice_gui/nice_gui.py

@@ -9,6 +9,7 @@ import asyncio
 from contextlib import contextmanager
 from matplotlib import pyplot as plt
 from .utils import handle_exceptions, provide_arguments
+from multiprocessing import Process
 
 wp = jp.QuasarPage(delete_flag=False, title='Nice GUI', favicon='favicon.png')
 wp.head_html = '<script>confirm = () => true;</script>'  # HACK: avoid confirmation dialog for reload
@@ -91,6 +92,20 @@ class LinePlot(Plot):
 
 class Ui(Starlette):
 
+    def __init__(self):
+        # NOTE: we enhance our own ui object with all capabilities of jp.app
+        self.__dict__.update(jp.app.__dict__)
+
+        self.tasks = []
+
+        @self.on_event('startup')
+        def startup():
+            [jp.run_task(t) for t in self.tasks]
+
+    def run(self):
+
+        uvicorn.run(self, host='0.0.0.0', port=80, lifespan='on', reload=False)
+
     def label(self, text='', typography=[]):
 
         if isinstance(typography, str):
@@ -221,16 +236,4 @@ class Ui(Starlette):
                     traceback.print_exc()
                     await asyncio.sleep(interval)
 
-        jp.run_task(timeout() if once else loop())
-
-    def run(self):
-
-        # NOTE: prevent reloader from restarting uvicorn
-        if inspect.stack()[-2].filename.endswith('spawn.py'):
-            return
-
-        uvicorn.run('nice_gui:ui', host='0.0.0.0', port=80, lifespan='on', reload=True)
-
-# NOTE: instantiate our own ui object with all capabilities of jp.app
-ui = Ui()
-ui.__dict__.update(jp.app.__dict__)
+        self.tasks.append((timeout() if once else loop()))

+ 56 - 0
nicegui

@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+"""modified copy of https://github.com/stevekrenzel/autoreload/blob/master/autoreload"""
+
+import os
+import sys
+import subprocess
+import time
+import psutil
+
+def file_filter(name):
+    return (not name.startswith(".")) and (not name.endswith(".swp"))
+
+
+def file_times(path):
+    for top_level in filter(file_filter, os.listdir(path)):
+        for root, dirs, files in os.walk(top_level):
+            for file in filter(file_filter, files):
+                yield os.stat(os.path.join(root, file)).st_mtime
+
+
+def print_stdout(process):
+    stdout = process.stdout
+    if stdout != None:
+        print(stdout)
+
+
+# We concatenate all of the arguments together, and treat that as the command to run
+command = " ".join(sys.argv[1:])
+command = 'python3 ' + command
+
+# The path to watch
+path = "."
+
+# How often we check the filesystem for changes (in seconds)
+wait = 1
+
+# The process to autoreload
+process = subprocess.Popen(command, shell=True)
+
+# The current maximum file modified time under the watched directory
+last_mtime = max(file_times(path))
+
+
+while True:
+    max_mtime = max(file_times(path))
+    print_stdout(process)
+    if max_mtime > last_mtime:
+        last_mtime = max_mtime
+        print(f'Restarting {process}.')
+        new = subprocess.Popen(command, shell=True)
+        time.sleep(0.5)
+        for child in psutil.Process(process.pid).children(recursive=True):
+            child.kill()
+        process.kill()
+        process = new
+    time.sleep(wait)

+ 42 - 1
poetry.lock

@@ -251,6 +251,17 @@ category = "main"
 optional = false
 python-versions = ">=3.6"
 
+[[package]]
+name = "psutil"
+version = "5.8.0"
+description = "Cross-platform lib for process and system monitoring in Python."
+category = "main"
+optional = false
+python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+
+[package.extras]
+test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"]
+
 [[package]]
 name = "pycodestyle"
 version = "2.7.0"
@@ -361,7 +372,7 @@ python-versions = ">=3.6.1"
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.9"
-content-hash = "f1bccf6df9f54f60fa5b35168d34038a8d38f80cd84eb624a4563174c9547fc1"
+content-hash = "4aac483c4224c87270e69bff783cbad6256da6f7e330a7c0925868695aa20f4a"
 
 [metadata.files]
 addict = [
@@ -663,6 +674,36 @@ pillow = [
     {file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
     {file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
 ]
+psutil = [
+    {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"},
+    {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"},
+    {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"},
+    {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"},
+    {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"},
+    {file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"},
+    {file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"},
+    {file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"},
+    {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"},
+    {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"},
+    {file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"},
+    {file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"},
+    {file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"},
+    {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"},
+    {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"},
+    {file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"},
+    {file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"},
+    {file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"},
+    {file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"},
+    {file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"},
+    {file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"},
+    {file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"},
+    {file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"},
+    {file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"},
+    {file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"},
+    {file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"},
+    {file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"},
+    {file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"},
+]
 pycodestyle = [
     {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
     {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},

+ 1 - 0
pyproject.toml

@@ -11,6 +11,7 @@ justpy = "0.1.5"
 icecream = "^2.1.0"
 matplotlib = "^3.4.1"
 autopep8 = "^1.5.7"
+psutil = "^5.8.0"
 
 [tool.poetry.dev-dependencies]
 debugpy = "^1.3.0"