|
@@ -52,10 +52,12 @@ class Client:
|
|
|
|
|
|
@property
|
|
@property
|
|
def ip(self) -> Optional[str]:
|
|
def ip(self) -> Optional[str]:
|
|
|
|
+ """Return the IP address of the client, or None if the client is not connected."""
|
|
return self.environ.get('REMOTE_ADDR') if self.environ else None
|
|
return self.environ.get('REMOTE_ADDR') if self.environ else None
|
|
|
|
|
|
@property
|
|
@property
|
|
def has_socket_connection(self) -> bool:
|
|
def has_socket_connection(self) -> bool:
|
|
|
|
+ """Return True if the client is connected, False otherwise."""
|
|
return self.environ is not None
|
|
return self.environ is not None
|
|
|
|
|
|
def __enter__(self):
|
|
def __enter__(self):
|
|
@@ -88,7 +90,7 @@ class Client:
|
|
}, status_code, {'Cache-Control': 'no-store', 'X-NiceGUI-Content': 'page'})
|
|
}, status_code, {'Cache-Control': 'no-store', 'X-NiceGUI-Content': 'page'})
|
|
|
|
|
|
async def connected(self, timeout: float = 3.0, check_interval: float = 0.1) -> None:
|
|
async def connected(self, timeout: float = 3.0, check_interval: float = 0.1) -> None:
|
|
- '''Blocks execution until the client is connected.'''
|
|
|
|
|
|
+ """Block execution until the client is connected."""
|
|
self.is_waiting_for_connection = True
|
|
self.is_waiting_for_connection = True
|
|
deadline = time.time() + timeout
|
|
deadline = time.time() + timeout
|
|
while not self.environ:
|
|
while not self.environ:
|
|
@@ -98,7 +100,7 @@ class Client:
|
|
self.is_waiting_for_connection = False
|
|
self.is_waiting_for_connection = False
|
|
|
|
|
|
async def disconnected(self, check_interval: float = 0.1) -> None:
|
|
async def disconnected(self, check_interval: float = 0.1) -> None:
|
|
- '''Blocks execution until the client disconnects.'''
|
|
|
|
|
|
+ """Block execution until the client disconnects."""
|
|
self.is_waiting_for_disconnect = True
|
|
self.is_waiting_for_disconnect = True
|
|
while self.id in globals.clients:
|
|
while self.id in globals.clients:
|
|
await asyncio.sleep(check_interval)
|
|
await asyncio.sleep(check_interval)
|
|
@@ -106,11 +108,12 @@ class Client:
|
|
|
|
|
|
async def run_javascript(self, code: str, *,
|
|
async def run_javascript(self, code: str, *,
|
|
respond: bool = True, timeout: float = 1.0, check_interval: float = 0.01) -> Optional[str]:
|
|
respond: bool = True, timeout: float = 1.0, check_interval: float = 0.01) -> Optional[str]:
|
|
- '''Allows execution of javascript on the client.
|
|
|
|
|
|
+ """Execute JavaScript on the client.
|
|
|
|
|
|
The client connection must be established before this method is called.
|
|
The client connection must be established before this method is called.
|
|
You can do this by `await client.connected()` or register a callback with `client.on_connected(...)`.
|
|
You can do this by `await client.connected()` or register a callback with `client.on_connected(...)`.
|
|
- If respond is True, the javascript code must return a string.'''
|
|
|
|
|
|
+ If respond is True, the javascript code must return a string.
|
|
|
|
+ """
|
|
request_id = str(uuid.uuid4())
|
|
request_id = str(uuid.uuid4())
|
|
command = {
|
|
command = {
|
|
'code': code,
|
|
'code': code,
|
|
@@ -127,11 +130,18 @@ class Client:
|
|
return self.waiting_javascript_commands.pop(request_id)
|
|
return self.waiting_javascript_commands.pop(request_id)
|
|
|
|
|
|
def open(self, target: Union[Callable, str]) -> None:
|
|
def open(self, target: Union[Callable, str]) -> None:
|
|
|
|
+ """Open a new page in the client."""
|
|
path = target if isinstance(target, str) else globals.page_routes[target]
|
|
path = target if isinstance(target, str) else globals.page_routes[target]
|
|
outbox.enqueue_message('open', path, self.id)
|
|
outbox.enqueue_message('open', path, self.id)
|
|
|
|
|
|
|
|
+ def download(self, url: str, filename: Optional[str] = None) -> None:
|
|
|
|
+ """Download a file from the given URL."""
|
|
|
|
+ outbox.enqueue_message('download', {'url': url, 'filename': filename}, self.id)
|
|
|
|
+
|
|
def on_connect(self, handler: Union[Callable, Awaitable]) -> None:
|
|
def on_connect(self, handler: Union[Callable, Awaitable]) -> None:
|
|
|
|
+ """Register a callback to be called when the client connects."""
|
|
self.connect_handlers.append(handler)
|
|
self.connect_handlers.append(handler)
|
|
|
|
|
|
def on_disconnect(self, handler: Union[Callable, Awaitable]) -> None:
|
|
def on_disconnect(self, handler: Union[Callable, Awaitable]) -> None:
|
|
|
|
+ """Register a callback to be called when the client disconnects."""
|
|
self.disconnect_handlers.append(handler)
|
|
self.disconnect_handlers.append(handler)
|