globals.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import asyncio
  2. import inspect
  3. import logging
  4. from contextlib import contextmanager
  5. from enum import Enum
  6. from pathlib import Path
  7. from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, Iterator, List, Optional, Union
  8. from socketio import AsyncServer
  9. from uvicorn import Server
  10. from . import background_tasks
  11. from .app import App
  12. from .language import Language
  13. if TYPE_CHECKING:
  14. from .air import Air
  15. from .client import Client
  16. from .slot import Slot
  17. class State(Enum):
  18. STOPPED = 0
  19. STARTING = 1
  20. STARTED = 2
  21. STOPPING = 3
  22. app: App
  23. sio: AsyncServer
  24. server: Server
  25. loop: Optional[asyncio.AbstractEventLoop] = None
  26. log: logging.Logger = logging.getLogger('nicegui')
  27. state: State = State.STOPPED
  28. ui_run_has_been_called: bool = False
  29. reload: bool
  30. title: str
  31. viewport: str
  32. favicon: Optional[Union[str, Path]]
  33. dark: Optional[bool]
  34. language: Language
  35. binding_refresh_interval: float
  36. excludes: List[str]
  37. tailwind: bool
  38. air: Optional['Air'] = None
  39. socket_io_js_extra_headers: Dict = {}
  40. _socket_id: Optional[str] = None
  41. slot_stacks: Dict[int, List['Slot']] = {}
  42. clients: Dict[str, 'Client'] = {}
  43. index_client: 'Client'
  44. page_routes: Dict[Callable[..., Any], str] = {}
  45. startup_handlers: List[Union[Callable[..., Any], Awaitable]] = []
  46. shutdown_handlers: List[Union[Callable[..., Any], Awaitable]] = []
  47. connect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
  48. disconnect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
  49. exception_handlers: List[Callable[..., Any]] = [log.exception]
  50. def get_task_id() -> int:
  51. try:
  52. return id(asyncio.current_task())
  53. except RuntimeError:
  54. return 0
  55. def get_slot_stack() -> List['Slot']:
  56. task_id = get_task_id()
  57. if task_id not in slot_stacks:
  58. slot_stacks[task_id] = []
  59. return slot_stacks[task_id]
  60. def prune_slot_stack() -> None:
  61. task_id = get_task_id()
  62. if not slot_stacks[task_id]:
  63. del slot_stacks[task_id]
  64. def get_slot() -> 'Slot':
  65. return get_slot_stack()[-1]
  66. def get_client() -> 'Client':
  67. return get_slot().parent.client
  68. @contextmanager
  69. def socket_id(id: str) -> Iterator[None]:
  70. global _socket_id
  71. _socket_id = id
  72. yield
  73. _socket_id = None
  74. def handle_exception(exception: Exception) -> None:
  75. for handler in exception_handlers:
  76. result = handler() if not inspect.signature(handler).parameters else handler(exception)
  77. if isinstance(result, Awaitable):
  78. background_tasks.create(result)