Explorar o código

sort imports and other formatting improvements

Falko Schindler %!s(int64=3) %!d(string=hai) anos
pai
achega
2f562a3c31
Modificáronse 63 ficheiros con 311 adicións e 274 borrados
  1. 10 10
      .vscode/settings.json
  2. 0 11
      custom_test.py
  3. 4 2
      examples.py
  4. 10 5
      main.py
  5. 0 3
      nicegui.code-workspace
  6. 1 1
      nicegui/__init__.py
  7. 11 2
      nicegui/binding.py
  8. 5 3
      nicegui/config.py
  9. 5 7
      nicegui/elements/bool_element.py
  10. 4 6
      nicegui/elements/button.py
  11. 3 0
      nicegui/elements/card.py
  12. 3 1
      nicegui/elements/chart.py
  13. 4 6
      nicegui/elements/checkbox.py
  14. 6 8
      nicegui/elements/choice_element.py
  15. 2 0
      nicegui/elements/colors.py
  16. 2 0
      nicegui/elements/column.py
  17. 2 0
      nicegui/elements/custom_example.py
  18. 4 2
      nicegui/elements/custom_view.py
  19. 3 4
      nicegui/elements/dialog.py
  20. 5 5
      nicegui/elements/element.py
  21. 5 8
      nicegui/elements/float_element.py
  22. 5 1
      nicegui/elements/group.py
  23. 6 4
      nicegui/elements/html.py
  24. 3 3
      nicegui/elements/icon.py
  25. 3 4
      nicegui/elements/image.py
  26. 6 8
      nicegui/elements/input.py
  27. 9 3
      nicegui/elements/interactive_image.py
  28. 7 7
      nicegui/elements/joystick.py
  29. 3 7
      nicegui/elements/keyboard.py
  30. 3 4
      nicegui/elements/label.py
  31. 3 8
      nicegui/elements/line_plot.py
  32. 4 4
      nicegui/elements/link.py
  33. 7 2
      nicegui/elements/log.py
  34. 5 4
      nicegui/elements/markdown.py
  35. 3 4
      nicegui/elements/menu.py
  36. 2 6
      nicegui/elements/menu_item.py
  37. 3 7
      nicegui/elements/notify.py
  38. 7 9
      nicegui/elements/number.py
  39. 3 1
      nicegui/elements/open.py
  40. 4 1
      nicegui/elements/page.py
  41. 3 5
      nicegui/elements/plot.py
  42. 5 7
      nicegui/elements/radio.py
  43. 2 0
      nicegui/elements/row.py
  44. 16 10
      nicegui/elements/scene.py
  45. 5 1
      nicegui/elements/scene_object3d.py
  46. 13 0
      nicegui/elements/scene_objects.py
  47. 6 8
      nicegui/elements/select.py
  48. 5 4
      nicegui/elements/slider.py
  49. 5 7
      nicegui/elements/string_element.py
  50. 5 4
      nicegui/elements/svg.py
  51. 4 6
      nicegui/elements/switch.py
  52. 5 7
      nicegui/elements/toggle.py
  53. 5 7
      nicegui/elements/upload.py
  54. 5 8
      nicegui/elements/value_element.py
  55. 12 2
      nicegui/events.py
  56. 5 2
      nicegui/globals.py
  57. 3 0
      nicegui/lifecycle.py
  58. 7 3
      nicegui/nicegui.py
  59. 6 2
      nicegui/routes.py
  60. 5 2
      nicegui/run.py
  61. 1 2
      nicegui/task_logger.py
  62. 2 1
      nicegui/timer.py
  63. 11 15
      nicegui/ui.py

+ 10 - 10
.vscode/settings.json

@@ -1,18 +1,18 @@
 {
-  "editor.formatOnSave": true,
   "editor.defaultFormatter": "esbenp.prettier-vscode",
+  "editor.formatOnSave": true,
   "editor.minimap.enabled": false,
   "python.formatting.provider": "autopep8",
-  "[python]": {
-    "editor.defaultFormatter": "ms-python.python"
-  },
-  "python.formatting.autopep8Args": ["--max-line-length", "120", "--ignore", "E305,E302"],
+  "python.formatting.autopep8Args": ["--max-line-length=120", "--experimental"],
+  "python.sortImports.args": ["--line-length=120"],
+  "python.testing.promptToConfigure": false,
   "python.testing.pytestArgs": ["."],
-  "python.testing.unittestEnabled": false,
-  "python.testing.nosetestsEnabled": false,
   "python.testing.pytestEnabled": false,
-  "python.testing.promptToConfigure": false,
-  "files.associations": {
-    "*.html": "jinja-html"
+  "python.testing.unittestEnabled": false,
+  "[python]": {
+    "editor.defaultFormatter": "ms-python.python",
+    "editor.codeActionsOnSave": {
+      "source.organizeImports": true
+    }
   }
 }

+ 0 - 11
custom_test.py

@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-from nicegui import ui
-
-with ui.card():
-    example = ui.custom_example(on_change=lambda number: label.set_text(f'Custom value: {number}'))
-
-ui.button('Add 100', on_click=lambda: example.add(100))
-
-label = ui.label()
-
-ui.joystick(on_move=lambda e: print("move", e.data.vector), color='blue', size=50)

+ 4 - 2
examples.py

@@ -1,8 +1,10 @@
 #!/usr/bin/env python3
-from nicegui import ui
 from datetime import datetime
-from matplotlib import pyplot as plt
+
 import numpy as np
+from matplotlib import pyplot as plt
+
+from nicegui import ui
 
 with ui.row():
     with ui.card():

+ 10 - 5
main.py

@@ -1,12 +1,14 @@
 #!/usr/bin/env python3
-from nicegui import ui
-from contextlib import contextmanager
+import asyncio
 import inspect
+import re
 import sys
+from contextlib import contextmanager
 from typing import Callable, Union
+
 import docutils.core
-import re
-import asyncio
+
+from nicegui import ui
 from nicegui.elements.html import Html
 from nicegui.elements.markdown import Markdown
 from nicegui.globals import page_stack
@@ -14,6 +16,7 @@ from nicegui.globals import page_stack
 # add docutils css to webpage
 page_stack[0].head_html += docutils.core.publish_parts('', writer_name='html')['stylesheet']
 
+
 @contextmanager
 def example(content: Union[Callable, type, str]):
     callFrame = inspect.currentframe().f_back.f_back
@@ -69,6 +72,7 @@ def example(content: Union[Callable, type, str]):
             code = '\n'.join(code)
             ui.markdown(code).classes('mt-12 w-5/12 overflow-auto')
 
+
 with ui.row().classes('flex w-full'):
     with open('README.md', 'r') as file:
         content = file.read()
@@ -219,8 +223,8 @@ with example(ui.upload):
     content = ui.label()
 
 with example(ui.plot):
-    from matplotlib import pyplot as plt
     import numpy as np
+    from matplotlib import pyplot as plt
 
     with ui.plot(figsize=(2.5, 1.8)):
         x = np.linspace(0.0, 5.0)
@@ -455,6 +459,7 @@ It also enables you to identify sessions over [longer time spans by configuring
 with example(sessions):
     from collections import Counter
     from datetime import datetime
+
     from starlette.requests import Request
 
     id_counter = Counter()

+ 0 - 3
nicegui.code-workspace

@@ -36,8 +36,5 @@
         }
       }
     ]
