123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- from __future__ import annotations
- import asyncio
- import inspect
- import logging
- from contextlib import contextmanager
- from enum import Enum
- from pathlib import Path
- from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Iterator, List, Literal, Optional, Set, Union
- from socketio import AsyncServer
- from uvicorn import Server
- from . import background_tasks
- if TYPE_CHECKING:
- from .air import Air
- from .app import App
- from .client import Client
- from .language import Language
- from .slot import Slot
- class State(Enum):
- STOPPED = 0
- STARTING = 1
- STARTED = 2
- STOPPING = 3
- app: App
- sio: AsyncServer
- server: Server
- loop: Optional[asyncio.AbstractEventLoop] = None
- log: logging.Logger = logging.getLogger('nicegui')
- state: State = State.STOPPED
- ui_run_has_been_called: bool = False
- optional_features: Set[str] = set()
- reload: bool
- title: str
- viewport: str
- favicon: Optional[Union[str, Path]]
- storage_path: Path
- dark: Optional[bool]
- language: Language
- binding_refresh_interval: float
- tailwind: bool
- prod_js: bool
- endpoint_documentation: Literal['none', 'internal', 'page', 'all'] = 'none'
- air: Optional[Air] = None
- socket_io_js_query_params: Dict = {}
- socket_io_js_extra_headers: Dict = {}
- # NOTE we favor websocket over polling
- socket_io_js_transports: List[Literal['websocket', 'polling']] = ['websocket', 'polling']
- _socket_id: Optional[str] = None
- slot_stacks: Dict[int, List[Slot]] = {}
- clients: Dict[str, Client] = {}
- index_client: Client
- quasar_config: Dict = {
- 'brand': {
- 'primary': '#5898d4',
- },
- 'loadingBar': {
- 'color': 'primary',
- 'skipHijack': False,
- },
- }
- page_routes: Dict[Callable[..., Any], str] = {}
- startup_handlers: List[Union[Callable[..., Any], Awaitable]] = []
- shutdown_handlers: List[Union[Callable[..., Any], Awaitable]] = []
- connect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
- disconnect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
- exception_handlers: List[Callable[..., Any]] = [log.exception]
- def get_task_id() -> int:
- try:
- return id(asyncio.current_task())
- except RuntimeError:
- return 0
- def get_slot_stack() -> List[Slot]:
- task_id = get_task_id()
- if task_id not in slot_stacks:
- slot_stacks[task_id] = []
- return slot_stacks[task_id]
- def prune_slot_stack() -> None:
- task_id = get_task_id()
- if not slot_stacks[task_id]:
- del slot_stacks[task_id]
- def get_slot() -> Slot:
- return get_slot_stack()[-1]
- def get_client() -> Client:
- return get_slot().parent.client
- @contextmanager
- def socket_id(id: str) -> Iterator[None]:
- global _socket_id
- _socket_id = id
- yield
- _socket_id = None
- def handle_exception(exception: Exception) -> None:
- for handler in exception_handlers:
- result = handler() if not inspect.signature(handler).parameters else handler(exception)
- if isinstance(result, Awaitable):
- background_tasks.create(result)
|