generated from john/python-template
Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
co-authored by
Copilot App
parent
2093eb6fb3
commit
3873810022
@@ -60,6 +60,7 @@ WORKER_PROVIDER_TIMEOUT_SECONDS=30.0
|
||||
WORKER_STALE_JOB_SECONDS=30.0
|
||||
WORKER_RETRY_BACKOFF_SECONDS=1.0
|
||||
WORKER_SHUTDOWN_GRACE_SECONDS=5.0
|
||||
WORKER_POLL_INTERVAL_SECONDS=1.0
|
||||
WORKER_MIN_TRANSCRIPTION_CHARS=0
|
||||
WORKER_MIN_TRANSCRIPTION_LINES=0
|
||||
WORKER_FAIL_ON_FINISH_REASON_LENGTH=false
|
||||
|
||||
@@ -59,7 +59,7 @@ async def _lifespan(app: FastAPI):
|
||||
stop_event, worker_notifier, worker_health = await stack.enter_async_context(
|
||||
worker_consumer_lifespan(
|
||||
session_factory=app.state.runtime.session_factory,
|
||||
poll_interval_seconds=1.0,
|
||||
poll_interval_seconds=settings.worker_poll_interval_seconds,
|
||||
shutdown_timeout_seconds=(
|
||||
settings.worker_provider_timeout_seconds + settings.worker_shutdown_grace_seconds
|
||||
),
|
||||
|
||||
@@ -117,6 +117,7 @@ class Settings(BaseSettings):
|
||||
worker_stale_job_seconds: float = Field(default=30.0, gt=0.0)
|
||||
worker_retry_backoff_seconds: float = Field(default=1.0, ge=0.0)
|
||||
worker_shutdown_grace_seconds: float = Field(default=5.0, ge=0.0)
|
||||
worker_poll_interval_seconds: float = Field(default=1.0, gt=0.0)
|
||||
worker_min_transcription_chars: int = Field(default=0, ge=0)
|
||||
worker_min_transcription_lines: int = Field(default=0, ge=0)
|
||||
worker_fail_on_finish_reason_length: bool = False
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import hashlib
|
||||
import logging
|
||||
from collections.abc import Sequence
|
||||
@@ -398,6 +399,10 @@ async def store_source_file(
|
||||
)
|
||||
return StoredSourceFile(
|
||||
path=stored_path,
|
||||
file_hash=hashlib.sha256(file_bytes).hexdigest(),
|
||||
file_hash=await asyncio.to_thread(_sha256_hexdigest, file_bytes),
|
||||
file_size_bytes=len(file_bytes),
|
||||
)
|
||||
|
||||
|
||||
def _sha256_hexdigest(data: bytes) -> str:
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable
|
||||
|
||||
from fastapi import Request
|
||||
@@ -116,7 +117,7 @@ def _render_homepage_view(*, markdown_text: str, render_image_panel: Callable[[]
|
||||
ui.element("div")
|
||||
|
||||
|
||||
def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload) -> None:
|
||||
def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload, initial_markdown: str) -> None:
|
||||
with ui.grid().classes("w-full grid-cols-12 gap-4"):
|
||||
with ui.column().classes("col-span-12 lg:col-span-4 gap-4"):
|
||||
with archival_card(title="Homepage Image"):
|
||||
@@ -132,7 +133,7 @@ def _render_homepage_editor(*, render_image_panel, markdown_input, on_upload) ->
|
||||
markdown_input[0] = (
|
||||
ui.textarea(
|
||||
label="Homepage markdown",
|
||||
value=read_homepage_markdown(),
|
||||
value=initial_markdown,
|
||||
)
|
||||
.props("outlined autogrow")
|
||||
.classes("w-full")
|
||||
@@ -152,6 +153,7 @@ def register_page() -> None: # noqa: PLR0915
|
||||
render_navigation_header(current_path="/homepage")
|
||||
photos = await photos_service.list_photos(person_id=None)
|
||||
active_index = [0]
|
||||
homepage_markdown = [""]
|
||||
|
||||
@ui.refreshable
|
||||
def render_image_panel() -> None:
|
||||
@@ -172,12 +174,20 @@ def register_page() -> None: # noqa: PLR0915
|
||||
on_click=lambda: ui.navigate.to("/homepage/edit"),
|
||||
icon="edit",
|
||||
).classes("ui-btn-primary text-xs")
|
||||
|
||||
@ui.refreshable
|
||||
def render_home_content() -> None:
|
||||
_render_homepage_view(
|
||||
markdown_text=read_homepage_markdown().strip(),
|
||||
markdown_text=homepage_markdown[0].strip(),
|
||||
render_image_panel=render_image_panel,
|
||||
)
|
||||
|
||||
@ui.page("/homepage/edit", title="Edit Homepage")
|
||||
render_home_content()
|
||||
|
||||
homepage_markdown[0] = await asyncio.to_thread(read_homepage_markdown, settings)
|
||||
render_home_content.refresh()
|
||||
|
||||
@ui.page("/homepage/edit", title="Edit Home Page")
|
||||
async def homepage_edit_page(request: Request, session_factory: SessionFactoryDep) -> None: # noqa: PLR0915
|
||||
photos_service = PhotosService(session_factory=session_factory)
|
||||
settings = resolve_runtime_settings(request)
|
||||
@@ -268,7 +278,11 @@ def register_page() -> None: # noqa: PLR0915
|
||||
ui.navigate.to("/homepage/edit")
|
||||
|
||||
async def save_homepage() -> None:
|
||||
save_homepage_markdown((markdown_input[0].value if markdown_input[0] is not None else "") or "")
|
||||
await asyncio.to_thread(
|
||||
save_homepage_markdown,
|
||||
(markdown_input[0].value if markdown_input[0] is not None else "") or "",
|
||||
settings,
|
||||
)
|
||||
ui.notify("Homepage saved", type="positive")
|
||||
ui.navigate.to("/homepage")
|
||||
|
||||
@@ -283,4 +297,9 @@ def register_page() -> None: # noqa: PLR0915
|
||||
render_image_panel=render_image_panel,
|
||||
markdown_input=markdown_input,
|
||||
on_upload=on_upload,
|
||||
initial_markdown="",
|
||||
)
|
||||
|
||||
loaded_markdown = await asyncio.to_thread(read_homepage_markdown, settings)
|
||||
if markdown_input[0] is not None:
|
||||
markdown_input[0].value = loaded_markdown
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
@@ -540,8 +541,8 @@ async def _recover_prompt(prompts: PromptStore, name: str) -> None:
|
||||
|
||||
|
||||
async def _read_home_page_text(settings: Settings) -> str:
|
||||
return read_homepage_markdown(settings=settings)
|
||||
return await asyncio.to_thread(read_homepage_markdown, settings=settings)
|
||||
|
||||
|
||||
async def _write_home_page_text(settings: Settings, markdown_text: str) -> None:
|
||||
save_homepage_markdown(markdown_text, settings=settings)
|
||||
await asyncio.to_thread(save_homepage_markdown, markdown_text, settings=settings)
|
||||
|
||||
@@ -65,6 +65,7 @@ class TestAppLifespan:
|
||||
openrouter_api_key="test-key",
|
||||
environment="test",
|
||||
bootstrap_schema_on_startup=True,
|
||||
worker_poll_interval_seconds=2.5,
|
||||
upload_dir=tmp_path / "uploads",
|
||||
prompt_dir=tmp_path / "prompts",
|
||||
)
|
||||
@@ -80,6 +81,7 @@ class TestAppLifespan:
|
||||
assert "worker_start" in calls
|
||||
assert "worker_stop" in calls
|
||||
assert "dispose_db" in calls
|
||||
assert worker_kwargs["poll_interval_seconds"] == pytest.approx(settings.worker_poll_interval_seconds)
|
||||
assert worker_kwargs["shutdown_timeout_seconds"] == pytest.approx(
|
||||
settings.worker_provider_timeout_seconds + settings.worker_shutdown_grace_seconds
|
||||
)
|
||||
|
||||
@@ -170,6 +170,7 @@ class TestWorkerReliabilitySettings:
|
||||
assert settings.worker_stale_job_seconds == 30.0
|
||||
assert settings.worker_retry_backoff_seconds == 1.0
|
||||
assert settings.worker_shutdown_grace_seconds == 5.0
|
||||
assert settings.worker_poll_interval_seconds == 1.0
|
||||
|
||||
|
||||
def test_provider_timeout_is_not_capped_at_twenty_seconds():
|
||||
|
||||
@@ -170,6 +170,7 @@ def test_env_example_default_values_match_settings_defaults():
|
||||
"WORKER_STALE_JOB_SECONDS": str(defaults.worker_stale_job_seconds),
|
||||
"WORKER_RETRY_BACKOFF_SECONDS": str(defaults.worker_retry_backoff_seconds),
|
||||
"WORKER_SHUTDOWN_GRACE_SECONDS": str(defaults.worker_shutdown_grace_seconds),
|
||||
"WORKER_POLL_INTERVAL_SECONDS": str(defaults.worker_poll_interval_seconds),
|
||||
"WORKER_MIN_TRANSCRIPTION_CHARS": str(defaults.worker_min_transcription_chars),
|
||||
"WORKER_MIN_TRANSCRIPTION_LINES": str(defaults.worker_min_transcription_lines),
|
||||
"WORKER_FAIL_ON_FINISH_REASON_LENGTH": str(defaults.worker_fail_on_finish_reason_length).lower(),
|
||||
|
||||
Reference in New Issue
Block a user