flash-resume 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ """Flash Resume package."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+
7
+ # Ensure Windows terminal standard streams cleanly support UTF-8 characters and emojis
8
+ if sys.platform == "win32":
9
+ try:
10
+ if sys.stdout and hasattr(sys.stdout, "reconfigure"):
11
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
12
+ if sys.stderr and hasattr(sys.stderr, "reconfigure"):
13
+ sys.stderr.reconfigure(encoding="utf-8", errors="replace")
14
+ except Exception:
15
+ pass
16
+
17
+ __version__ = "0.2.0"
@@ -0,0 +1,112 @@
1
+ """Windows autostart registration for the companion server.
2
+
3
+ Registers a per-user Run-key entry so ``flash_resume.bootstrap`` (the silent
4
+ server boot) starts automatically at logon, with no console window and no
5
+ admin rights required.
6
+
7
+ Run key chosen over Task Scheduler: a single HKCU registry write, no
8
+ schtasks/COM edge cases, and it works without elevation.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import logging
14
+ import os
15
+ import sys
16
+ from pathlib import Path
17
+
18
+ logger = logging.getLogger("flash_resume.tailor")
19
+
20
+ RUN_KEY_PATH = r"Software\Microsoft\Windows\CurrentVersion\Run"
21
+ RUN_VALUE_NAME = "FlashResume"
22
+
23
+
24
+ class AutostartUnsupportedError(RuntimeError):
25
+ """Raised when autostart is requested on a non-Windows platform."""
26
+
27
+
28
+ def _require_windows() -> None:
29
+ if os.name != "nt":
30
+ raise AutostartUnsupportedError(
31
+ "Autostart is only supported on Windows. "
32
+ "Start the server manually with 'fs serve'."
33
+ )
34
+
35
+
36
+ def server_command() -> str:
37
+ """Return the command line used to silently start the server at logon.
38
+
39
+ Uses the ``pythonw.exe`` sibling of the running interpreter so no console
40
+ window is shown, invoking the ``flash_resume.bootstrap`` boot module.
41
+ """
42
+ pythonw = Path(sys.executable).with_name("pythonw.exe")
43
+ if not pythonw.exists():
44
+ pythonw = Path(sys.executable)
45
+ return f'"{pythonw}" -m flash_resume.bootstrap'
46
+
47
+
48
+ def install() -> str:
49
+ """Register the autostart Run-key value and return the command string."""
50
+ _require_windows()
51
+ cmd = server_command()
52
+ try:
53
+ import winreg
54
+
55
+ with winreg.OpenKey(
56
+ winreg.HKEY_CURRENT_USER,
57
+ RUN_KEY_PATH,
58
+ 0,
59
+ winreg.KEY_SET_VALUE,
60
+ ) as key:
61
+ winreg.SetValueEx(key, RUN_VALUE_NAME, 0, winreg.REG_SZ, cmd)
62
+ except OSError as e: # noqa: PERF203 - only reached on failure
63
+ logger.exception("Failed to write autostart Run key")
64
+ raise RuntimeError(f"Could not register autostart: {e}") from e
65
+ logger.info("Autostart registered: %s", cmd)
66
+ return cmd
67
+
68
+
69
+ def uninstall() -> bool:
70
+ """Remove the autostart Run-key value. Returns True if one was removed."""
71
+ _require_windows()
72
+ try:
73
+ import winreg
74
+
75
+ with winreg.OpenKey(
76
+ winreg.HKEY_CURRENT_USER,
77
+ RUN_KEY_PATH,
78
+ 0,
79
+ winreg.KEY_SET_VALUE | winreg.KEY_QUERY_VALUE,
80
+ ) as key:
81
+ try:
82
+ winreg.DeleteValue(key, RUN_VALUE_NAME)
83
+ except FileNotFoundError:
84
+ return False
85
+ except OSError as e:
86
+ logger.exception("Failed to remove autostart Run key")
87
+ raise RuntimeError(f"Could not unregister autostart: {e}") from e
88
+ logger.info("Autostart removed")
89
+ return True
90
+
91
+
92
+ def status() -> tuple[bool, str]:
93
+ """Return (is_registered, command_or_reason) for the autostart entry."""
94
+ _require_windows()
95
+ try:
96
+ import winreg
97
+
98
+ with winreg.OpenKey(
99
+ winreg.HKEY_CURRENT_USER,
100
+ RUN_KEY_PATH,
101
+ 0,
102
+ winreg.KEY_QUERY_VALUE,
103
+ ) as key:
104
+ try:
105
+ value, _ = winreg.QueryValueEx(key, RUN_VALUE_NAME)
106
+ except FileNotFoundError:
107
+ return False, "Not registered"
108
+ return True, value
109
+ except FileNotFoundError:
110
+ return False, "Run key path not present"
111
+ except OSError as e:
112
+ return False, f"Could not read Run key: {e}"
@@ -0,0 +1,29 @@
1
+ """Silent server-boot entrypoint for background autostart.
2
+
3
+ Runs the same FastAPI companion server as ``fs serve`` but is intended to be
4
+ invoked by a hidden ``pythonw`` process (no console window) at logon, so the
5
+ engine is always available to the Chrome extension without the user opening a
6
+ terminal.
7
+
8
+ Use directly with::
9
+
10
+ pythonw -m flash_resume.bootstrap
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+
16
+ def main() -> None:
17
+ """Start uvicorn on the same app/port the ``fs serve`` command uses."""
18
+ import uvicorn
19
+
20
+ uvicorn.run(
21
+ "flash_resume.services.server:app",
22
+ host="127.0.0.1",
23
+ port=8000,
24
+ reload=False,
25
+ )
26
+
27
+
28
+ if __name__ == "__main__":
29
+ main()