-  },
-  "files.associations": {
-    "*.html": "jinja-html"
   }
 }

+ 1 - 1
nicegui/__init__.py

@@ -1,2 +1,2 @@
-from nicegui.nicegui import app, ui
 from nicegui import elements
+from nicegui.nicegui import app, ui

+ 11 - 2
nicegui/binding.py

@@ -1,15 +1,18 @@
 #!/usr/bin/env python3
 import asyncio
 from collections import defaultdict
-from justpy.htmlcomponents import HTMLBaseComponent
 from typing import Any, Callable, Optional, Set, Tuple
-from .task_logger import create_task
+
+from justpy.htmlcomponents import HTMLBaseComponent
+
 from .globals import config
+from .task_logger import create_task
 
 bindings = defaultdict(list)
 bindable_properties = dict()
 active_links = []
 
+
 async def loop():
     while True:
         visited: Set[Tuple[int, str]] = set()
@@ -23,15 +26,18 @@ async def loop():
         update_views(visited_views)
         await asyncio.sleep(config.binding_refresh_interval)
 
+
 async def update_views_async(views: Set[HTMLBaseComponent]):
     for view in views:
         await view.update()
 
+
 def update_views(views: Set[HTMLBaseComponent]):
     if asyncio._get_running_loop() is None:
         return  # NOTE: no need to update view if event loop is not running, yet
     create_task(update_views_async(views), name='update_views_async')
 
+
 def propagate(source_obj,
               source_name,
               visited: Set[Tuple[int, str]] = None,
@@ -52,18 +58,21 @@ def propagate(source_obj,
             propagate(target_obj, target_name, visited, visited_views)
     return visited_views
 
+
 def bind_to(self_obj: Any, self_name: str, other_obj: Any, other_name: str, forward: Callable):
     bindings[(id(self_obj), self_name)].append((self_obj, other_obj, other_name, forward))
     if (id(self_obj), self_name) not in bindable_properties:
         active_links.append((self_obj, self_name, other_obj, other_name, forward))
     update_views(propagate(self_obj, self_name))
 
+
 def bind_from(self_obj: Any, self_name: str, other_obj: Any, other_name: str, backward: Callable):
     bindings[(id(other_obj), other_name)].append((other_obj, self_obj, self_name, backward))
     if (id(other_obj), other_name) not in bindable_properties:
         active_links.append((other_obj, other_name, self_obj, self_name, backward))
     update_views(propagate(other_obj, other_name))
 
+
 class BindableProperty:
 
     def __init__(self, on_change: Optional[Callable] = None):

+ 5 - 3
nicegui/config.py

@@ -1,10 +1,12 @@
-from dataclasses import dataclass
-from typing import Callable, Optional
-import inspect
 import ast
+import inspect
 import os
+from dataclasses import dataclass
+from typing import Callable, Optional
+
 from . import globals
 
+
 @dataclass
 class Config():
     # NOTE: should be in sync with ui.run arguments

+ 5 - 7
nicegui/elements/bool_element.py

@@ -1,13 +1,11 @@
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
+
 from .value_element import ValueElement
 
+
 class BoolElement(ValueElement):
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 *,
-                 value: bool,
-                 on_change: Optional[Callable],
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent, *, value: bool, on_change: Optional[Callable]):
         super().__init__(view, value=value, on_change=on_change)

+ 4 - 6
nicegui/elements/button.py

@@ -1,18 +1,16 @@
 from typing import Callable, Optional
+
 import justpy as jp
 
-from ..binding import bind_from, bind_to, BindableProperty
+from ..binding import BindableProperty, bind_from, bind_to
 from ..events import ClickEventArguments, handle_event
 from .element import Element
 
+
 class Button(Element):
     text = BindableProperty()
 
-    def __init__(self,
-                 text: str = '',
-                 *,
-                 on_click: Optional[Callable] = None,
-                 ):
+    def __init__(self, text: str = '', *, on_click: Optional[Callable] = None):
         """Button Element
 
         :param text: the label of the button

+ 3 - 0
nicegui/elements/card.py

@@ -1,6 +1,8 @@
 import justpy as jp
+
 from .group import Group
 
+
 class Card(Group):
 
     def __init__(self):
@@ -11,6 +13,7 @@ class Card(Group):
         view = jp.QCard(classes='column items-start q-pa-md', style='gap: 1em', delete_flag=False, temp=False)
         super().__init__(view)
 
+
 class CardSection(Group):
 
     def __init__(self):

+ 3 - 1
nicegui/elements/chart.py

@@ -1,5 +1,7 @@
-import justpy as jp
 from typing import Dict
+
+import justpy as jp
+
 from .element import Element
 
 

+ 4 - 6
nicegui/elements/checkbox.py

@@ -1,15 +1,13 @@
 from typing import Callable, Optional
+
 import justpy as jp
+
 from .bool_element import BoolElement
 
+
 class Checkbox(BoolElement):
 
-    def __init__(self,
-                 text: str = '',
-                 *,
-                 value: bool = False,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable] = None):
         """Checkbox Element
 
         :param text: the label to display next to the checkbox

+ 6 - 8
nicegui/elements/choice_element.py

@@ -1,16 +1,14 @@
-import justpy as jp
 from typing import Any, Callable, Dict, List, Optional, Union
+
+import justpy as jp
+
 from .value_element import ValueElement
 
+
 class ChoiceElement(ValueElement):
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 options: Union[List, Dict],
-                 *,
-                 value: Any,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent, options: Union[List, Dict], *,
+                 value: Any, on_change: Optional[Callable] = None):
         if isinstance(options, List):
             view.options = [{'label': option, 'value': option} for option in options]
         else:

