mirror of
https://github.com/Textualize/textual-serve.git
synced 2025-10-17 02:50:37 +03:00
Progress on delivering files
This commit is contained in:
25
examples/download_screenshot.py
Normal file
25
examples/download_screenshot.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from textual import on
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.binding import Binding
|
||||
from textual.widgets import Button
|
||||
|
||||
|
||||
class ScreenshotApp(App[None]):
|
||||
BINDINGS = [Binding("s", "deliver_screenshot", "Screenshot")]
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Button("Hello, World!")
|
||||
|
||||
@on(Button.Pressed)
|
||||
def on_button_pressed(self) -> None:
|
||||
self.action_deliver_screenshot()
|
||||
|
||||
def action_deliver_screenshot(self) -> None:
|
||||
print("Delivering screenshot action!")
|
||||
filename = self.save_screenshot("screenshot.svg")
|
||||
self.deliver_text(filename)
|
||||
|
||||
|
||||
app = ScreenshotApp()
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
@@ -3,4 +3,4 @@ from textual_serve.server import Server
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = Server(sys.argv[1])
|
||||
server.serve(debug=False)
|
||||
server.serve(debug=True)
|
||||
|
||||
@@ -24,7 +24,9 @@ build-backend = "hatchling.build"
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = [
|
||||
"httpx", # required to run the dictionary example
|
||||
"httpx",
|
||||
"textual-dev>=1.5.1",
|
||||
# required to run the dictionary example
|
||||
]
|
||||
|
||||
[tool.hatch.metadata]
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
-e file:.
|
||||
aiohttp==3.9.5
|
||||
# via aiohttp-jinja2
|
||||
# via textual-dev
|
||||
# via textual-serve
|
||||
aiohttp-jinja2==1.6
|
||||
# via textual-serve
|
||||
@@ -25,6 +26,8 @@ attrs==23.2.0
|
||||
certifi==2024.7.4
|
||||
# via httpcore
|
||||
# via httpx
|
||||
click==8.1.7
|
||||
# via textual-dev
|
||||
exceptiongroup==1.2.2
|
||||
# via anyio
|
||||
frozenlist==1.4.1
|
||||
@@ -55,6 +58,7 @@ mdit-py-plugins==0.4.1
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
msgpack==1.0.8
|
||||
# via textual-dev
|
||||
# via textual-serve
|
||||
msgpack-types==0.3.0
|
||||
# via textual-serve
|
||||
@@ -70,11 +74,14 @@ sniffio==1.3.1
|
||||
# via anyio
|
||||
# via httpx
|
||||
textual==0.75.1
|
||||
# via textual-dev
|
||||
# via textual-serve
|
||||
textual-dev==1.5.1
|
||||
typing-extensions==4.12.2
|
||||
# via anyio
|
||||
# via rich
|
||||
# via textual
|
||||
# via textual-dev
|
||||
uc-micro-py==1.0.3
|
||||
# via linkify-it-py
|
||||
yarl==1.9.4
|
||||
|
||||
@@ -307,6 +307,7 @@ class AppService:
|
||||
)
|
||||
await self.remote_write_str(payload)
|
||||
elif meta_type == "deliver_file_start":
|
||||
log.info("deliver_file_start, %s", meta_data)
|
||||
try:
|
||||
# Record this delivery key as available for download.
|
||||
delivery_key = str(meta_data["key"])
|
||||
@@ -325,14 +326,6 @@ class AppService:
|
||||
# to start the download.
|
||||
json_string = json.dumps(["deliver_file_start", delivery_key])
|
||||
await self.remote_write_str(json_string)
|
||||
# TODO - Request chunks in the handler for "/download/{key}" instead
|
||||
# await self.send_meta(
|
||||
# {
|
||||
# "type": "deliver_chunk_request",
|
||||
# "key": delivery_key,
|
||||
# "size": 1024 * 64, # Request 64KB chunks
|
||||
# }
|
||||
# )
|
||||
elif meta_type == "deliver_file_end":
|
||||
try:
|
||||
delivery_key = str(meta_data["key"])
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass, field
|
||||
import logging
|
||||
from typing import AsyncGenerator
|
||||
from typing import AsyncGenerator, TYPE_CHECKING
|
||||
|
||||
from textual_serve.app_service import AppService
|
||||
if TYPE_CHECKING:
|
||||
from textual_serve.app_service import AppService
|
||||
|
||||
log = logging.getLogger("textual-serve")
|
||||
|
||||
@@ -13,7 +16,7 @@ DOWNLOAD_TIMEOUT = 4
|
||||
|
||||
@dataclass
|
||||
class Download:
|
||||
app_service: AppService
|
||||
app_service: "AppService"
|
||||
delivery_key: str
|
||||
file_name: str
|
||||
open_method: str
|
||||
@@ -45,7 +48,7 @@ class DownloadManager:
|
||||
async def create_download(
|
||||
self,
|
||||
*,
|
||||
app_service: AppService,
|
||||
app_service: "AppService",
|
||||
delivery_key: str,
|
||||
file_name: str,
|
||||
open_method: str,
|
||||
@@ -93,6 +96,7 @@ class DownloadManager:
|
||||
"""Download a file from the given app service.
|
||||
|
||||
Args:
|
||||
app_service: The app service to download from.
|
||||
delivery_key: The delivery key to download.
|
||||
"""
|
||||
|
||||
@@ -129,7 +133,7 @@ class DownloadManager:
|
||||
download = self._active_downloads[delivery_key]
|
||||
await download.incoming_chunks.put(chunk)
|
||||
|
||||
async def _get_app_service(self, delivery_key: str) -> AppService:
|
||||
async def _get_app_service(self, delivery_key: str) -> "AppService":
|
||||
"""Get the app service that the given delivery key is linked to.
|
||||
|
||||
Args:
|
||||
|
||||
Reference in New Issue
Block a user