| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- """
- dev.py
- ======
- This script acts as a local development orchestrator. Instead of recreating the frontend
- in Python, which would violate the "Don't Repeat Yourself" (DRY) principle and introduce
- massive technical debt, this script leverages the existing architecture.
- It performs four main actions sequentially:
- 1. Executes `roi.py` to fetch the latest market data and generate the frontend JSON files.
- 2. Executes `bun install` to ensure frontend JS dependencies are present.
- 3. Executes `bun run build` to compile the TypeScript frontend into browser-ready JavaScript.
- 4. Spawns a local Python HTTP server pointing to the `www/` directory.
- """
- import os # Required for changing working directories and checking paths.
- import subprocess # Required for spawning external processes (like 'bun' and other python scripts).
- import sys # Required to grab the current Python executable path.
- import http.server # Required to run the local web server.
- import socketserver # Required to bind the HTTP handler to a specific port.
- def main() -> None:
- """
- Main execution function for the local development server orchestrator.
- """
- # -------------------------------------------------------------------------
- # STEP 1: GENERATE BACKEND DATA
- # -------------------------------------------------------------------------
- print(">>> [1/4] Running roi.py to generate updated JSON data...")
- try:
- subprocess.run([sys.executable, "roi.py"], check=True)
- except subprocess.CalledProcessError as e:
- sys.exit(f"!!! Error: Failed to execute roi.py. Process exited with code {e.returncode}")
- # -------------------------------------------------------------------------
- # STEP 2: INSTALL FRONTEND DEPENDENCIES
- # -------------------------------------------------------------------------
- # Unlike 'uv run', 'bun run' does not automatically install missing dependencies
- # defined in package.json. We must explicitly invoke 'bun install' first to
- # populate the node_modules/ directory.
- print(">>> [2/4] Installing frontend dependencies via Bun...")
- try:
- subprocess.run(["bun", "install"], check=True)
- except FileNotFoundError:
- # We catch the FileNotFoundError here because this is the first time 'bun' is invoked.
- sys.exit("!!! Error: 'bun' command not found. Please ensure Bun is installed (https://bun.sh/) and in your PATH.")
- except subprocess.CalledProcessError as e:
- sys.exit(f"!!! Error: Frontend dependency installation failed. Bun exited with code {e.returncode}")
- # -------------------------------------------------------------------------
- # STEP 3: BUILD THE FRONTEND
- # -------------------------------------------------------------------------
- # Compiles the TypeScript inside ts/ to JavaScript inside www/
- print(">>> [3/4] Building the TypeScript frontend using Bun...")
- try:
- subprocess.run(["bun", "run", "build"], check=True)
- except subprocess.CalledProcessError as e:
- sys.exit(f"!!! Error: Frontend build failed. Bun exited with code {e.returncode}")
- # -------------------------------------------------------------------------
- # STEP 4: SERVE THE FRONTEND LOCALLY
- # -------------------------------------------------------------------------
- print(">>> [4/4] Starting local development server...")
-
- PORT = 8000
- WEB_DIR = "www"
- if not os.path.isdir(WEB_DIR):
- sys.exit(f"!!! Error: Directory '{WEB_DIR}' does not exist. The build step may have failed silently.")
- os.chdir(WEB_DIR)
- Handler = http.server.SimpleHTTPRequestHandler
- with socketserver.TCPServer(("", PORT), Handler) as httpd:
- print(f">>> Serving at http://localhost:{PORT}")
- print(">>> Press Ctrl+C to stop the server.")
- try:
- httpd.serve_forever()
- except KeyboardInterrupt:
- print("\n>>> Shutting down development server gracefully. Goodbye!")
- if __name__ == '__main__':
- main()
|