+ 2 - 0
nicegui/elements/colors.py

@@ -3,6 +3,7 @@ from .element import Element
 
 CustomView.use(__file__)
 
+
 class ColorsView(CustomView):
 
     def __init__(self, primary, secondary, accent, positive, negative, info, warning):
@@ -16,6 +17,7 @@ class ColorsView(CustomView):
                          warning=warning)
         self.initialize(temp=False)
 
+
 class Colors(Element):
 
     def __init__(self, *,

+ 2 - 0
nicegui/elements/column.py

@@ -1,6 +1,8 @@
 import justpy as jp
+
 from .group import Group
 
+
 class Column(Group):
 
     def __init__(self):

+ 2 - 0
nicegui/elements/custom_example.py

@@ -3,6 +3,7 @@ from .element import Element
 
 CustomView.use(__file__)
 
+
 class CustomExampleView(CustomView):
 
     def __init__(self, on_change):
@@ -18,6 +19,7 @@ class CustomExampleView(CustomView):
             return self.on_change(self.options.value)
         return False
 
+
 class CustomExample(Element):
 
     def __init__(self, *, on_change=None):

+ 4 - 2
nicegui/elements/custom_view.py

@@ -1,8 +1,10 @@
-import justpy as jp
 import os.path
 from typing import List
-from starlette.routing import Route
+
+import justpy as jp
 from starlette.responses import FileResponse
+from starlette.routing import Route
+
 
 class CustomView(jp.JustpyBaseComponent):
 

+ 3 - 4
nicegui/elements/dialog.py

@@ -1,12 +1,11 @@
 import justpy as jp
+
 from .group import Group
 
+
 class Dialog(Group):
 
-    def __init__(self,
-                 *,
-                 value: bool = False
-                 ):
+    def __init__(self, *, value: bool = False):
         """Dialog
 
         Creates a modal dialog.

+ 5 - 5
nicegui/elements/element.py

@@ -1,14 +1,14 @@
 import justpy as jp
-from ..binding import bind_from, bind_to, BindableProperty
-from ..globals import view_stack, page_stack
+
+from ..binding import BindableProperty, bind_from, bind_to
+from ..globals import page_stack, view_stack
+
 
 class Element:
     visible = BindableProperty(
         on_change=lambda sender, visible: (sender.view.remove_class if visible else sender.view.set_class)('hidden'))
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent):
         self.parent_view = view_stack[-1]
         self.parent_view.add(view)
         self.view = view

+ 5 - 8
nicegui/elements/float_element.py

@@ -1,16 +1,13 @@
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
+
 from .value_element import ValueElement
 
+
 class FloatElement(ValueElement):
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 *,
-                 value: float,
-                 format: str = None,
-                 on_change: Optional[Callable],
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent, *, value: float, format: str = None, on_change: Optional[Callable]):
         self.format = format
 
         super().__init__(view, value=value, on_change=on_change)

+ 5 - 1
nicegui/elements/group.py

@@ -1,10 +1,14 @@
 from __future__ import annotations
+
 from typing import List
+
 import justpy as jp
+
+from ..binding import active_links, bindable_properties, bindings
 from ..globals import view_stack
-from ..binding import active_links, bindings, bindable_properties
 from .element import Element
 
+
 class Group(Element):
 
     def __enter__(self):

+ 6 - 4
nicegui/elements/html.py

@@ -1,11 +1,13 @@
+from typing import Any
+
 import justpy as jp
+
 from .element import Element
 
+
 class Html(Element):
 
-    def __init__(self,
-                 content: str = '',
-                 ):
+    def __init__(self, content: str = ''):
         """HTML Element
 
         Renders arbitrary HTML onto the page. `Tailwind <https://tailwindcss.com/>`_ can be used for styling.
@@ -21,7 +23,7 @@ class Html(Element):
         return self.view.inner_html
 
     @content.setter
-    def content(self, content: any):
+    def content(self, content: Any):
         self.set_content(content)
 
     def set_content(self, content: str):

+ 3 - 3
nicegui/elements/icon.py

@@ -1,11 +1,11 @@
 import justpy as jp
+
 from .element import Element
 
+
 class Icon(Element):
 
-    def __init__(self,
-                 name: str,
-                 ):
+    def __init__(self, name: str):
         view = jp.QIcon(name=name, classes=f'q-pt-xs', size='20px', temp=False)
 
         super().__init__(view)

+ 3 - 4
nicegui/elements/image.py

@@ -1,14 +1,13 @@
 import justpy as jp
 
-from ..binding import bind_from, bind_to, BindableProperty
+from ..binding import BindableProperty, bind_from, bind_to
 from .group import Group
 
+
 class Image(Group):
     source = BindableProperty()
 
-    def __init__(self,
-                 source: str = '',
-                 ):
+    def __init__(self, source: str = ''):
         """Image Element
 
         Displays an image.

+ 6 - 8
nicegui/elements/input.py

@@ -1,16 +1,14 @@
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
+
 from .string_element import StringElement
 
+
 class Input(StringElement):
 
-    def __init__(self,
-                 label: str = None,
-                 *,
-                 placeholder: str = None,
-                 value: str = '',
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, label: str = None, *,
+                 placeholder: str = None, value: str = '', on_change: Optional[Callable] = None):
         """Text Input Element
 
         :param label: displayed label for the text input

+ 9 - 3
nicegui/elements/interactive_image.py

@@ -1,13 +1,17 @@
 from __future__ import annotations
-from justpy import WebPage
-from typing import Any, Callable, Dict, List, Optional
+
 import traceback
+from typing import Any, Callable, Dict, List, Optional
+
+from justpy import WebPage
+
 from ..events import MouseEventArguments, handle_event
 from .custom_view import CustomView
 from .element import Element
 
 CustomView.use(__file__)
 
+
 class InteractiveImageView(CustomView):
 
     def __init__(self, source: str, on_mouse: Callable, events: List[str], cross: bool):
@@ -24,9 +28,11 @@ class InteractiveImageView(CustomView):
         page_sockets = [s for page_id in self.pages for s in WebPage.sockets.get(page_id, {}).values()]
         self.sockets = [s for s in self.sockets if s in page_sockets]
 
+
 class InteractiveImage(Element):
 
-    def __init__(self, source: str, *, on_mouse: Optional[Callable] = None, events: List[str] = ['click'], cross: bool = False):
+    def __init__(self, source: str, *,
+                 on_mouse: Optional[Callable] = None, events: List[str] = ['click'], cross: bool = False):
         """Interactive Image
 
         Create an image with an SVG overlay that handles mouse events and yields image coordinates.

+ 7 - 7
nicegui/elements/joystick.py

@@ -1,17 +1,18 @@
-from typing import Callable, Dict, Optional
+from typing import Any, Callable, Optional
+
 from .custom_view import CustomView
 from .element import Element
 
 CustomView.use(__file__, ['nipplejs.min.js'])
 
+
 class JoystickView(CustomView):
 
     def __init__(self,
                  on_start: Optional[Callable],
                  on_move: Optional[Callable],
                  on_end: Optional[Callable],
-                 **options,
-                 ):
+                 **options: Any):
         super().__init__('joystick', **options)
 
         self.on_start = on_start
@@ -38,15 +39,14 @@ class JoystickView(CustomView):
             return self.on_end(msg)
         return False
 
+
 class Joystick(Element):
 
-    def __init__(self,
-                 *,
+    def __init__(self, *,
                  on_start: Optional[Callable] = None,
                  on_move: Optional[Callable] = None,
                  on_end: Optional[Callable] = None,
-                 **options: Dict,
-                 ):
+                 **options: Any):
         """Joystick
 
         Create a joystick based on `nipple.js <https://yoannmoi.net/nipplejs/>`_.

+ 3 - 7
nicegui/elements/keyboard.py

@@ -1,12 +1,13 @@
 import traceback
 from typing import Callable, Dict, Optional
 
-from ..events import KeyEventArguments, KeyboardAction, KeyboardKey, KeyboardModifiers, handle_event
+from ..events import KeyboardAction, KeyboardKey, KeyboardModifiers, KeyEventArguments, handle_event
 from .custom_view import CustomView
 from .element import Element
 
 CustomView.use(__file__)
 
+
 class KeyboardView(CustomView):
 
     def __init__(self, on_key: Callable, repeating: bool):
@@ -18,12 +19,7 @@ class KeyboardView(CustomView):
 
 class Keyboard(Element):
 
-    def __init__(self,
-                 *,
-                 on_key: Optional[Callable] = None,
-                 active: bool = True,
-                 repeating: bool = True,
-                 ):
+    def __init__(self, *, on_key: Optional[Callable] = None, active: bool = True, repeating: bool = True):
         """
         Keyboard
 

+ 3 - 4
nicegui/elements/label.py

@@ -1,14 +1,13 @@
 import justpy as jp
 
-from ..binding import bind_from, bind_to, BindableProperty
+from ..binding import BindableProperty, bind_from, bind_to
 from .element import Element
 
+
 class Label(Element):
     text = BindableProperty()
 
-    def __init__(self,
-                 text: str = '',
-                 ):
+    def __init__(self, text: str = ''):
         """Label Element
 
         Displays some text.

+ 3 - 8
nicegui/elements/line_plot.py

@@ -1,16 +1,11 @@
 from typing import List
+
 from .plot import Plot
 
+
 class LinePlot(Plot):
 
-    def __init__(self,
-                 *,
-                 n: int = 1,
-                 limit: int = 100,
-                 update_every: int = 1,
-                 close: bool = True,
-                 **kwargs,
-                 ):
+    def __init__(self, *, n: int = 1, limit: int = 100, update_every: int = 1, close: bool = True, **kwargs):
         """Line Plot
 
         Create a line plot. The `push` method provides live updating when utilized in combination with `ui.timer`.

+ 4 - 4
nicegui/elements/link.py

@@ -1,14 +1,14 @@
 from typing import Union
+
 import justpy as jp
+
 from .element import Element
 from .page import Page
 
+
 class Link(Element):
 
-    def __init__(self,
-                 text: str = '',
-                 target: Union[Page, str] = '#',
-                 ):
+    def __init__(self, text: str = '', target: Union[Page, str] = '#'):
         """Link
 
         Create a link.

+ 7 - 2
nicegui/elements/log.py

@@ -1,16 +1,20 @@
 from __future__ import annotations
-from typing import Deque
+
 import asyncio
 import traceback
 import urllib
 from collections import deque
+from typing import Deque
+
 from justpy.htmlcomponents import WebPage
+
+from ..task_logger import create_task
 from .custom_view import CustomView
 from .element import Element
-from ..task_logger import create_task
 
 CustomView.use(__file__)
 
+
 class LogView(CustomView):
 
     def __init__(self, lines: Deque[str], max_lines: int):
@@ -28,6 +32,7 @@ class LogView(CustomView):
         except:
             traceback.print_exc()
 
+
 class Log(Element):
 
     def __init__(self, max_lines: int = None):

+ 5 - 4
nicegui/elements/markdown.py

@@ -1,12 +1,13 @@
+import re
+
 import markdown2
+
 from .html import Html
-import re
+
 
 class Markdown(Html):
 
-    def __init__(self,
-                 content: str = '',
-                 ):
+    def __init__(self, content: str = ''):
         """Markdown Element
 
         Renders markdown onto the page.

+ 3 - 4
nicegui/elements/menu.py

@@ -1,12 +1,11 @@
 import justpy as jp
+
 from .group import Group
 
+
 class Menu(Group):
 
-    def __init__(self,
-                 *,
-                 value: bool = False,
-                 ):
+    def __init__(self, *, value: bool = False):
         """Menu
 
         Creates a menu.

+ 2 - 6
nicegui/elements/menu_item.py

@@ -1,4 +1,5 @@
 from typing import Callable, Optional
+
 import justpy as jp
 
 from ..events import ClickEventArguments, handle_event
@@ -7,12 +8,7 @@ from .element import Element
 
 class MenuItem(Element):
 
-    def __init__(self,
-                 text: str = '',
-                 on_click: Optional[Callable] = None,
-                 *,
-                 auto_close: bool = True,
-                 ):
+    def __init__(self, text: str = '', on_click: Optional[Callable] = None, *, auto_close: bool = True):
         """Menu Item Element
 
         A menu item to be added to a menu.

+ 3 - 7
nicegui/elements/notify.py

@@ -1,16 +1,12 @@
 import justpy as jp
-from .element import Element
+
 from ..task_logger import create_task
+from .element import Element
 
 
 class Notify(Element):
 
-    def __init__(self,
-                 message: str,
-                 *,
-                 position: str = 'bottom',
-                 close_button: str = None,
-                 ):
+    def __init__(self, message: str, *, position: str = 'bottom', close_button: str = None):
         """Notification
 
         Displays a notification on the screen.

+ 7 - 9
nicegui/elements/number.py

@@ -1,17 +1,15 @@
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
+
 from .float_element import FloatElement
 
+
 class Number(FloatElement):
 
-    def __init__(self,
-                 label: str = None,
-                 *,
-                 placeholder: str = None,
-                 value: float = None,
-                 format: str = None,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(
+            self, label: str = None, *,
+            placeholder: str = None, value: float = None, format: str = None, on_change: Optional[Callable] = None):
         """Number Input Element
 
         :param label: displayed name for the number input

+ 3 - 1
nicegui/elements/open.py

@@ -1,8 +1,9 @@
 from typing import Optional, Union
+
 from justpy import WebPage
+from nicegui.elements.page import Page
 from starlette.websockets import WebSocket
 
-from nicegui.elements.page import Page
 from ..task_logger import create_task
 
 
@@ -17,6 +18,7 @@ def open(self, target: Union[Page, str], socket: Optional[WebSocket] = None):
     """
     create_task(open_async(self, target, socket), name='open_async')
 
+
 async def open_async(self, target: Union[Page, str], socket: Optional[WebSocket]):
     path = target if isinstance(target, str) else target.route
     sockets = [socket] if socket else [s for socket_dict in WebPage.sockets.values() for s in socket_dict.values()]

+ 4 - 1
nicegui/elements/page.py

@@ -1,10 +1,13 @@
 import inspect
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
 from pygments.formatters import HtmlFormatter
 from starlette.requests import Request
+
 from ..globals import config, page_stack, view_stack
 
+
 class Page(jp.QuasarPage):
 
     def __init__(self,

+ 3 - 5
nicegui/elements/plot.py

@@ -1,14 +1,12 @@
 import justpy as jp
 import matplotlib.pyplot as plt
+
 from .element import Element
 
+
 class Plot(Element):
 
-    def __init__(self,
-                 *,
-                 close: bool = True,
-                 **kwargs,
-                 ):
+    def __init__(self, *, close: bool = True, **kwargs):
         """Plot Context
 
         Create a context to configure a `Matplotlib <https://matplotlib.org/>`_ plot.

+ 5 - 7
nicegui/elements/radio.py

@@ -1,15 +1,13 @@
+from typing import Any, Callable, Dict, List, Optional, Union
+
 import justpy as jp
-from typing import Callable, Dict, List, Optional, Union
+
 from .choice_element import ChoiceElement
 
+
 class Radio(ChoiceElement):
 
-    def __init__(self,
-                 options: Union[List, Dict],
-                 *,
-                 value: any = None,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, options: Union[List, Dict], *, value: Any = None, on_change: Optional[Callable] = None):
         """Radio Selection Element
 
         :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options

+ 2 - 0
nicegui/elements/row.py

@@ -1,6 +1,8 @@
 import justpy as jp
+
 from .group import Group
 
+
 class Row(Group):
 
     def __init__(self):

+ 16 - 10
nicegui/elements/scene.py

@@ -1,18 +1,21 @@
+import traceback
 from dataclasses import dataclass
-from justpy import WebPage
 from typing import Callable, Optional
-import traceback
+
 import websockets
-from .element import Element
+from justpy import WebPage
+
+from ..events import handle_event
+from ..globals import view_stack
+from ..task_logger import create_task
 from .custom_view import CustomView
+from .element import Element
 from .page import Page
 from .scene_object3d import Object3D
-from ..globals import view_stack
-from ..events import handle_event
-from ..task_logger import create_task
 
 CustomView.use(__file__, ['three.min.js', 'OrbitControls.js', 'STLLoader.js', 'tween.umd.min.js'])
 
+
 @dataclass
 class SceneCamera:
     x: float = 0
@@ -31,6 +34,7 @@ class SceneCamera:
             f'{self.look_at_x}, {self.look_at_y}, {self.look_at_z}, ' \
             f'{self.up_x}, {self.up_y}, {self.up_z}, {duration})'
 
+
 class SceneView(CustomView):
 
     def __init__(self, *, width: int, height: int, on_click: Optional[Callable]):
@@ -65,15 +69,16 @@ class SceneView(CustomView):
             pass
         return True
 
+
 class Scene(Element):
-    from .scene_objects import Group as group
     from .scene_objects import Box as box
-    from .scene_objects import Sphere as sphere
+    from .scene_objects import Curve as curve
     from .scene_objects import Cylinder as cylinder
     from .scene_objects import Extrusion as extrusion
-    from .scene_objects import Stl as stl
+    from .scene_objects import Group as group
     from .scene_objects import Line as line
-    from .scene_objects import Curve as curve
+    from .scene_objects import Sphere as sphere
+    from .scene_objects import Stl as stl
     from .scene_objects import Texture as texture
 
     def __init__(self, width: int = 400, height: int = 300, on_click: Optional[Callable] = None):
@@ -124,6 +129,7 @@ class Scene(Element):
         for socket in WebPage.sockets.get(self.page.page_id, {}).values():
             create_task(self.view.run_method(camera.create_move_command(duration), socket), 'move camera')
 
+
 class SceneObject:
 
     def __init__(self, view: SceneView, page: Page):

+ 5 - 1
nicegui/elements/scene_object3d.py

@@ -1,10 +1,14 @@
 from __future__ import annotations
-from typing import List, Optional
+
 import uuid
+from typing import List, Optional
+
 import numpy as np
 from justpy.htmlcomponents import WebPage
+
 from ..task_logger import create_task
 
+
 class Object3D:
     stack: List[Object3D] = []
 

+ 13 - 0
nicegui/elements/scene_objects.py

@@ -1,18 +1,24 @@
 from __future__ import annotations
+
 from typing import List, Optional
+
 from justpy import WebPage
+
 from .scene_object3d import Object3D
 
+
 class Scene(Object3D):
 
     def __init__(self, view):
         super().__init__('scene', view)
 
+
 class Group(Object3D):
 
     def __init__(self):
         super().__init__('group')
 
+
 class Box(Object3D):
 
     def __init__(self,
@@ -23,6 +29,7 @@ class Box(Object3D):
                  ):
         super().__init__('box', width, height, depth, wireframe)
 
+
 class Sphere(Object3D):
 
     def __init__(self,
@@ -33,6 +40,7 @@ class Sphere(Object3D):
                  ):
         super().__init__('sphere', radius, width_segments, height_segments, wireframe)
 
+
 class Cylinder(Object3D):
 
     def __init__(self,
@@ -45,6 +53,7 @@ class Cylinder(Object3D):
                  ):
         super().__init__('cylinder', top_radius, bottom_radius, height, radial_segments, height_segments, wireframe)
 
+
 class Extrusion(Object3D):
 
     def __init__(self,
@@ -54,6 +63,7 @@ class Extrusion(Object3D):
                  ):
         super().__init__('extrusion', outline, height, wireframe)
 
+
 class Stl(Object3D):
 
     def __init__(self,
@@ -62,6 +72,7 @@ class Stl(Object3D):
                  ):
         super().__init__('stl', url, wireframe)
 
+
 class Line(Object3D):
 
     def __init__(self,
@@ -70,6 +81,7 @@ class Line(Object3D):
                  ):
         super().__init__('line', start, end)
 
+
 class Curve(Object3D):
 
     def __init__(self,
@@ -81,6 +93,7 @@ class Curve(Object3D):
                  ):
         super().__init__('curve', start, control1, control2, end, num_points)
 
+
 class Texture(Object3D):
 
     def __init__(self,

+ 6 - 8
nicegui/elements/select.py

@@ -1,15 +1,13 @@
+from typing import Any, Callable, Dict, List, Optional, Union
+
 import justpy as jp
-from typing import Callable, Dict, List, Optional, Union
+
 from .choice_element import ChoiceElement
 
+
 class Select(ChoiceElement):
 
-    def __init__(self,
-                 options: Union[List, Dict],
-                 *,
-                 value: any = None,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, options: Union[List, Dict], *, value: Any = None, on_change: Optional[Callable] = None):
         """Dropdown Selection Element
 
         :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options
@@ -20,7 +18,7 @@ class Select(ChoiceElement):
 
         super().__init__(view, options, value=value, on_change=on_change)
 
-    def value_to_view(self, value: any):
+    def value_to_view(self, value: Any):
         matches = [o for o in self.view.options if o['value'] == value]
         if any(matches):
             return matches[0]['label']

+ 5 - 4
nicegui/elements/slider.py

@@ -1,17 +1,18 @@
 from typing import Callable, Optional
+
 import justpy as jp
+
 from .float_element import FloatElement
 
+
 class Slider(FloatElement):
 
-    def __init__(self,
-                 *,
+    def __init__(self, *,
                  min: float,
                  max: float,
                  step: float = 1,
                  value: float = None,
-                 on_change: Optional[Callable] = None,
-                 ):
+                 on_change: Optional[Callable] = None):
         """Slider Element
 
         :param min: lower bound of the slider

+ 5 - 7
nicegui/elements/string_element.py

@@ -1,13 +1,11 @@
-import justpy as jp
 from typing import Callable, Optional
+
+import justpy as jp
+
 from .value_element import ValueElement
 
+
 class StringElement(ValueElement):
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 *,
-                 value: float,
-                 on_change: Optional[Callable],
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent, *, value: float, on_change: Optional[Callable]):
         super().__init__(view, value=value, on_change=on_change)

+ 5 - 4
nicegui/elements/svg.py

@@ -1,12 +1,13 @@
+from typing import Any
+
 import justpy as jp
 
 from .element import Element
 
+
 class Svg(Element):
 
-    def __init__(self,
-                 content: str = '',
-                 ):
+    def __init__(self, content: str = ''):
         """Svg Element
 
         Displays an svg.
@@ -22,7 +23,7 @@ class Svg(Element):
         return self.view.inner_html()
 
     @content.setter
-    def content(self, content: any):
+    def content(self, content: Any):
         self.view.components = []
         jp.parse_html(content, a=self.view)
 

+ 4 - 6
nicegui/elements/switch.py

@@ -1,15 +1,13 @@
 from typing import Callable, Optional
+
 import justpy as jp
+
 from .bool_element import BoolElement
 
+
 class Switch(BoolElement):
 
-    def __init__(self,
-                 text: str = '',
-                 *,
-                 value: bool = False,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, text: str = '', *, value: bool = False, on_change: Optional[Callable] = None):
         """Switch Element
 
         :param text: the label to display next to the switch

+ 5 - 7
nicegui/elements/toggle.py

@@ -1,15 +1,13 @@
+from typing import Any, Callable, Dict, List, Optional, Union
+
 import justpy as jp
-from typing import Callable, Dict, List, Optional, Union
+
 from .choice_element import ChoiceElement
 
+
 class Toggle(ChoiceElement):
 
-    def __init__(self,
-                 options: Union[List, Dict],
-                 *,
-                 value: any = None,
-                 on_change: Optional[Callable] = None,
-                 ):
+    def __init__(self, options: Union[List, Dict], *, value: Any = None, on_change: Optional[Callable] = None):
         """Toggle Element
 
         :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options

+ 5 - 7
nicegui/elements/upload.py

@@ -1,18 +1,16 @@
+import base64
 import traceback
-import justpy as jp
 from typing import Callable, Optional
-import base64
+
+import justpy as jp
 
 from ..events import UploadEventArguments, handle_event
 from .element import Element
 
+
 class Upload(Element):
 
-    def __init__(self,
-                 *,
-                 multiple: bool = False,
-                 on_upload: Optional[Callable] = None,
-                 ):
+    def __init__(self, *, multiple: bool = False, on_upload: Optional[Callable] = None):
         """File Upload Element
 
         :param multiple: allow uploading multiple files at once (default: `False`)

+ 5 - 8
nicegui/elements/value_element.py

@@ -1,22 +1,19 @@
-import justpy as jp
 from typing import Any, Callable, Optional
 
+import justpy as jp
+
+from ..binding import BindableProperty, bind_from, bind_to
 from ..events import ValueChangeEventArguments, handle_event
-from ..binding import bind_from, bind_to, BindableProperty
 from .element import Element
 
+
 class ValueElement(Element):
     value = BindableProperty(
         on_change=lambda sender, value: handle_event(sender.change_handler,
                                                      ValueChangeEventArguments(sender=sender, value=value),
                                                      update=sender.parent_view))
 
-    def __init__(self,
-                 view: jp.HTMLBaseComponent,
-                 *,
-                 value: Any,
-                 on_change: Optional[Callable],
-                 ):
+    def __init__(self, view: jp.HTMLBaseComponent, *, value: Any, on_change: Optional[Callable]):
         super().__init__(view)
 
         self.change_handler = on_change

+ 12 - 2
nicegui/events.py

@@ -1,46 +1,55 @@
 import asyncio
+import traceback
 from inspect import signature
+from typing import Any, Callable, List, Optional
+
 from justpy.htmlcomponents import HTMLBaseComponent
 from pydantic import BaseModel
-import traceback
-from typing import Any, Callable, List, Optional
 from starlette.websockets import WebSocket
 
 from .elements.element import Element
 from .task_logger import create_task
 
+
 class EventArguments(BaseModel):
     class Config:
         arbitrary_types_allowed = True
     sender: Element
     socket: Optional[WebSocket]
 
+
 class ClickEventArguments(EventArguments):
     pass
 
+
 class MouseEventArguments(EventArguments):
     type: str
     image_x: float
     image_y: float
 
+
 class UploadEventArguments(EventArguments):
     files: List[bytes]
 
+
 class ValueChangeEventArguments(EventArguments):
     value: Any
 
+
 class KeyboardAction(BaseModel):
     keypress: bool
     keydown: bool
     keyup: bool
     repeat: bool
 
+
 class KeyboardModifiers(BaseModel):
     alt: bool
     ctrl: bool
     meta: bool
     shift: bool
 
+
 class KeyboardKey(BaseModel):
     name: str
     code: str
@@ -197,6 +206,7 @@ class KeyboardKey(BaseModel):
     def f12(self) -> bool:
         return self.name == 'F12'
 
+
 class KeyEventArguments(EventArguments):
     class Config:
         arbitrary_types_allowed = True

+ 5 - 2
nicegui/globals.py

@@ -1,10 +1,13 @@
 from __future__ import annotations
+
 import asyncio
 import logging
-from typing import List, TYPE_CHECKING
+from typing import TYPE_CHECKING, List
+
 if TYPE_CHECKING:
-    from starlette.applications import Starlette
     import justpy as jp
+    from starlette.applications import Starlette
+
     from .config import Config
     from .elements.page import Page
 

+ 3 - 0
nicegui/lifecycle.py

@@ -2,10 +2,13 @@ from typing import Awaitable, Callable, List, Union
 
 startup_tasks: List[Union[Callable, Awaitable]] = []
 
+
 def on_startup(self, task: Union[Callable, Awaitable]):
     self.startup_tasks.append(task)
 
+
 shutdown_tasks: List[Union[Callable, Awaitable]] = []
 
+
 def on_shutdown(self, task: Union[Callable, Awaitable]):
     self.shutdown_tasks.append(task)

+ 7 - 3
nicegui/nicegui.py

@@ -1,12 +1,13 @@
 #!/usr/bin/env python3
+# isort:skip_file
 from typing import Awaitable, Callable
 
 from .ui import Ui  # NOTE: before justpy
 import justpy as jp
-from .timer import Timer
-from . import globals
-from . import binding
+
+from . import binding, globals
 from .task_logger import create_task
+from .timer import Timer
 
 
 @jp.app.on_event('startup')
@@ -17,18 +18,21 @@ def startup():
     [safe_invoke(t) for t in Ui.startup_tasks if isinstance(t, Callable)]
     jp.run_task(binding.loop())
 
+
 @jp.app.on_event('shutdown')
 def shutdown():
     [create_task(t, name='shutdown task') for t in Ui.shutdown_tasks if isinstance(t, Awaitable)]
     [safe_invoke(t) for t in Ui.shutdown_tasks if isinstance(t, Callable)]
     [t.cancel() for t in globals.tasks]
 
+
 def safe_invoke(func: Callable):
     try:
         func()
     except:
         globals.log.exception(f'could not invoke {func}')
 
+
 app = globals.app = jp.app
 ui = Ui()
 

+ 6 - 2
nicegui/routes.py

@@ -1,8 +1,11 @@
-from functools import wraps
 import inspect
-from starlette import routing, requests
+from functools import wraps
+
+from starlette import requests, routing
+
 from . import globals
 
+
 def add_route(self, route):
     """
     :param route: starlette route including a path and a function to be called
@@ -10,6 +13,7 @@ def add_route(self, route):
     """
     globals.app.routes.insert(0, route)
 
+
 def get(self, path: str):
     """
     Use as a decorator for a function like @ui.get('/another/route/{id}').

+ 5 - 2
nicegui/run.py

@@ -1,9 +1,11 @@
-from typing import Callable, Optional
 import inspect
+import os
 import sys
 import webbrowser
+from typing import Callable, Optional
+
 import uvicorn
-import os
+
 from . import globals
 
 if not globals.config.interactive and globals.config.reload and not inspect.stack()[-2].filename.endswith('spawn.py'):
@@ -23,6 +25,7 @@ if not globals.config.interactive and globals.config.reload and not inspect.stac
     )
     sys.exit()
 
+
 def run(self, *,
         host: str = os.environ.get('HOST', '0.0.0.0'),
         port: int = int(os.environ.get('PORT', '8080')),

+ 1 - 2
nicegui/task_logger.py

@@ -1,11 +1,10 @@
 '''original copied from https://quantlane.com/blog/ensure-asyncio-task-exceptions-get-logged/'''
 
-from typing import Any, Awaitable, Optional, Tuple, TypeVar
-
 import asyncio
 import functools
 import logging
 import sys
+from typing import Any, Awaitable, Optional, Tuple, TypeVar
 
 T = TypeVar('T')
 

+ 2 - 1
nicegui/timer.py

@@ -1,8 +1,8 @@
 import asyncio
 import time
 import traceback
-from typing import Callable, List
 from collections import namedtuple
+from typing import Callable, List
 
 from .binding import BindableProperty
 from .globals import tasks, view_stack
@@ -10,6 +10,7 @@ from .task_logger import create_task
 
 NamedCoroutine = namedtuple('NamedCoroutine', ['name', 'coro'])
 
+
 class Timer:
     prepared_coroutines: List[NamedCoroutine] = []
 

+ 11 - 15
nicegui/ui.py

@@ -1,20 +1,26 @@
+# isort:skip_file
 class Ui:
     from .config import config  # NOTE: before run
     from .run import run  # NOTE: before justpy
 
     from .elements.button import Button as button
+    from .elements.card import Card as card
+    from .elements.card import CardSection as card_section
     from .elements.chart import Chart as chart
     from .elements.checkbox import Checkbox as checkbox
     from .elements.colors import Colors as colors
+    from .elements.column import Column as column
     from .elements.custom_example import CustomExample as custom_example
     from .elements.dialog import Dialog as dialog
+    from .elements.html import Html as html
     from .elements.icon import Icon as icon
     from .elements.image import Image as image
     from .elements.input import Input as input
     from .elements.interactive_image import InteractiveImage as interactive_image
     from .elements.joystick import Joystick as joystick
-    from .elements.html import Html as html
+    from .elements.keyboard import Keyboard as keyboard
     from .elements.label import Label as label
+    from .elements.line_plot import LinePlot as line_plot
     from .elements.link import Link as link
     from .elements.log import Log as log
     from .elements.markdown import Markdown as markdown
@@ -25,7 +31,9 @@ class Ui:
     from .elements.number import Number as number
     from .elements.open import open, open_async
     from .elements.page import Page as page
+    from .elements.plot import Plot as plot
     from .elements.radio import Radio as radio
+    from .elements.row import Row as row
     from .elements.scene import Scene as scene
     from .elements.select import Select as select
     from .elements.slider import Slider as slider
@@ -33,18 +41,6 @@ class Ui:
     from .elements.switch import Switch as switch
     from .elements.toggle import Toggle as toggle
     from .elements.upload import Upload as upload
-
-    from .elements.plot import Plot as plot
-    from .elements.line_plot import LinePlot as line_plot
-
-    from .elements.row import Row as row
-    from .elements.column import Column as column
-    from .elements.card import Card as card
-    from .elements.keyboard import Keyboard as keyboard
-    from .elements.card import CardSection as card_section
-
-    from .timer import Timer as timer
-
-    from .lifecycle import startup_tasks, on_startup, shutdown_tasks, on_shutdown
-
+    from .lifecycle import on_shutdown, on_startup, shutdown_tasks, startup_tasks
     from .routes import add_route, get
+    from .timer import Timer as timer