Files
scalesApp/.claude/plans/venv-auto-activation.md
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

165 lines
6.1 KiB
Markdown

# 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
```bat
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:
```bat
.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:
```bat
.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`:
```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`:
```bat
@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`:
```bat
@echo off
call "%~dp0.venv\Scripts\activate.bat"
python "%~dp0serial_bridge\app.py"
```
- **`run_test.bat`** — currently `python .\test_comport_writer\test_writer.py`:
```bat
@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
```bat
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.