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>
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:
- The venv is not where VS Code looks. It lives at
backend/venv, but the Python extension's auto-discovery only scans for.venv/venvdirectly under the opened workspace folder (C:\dev_projects\ScalesApp) — one level above it. - No interpreter is configured. There is no
.vscode/settings.jsonin the project, and the user-level settings contain nopython.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. .gitignorealready ignores.vscode/andvenv/, and has a.venventry. The user chose to keep VS Code settings local, so no.gitignorechange 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.1andrequests==2.32.5. - Delete
backend/venvonly 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— currentlycd .\backend\thenuvicorn ...(also note: the file has no trailing newline). Activate from the root before thecd:@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— currentlypython .\serial_bridge\app.py:@echo off call "%~dp0.venv\Scripts\activate.bat" python "%~dp0serial_bridge\app.py" -
run_test.bat— currentlypython .\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.
- Interpreter —
.venv\Scripts\python.exe --version→Python 3.11.9. - Dependencies —
.venv\Scripts\python.exe -m pip check→ no issues;pip freezeshowspython-dotenv==1.0.1,requests==2.32.5. - Auto-activation — reload the VS Code window, open a new terminal:
prompt shows
(.venv);where pythonresolves to...\ScalesApp\.venv\Scripts\python.exe. - Django backend —
run_server.batfrom a plaincmd.exe(no venv pre-activated): uvicorn starts and serves onhttp://127.0.0.1:8000. Also confirmpython manage.py checkinbackend/reports no issues. - Serial bridge —
run_comport_reader.batstarts the Flask server on port 5000 without an import error (pyserial,flask,pystrayall resolve). - Test writer —
run_test.batlaunches 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.