Files
scalesApp/.claude/plans/venv-auto-activation.md
T
gitea fe9fb71860 Add implementation plans and remove stray Word temp file
Plans record the decisions behind each feature and, for the protocol and
licensing work, what remains unvalidated against real hardware.

~WRL0003.tmp was a Word autosave artifact committed by accident.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 18:58:38 +03:00

6.1 KiB

Auto-activate the Python venv in VS Code terminals

Context

Opening a terminal in VS Code does not activate the project's Python venv. Two causes:

  1. The venv is not where VS Code looks. It lives at backend/venv, but the Python extension's auto-discovery only scans for .venv/venv directly under the opened workspace folder (C:\dev_projects\ScalesApp) — one level above it.
  2. No interpreter is configured. There is no .vscode/settings.json in the project, and the user-level settings contain no python.defaultInterpreterPath. Without a known interpreter, the extension has nothing to activate.

Separately, none of the run_*.bat scripts activate the venv — they call python / uvicorn bare, so they only work when a venv happens to already be active.

Outcome: a single .venv at the project root that VS Code discovers automatically, plus batch scripts that activate it themselves and work from any shell state.

Findings that shape the plan

  • The existing backend/venv (Python 3.11.9, 138 MB) already has the dependencies from all three requirements files installed (Django + uvicorn, Flask + pyserial + pystray + PyInstaller). One shared root venv is therefore a faithful consolidation, not a new decision.
  • Base interpreter C:\dev\Python\Python311\python.exe (3.11.9) is present — verified.
  • .gitignore already ignores .vscode/ and venv/, and has a .venv entry. The user chose to keep VS Code settings local, so no .gitignore change is needed.

Decisions made

  • Consolidate into one root .venv (standard layout, zero-config discovery).
  • Version conflicts between requirements files: highest version wins — install order chosen so the result is python-dotenv==1.0.1 and requests==2.32.5.
  • Delete backend/venv only after the new venv is verified working.

Steps

1. Create the root venv

C:\dev\Python\Python311\python.exe -m venv C:\dev_projects\ScalesApp\.venv

→ verify: .venv\Scripts\python.exe --version prints Python 3.11.9.

2. Install dependencies (order matters)

Install so that the higher pin of each conflicting package is applied last:

.venv\Scripts\python.exe -m pip install --upgrade pip
.venv\Scripts\python.exe -m pip install -r backend\requirements.txt
.venv\Scripts\python.exe -m pip install -r test_comport_writer\requirements.txt
.venv\Scripts\python.exe -m pip install -r serial_bridge\requirements.txt

serial_bridge pins requests==2.32.5 (higher) and python-dotenv==1.0.0 (lower), so a final explicit pin is required to land on the intended "highest wins" result:

.venv\Scripts\python.exe -m pip install "python-dotenv==1.0.1"

→ verify: pip freeze shows python-dotenv==1.0.1 and requests==2.32.5, and pip check reports no broken dependencies.

3. Create .vscode/settings.json (local only, already gitignored)

New file — .vscode/settings.json:

{
  "python.defaultInterpreterPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe",
  "python.terminal.activateEnvironment": true
}

python.terminal.activateEnvironment defaults to true, but is stated explicitly here so the intent is visible and survives a future user-settings change.

→ verify: reload the VS Code window, open a fresh terminal, and confirm the prompt is prefixed with (.venv).

4. Make the batch scripts self-contained

Add a call to the venv activation script so each one works regardless of shell state.

  • run_server.bat — currently cd .\backend\ then uvicorn ... (also note: the file has no trailing newline). Activate from the root before the cd:

    @echo off
    call "%~dp0.venv\Scripts\activate.bat"
    cd /d "%~dp0backend"
    uvicorn scalesapp.asgi:application --host 127.0.0.1 --port 8000 --reload
    
  • run_comport_reader.bat — currently python .\serial_bridge\app.py:

    @echo off
    call "%~dp0.venv\Scripts\activate.bat"
    python "%~dp0serial_bridge\app.py"
    
  • run_test.bat — currently python .\test_comport_writer\test_writer.py:

    @echo off
    call "%~dp0.venv\Scripts\activate.bat"
    python "%~dp0test_comport_writer\test_writer.py"
    

%~dp0 (the directory of the batch file itself, with trailing backslash) makes each script independent of the caller's working directory. stop.bat needs no change — it only calls taskkill.

5. Remove the old venv — only after step 6 passes

rmdir /s /q C:\dev_projects\ScalesApp\backend\venv

Reclaims 138 MB and prevents two interpreters drifting apart.


Verification

Run in order; do not proceed to the deletion in step 5 until all of these pass.

  1. Interpreter — .venv\Scripts\python.exe --version → Python 3.11.9.
  2. Dependencies — .venv\Scripts\python.exe -m pip check → no issues; pip freeze shows python-dotenv==1.0.1, requests==2.32.5.
  3. Auto-activation — reload the VS Code window, open a new terminal: prompt shows (.venv); where python resolves to ...\ScalesApp\.venv\Scripts\python.exe.
  4. Django backend — run_server.bat from a plain cmd.exe (no venv pre-activated): uvicorn starts and serves on http://127.0.0.1:8000. Also confirm python manage.py check in backend/ reports no issues.
  5. Serial bridge — run_comport_reader.bat starts the Flask server on port 5000 without an import error (pyserial, flask, pystray all resolve).
  6. Test writer — run_test.bat launches without an import error.

If step 4 or 5 fails on a missing package, the old backend/venv is still intact — install the missing package into .venv rather than rolling back.


Files touched

File Change
.venv/ new — root venv (gitignored)
.vscode/settings.json new — interpreter path (gitignored, local only)
run_server.bat activate venv; use %~dp0 for path independence
run_comport_reader.bat same
run_test.bat same
backend/venv/ deleted after verification

No application code changes. .gitignore needs no edit — .vscode/, venv/ and .venv are all already covered.