wesktop v0.7.0 /Changelog
On this page

#Changelog

#0.7.0

ASGI framework extracted to fastware. wesktop is now a thin desktop-app layer on top of fastware.

Context

All ASGI, SSE, middleware, server, auth, DI, testing, logging, tasks, features, error_log, audit, config, MCP, and dev modules have been extracted to the fastware package (v0.1.0). wesktop re-exports all symbols for backward compatibility, but the implementation lives in fastware. Four breaking changes: WebSocket binary frames, new server exception types, env var prefix rename, and fastware dependency added.

#Breaking

  • Breaking. Extracted ASGI framework modules to fastware package. wesktop now depends on fastware and re-exports all symbols. Import paths (from wesktop.asgi, from wesktop.server, etc.) continue to work but the underlying implementation is in fastware. Additional breaking changes: WebSocket send_json now sends binary frames (msgspec) instead of text frames; server errors raise PortInUseError/AlreadyRunningError instead of calling sys.exit(1); default env var prefix changed from WESKTOP_ to FASTWARE_.

#Features

  • Expanded CLI help texts for all commands and subcommands.

#0.6.0

#Features

  • Feature. serve_background() runs the server as an independent subprocess that survives the parent process exiting. run() now uses this for full window/server lifecycle separation.

#Fixes

  • Fix. Desktop entry launcher scripts no longer hardcode the working directory. Apps resolve paths from their package install location.

#0.5.0

#Breaking

  • Remove browser fallback from run(). run() no longer silently falls back to opening a browser when pywebview is unavailable. It now raises RuntimeError, making the failure explicit. Use serve() for headless/browser workflows.

#Features

  • Auto-register desktop entry. run() now automatically creates a desktop entry on first launch, removing the need for manual install commands.
  • PID resilience and single-instance mode. run() and serve() now handle stale PID files gracefully and support a single_instance parameter to prevent duplicate server instances.
  • Multi-window support. A second invocation of run() now opens a new native window connected to the existing server instead of restarting the server.

#Fixes

  • Resilient port check. Server startup now probes /health on the target port and can detect and kill stale server processes blocking the port, preventing silent startup failures.

#0.4.5

#Features

  • Feature. ensure_gui_backend() now searches macOS paths (Homebrew and Framework) for system PyGObject.

#Fixes

  • Fix. stop() now handles stale PID files gracefully instead of crashing with ProcessLookupError.

#0.4.4

#Features

  • Feature. ensure_gui_backend() finds and loads system PyGObject in isolated venvs. Called automatically by run().

#0.4.3

#Fixes

  • Fix. serve(foreground=False) signal handler patch now survives thread start race condition. Previous fix was ineffective because the noop was restored before the daemon thread executed startup.

#0.4.2

#Fixes

  • Fix. run() no longer crashes when pywebview has no GUI backend available (e.g., missing GTK/Qt in uv virtual environments).

#0.4.1

#Fixes

  • Fix. serve(foreground=False) no longer crashes with granian's signal handler registration in daemon threads. Fixes desktop mode (run()) and any background-server usage.
  • Fix. ViteDevProxy and dev() now use localhost instead of 127.0.0.1, fixing connectivity when Vite binds to IPv6 only.
  • Fix. ViteDevProxy now tries the backend first for all HTTP requests and only proxies to Vite on 404. Backend routes outside /api (like /health) are no longer incorrectly proxied.

#0.4.0

#Features

  • New feature. run() accepts a js_api parameter, passed through to pywebview's create_window() for exposing Python methods to JavaScript.
  • New feature. dev() starts a Vite dev server alongside the wesktop server in a single command, with ViteDevProxy for unified port access and automatic Vite lifecycle management.

#0.3.2

#Features

  • New feature. Forward reload parameter to run().

#Fixes

  • Fix. Query list coercion error handling, cached Request.state, typed Receive/Send aliases.
  • Fix. Merge lifespan state into WebSocket scope.
  • Fix. Replace private config path import with public config_file_path property.
  • Fix. Document optional MCP dependency in docstring.

#0.3.1

#Features

  • New feature. AppConfig dataclass for centralized app configuration via create_app().
  • New feature. serve(reload=True) auto-restarts the server on .py file changes.
  • New feature. MCP module with tool registration and routing support.
  • New feature. WebSocket.receive_raw() for mixed binary+text frame handling.
  • New feature. Broadcaster heartbeat_interval for SSE keepalive.

#Fixes

  • Fix. Recursive Pydantic model serialization in WebSocket send results.
  • Fix. Corrected module docstring to describe wesktop as a full-featured ASGI framework.

#0.3.0

#Breaking

  • Breaking. serve() API redesigned: foreground parameter is required (no default), host/port have no implicit defaults (must be explicit or via env vars).
  • Breaking. Error response format changed from {"error": "..."} to {"detail": "..."}. Query parameter type coercion failure now raises 422 instead of silently returning default.
  • Breaking. Module-level add_ws_route() removed. Use Router.ws() or Router.add_ws_route() instead (WebSocket routes are now app-scoped).

#Features

  • Router. Typed path parameters ({id:int}), greedy {key:path} matching, PUT/PATCH decorators, router composition with include_router (prefix mounting + router-level dependencies), app-scoped WebSocket routing with path params, WebSocket helper class.
  • Request/Response. Body reading for all HTTP methods, query_list() for multi-value params, query validation with constraints, cookie extraction, response headers/cookies with set_cookie/delete_cookie helpers, FileResponse, StreamResponse with configurable status, request.method/path/is_disconnected properties, State wrapper.
  • Dependency injection. Per-request DI with sync/async factory support, generator cleanup, dependency caching, dependency overrides for testing, router-level dependencies, feature-gated dependencies.
  • Auth module. JWT create/verify (HS256), bcrypt password hashing, JSONFileUserStore, get_current_user/require_role DI dependencies, CSRF double-submit middleware, session cookie helpers, decorator-based rate limiting.
  • Middleware and observability. structlog integration with auto-detect (JSON/console), RequestID/RequestTiming middleware, CORS and TrustedHost middleware, built-in middleware wiring in create_app, optional Sentry integration, SQLite error log for 5xx responses.
  • Pydantic integration. response_model parameter on route decorators for response validation, req.json_as(Model) for request body parsing with 422 error detail.
  • Server lifecycle. Unified serve() with stop()/status() utilities, pre_serve callback, app-namespaced env var settings, Vite dev proxy middleware.
  • Dev experience. TestClient (sync + async), TOML config loader with optional Pydantic validation.
  • Advanced features. Feature flags with JSON overrides, JSONL audit logging, background task registry with feature gating, 39 SDUI UI primitives with provider registry.

#Fixes

  • Fix. Pydantic BaseModel auto-serialization in responses and api_prefix-aware SPA fallback.

#0.2.1

#Fixes

  • Fix. Use PyPI-published strictcli instead of local source override. Fixes CI test failures.

#0.2.0

#Features

  • Lazy JSON. Request.json is now lazily parsed with caching, improving performance for handlers that don't need the body.
  • CLI with diagnose command. New wesktop diagnose command checks Python, Node, pywebview, and granian availability. Config file support via strictcli.

#Fixes

  • Icon fix. The icon parameter is now correctly wired through to pywebview.

#0.1.1

  • No user-facing changes.

#0.1.0

#Features

  • Initial release. ASGI router, SSE broadcaster, and extracted server lifecycle.
  • Desktop integration. pywebview, desktop entry creation, and public API exports.
  • npm shim. Install via npm i -g @smmh/wesktop for a global wesktop CLI that delegates to Python.