Skip to content

Windows 11 — local dev setup

End-to-end instructions for getting Onyx running on a clean Windows 11 box.

End-to-end instructions for getting Onyx running on a clean Windows 11 box. Aimed at developers; assumes an Administrator account for the system-software installs and PowerShell as the default shell.

One-line summary: install Python 3.11, Git, Tesseract, Poppler → clone → py -3.11 -m venv venv → activate → pip install -r REQUIREMENTS_DEVELOPMENT.txt → fill .envpython main.py --port 5002.


0. Prerequisites — what you’re about to install

Section titled “0. Prerequisites — what you’re about to install”
ToolWhySource
Python 3.11Onyx requires >=3.11 (pyproject.toml)python.org or winget
Git for Windowsclone the repo, gives you git + Git Bashgitforwindows.org
Tesseract OCRneeded by pytesseract (POD/PPD OCR)tesseract-ocr/tesseract
Poppler for Windowsneeded by pdf2image (PDF → image rendering)oschwartz10612/poppler-windows releases
VS Code (recommended)editor + integrated PowerShell terminalcode.visualstudio.com

You do not need to install PostgreSQL — local dev points at a Supabase pooler.

Tip for IT admins: every install below works without admin once the user is in the Developer Mode group. If your devs can’t elevate, install Python/Git/Tesseract/Poppler to C:\Users\<name>\ directories and add them to the User PATH.


Open PowerShell as Administrator:

Terminal window
winget install --id Python.Python.3.11 --source winget

Verify (open a new PowerShell window):

Terminal window
py -3.11 --version
# expected: Python 3.11.x
  1. Download “Windows installer (64-bit)” for Python 3.11.x from python.org/downloads/windows.
  2. Run it and check these boxes:
    • ✅ “Add python.exe to PATH”
    • ✅ “Install for all users” (if you have admin)
    • ✅ “Disable path length limit” (final screen — enables long paths globally)
  3. Reboot once after install so PATH changes propagate.

Windows can have multiple Python versions side-by-side. The py launcher (installed with Python) picks the right one explicitly: py -3.11 always runs 3.11 even if 3.12 or 3.10 is also on the box. Use py -3.11 for the initial venv creation; after activation the venv’s python already points at 3.11.

⚠️ Avoid the Microsoft Store version of Python — it sandboxes site-packages in a way that breaks pip install of some native-wheel packages (notably psycopg2-binary quirks). Use the python.org or winget version.


Terminal window
winget install --id Git.Git --source winget

…or grab the installer from gitforwindows.org. Defaults are fine. Two settings worth knowing:

  • “Checkout as-is, commit Unix-style line endings” (the core.autocrlf=input option) — recommended. Onyx is a cross-platform codebase; storing LF on disk is safer.
  • “Use Windows’ default console window” is fine; Git Bash works either way.

After install, in PowerShell:

Terminal window
git --version
git config --global core.autocrlf input
git config --global core.longpaths true

core.longpaths true is important because some Python tooling generates >260-char paths inside venv\Lib\site-packages\….


Onyx’s OCR features (pytesseract) need the Tesseract binary on PATH.

  1. Download the UB-Mannheim Windows installer: https://github.com/UB-Mannheim/tesseract/wiki (the “tesseract-ocr-w64-setup-X.Y.Z.exe” link).
  2. Install. Default path is C:\Program Files\Tesseract-OCR\ — leave it.
  3. Add to PATH manually (the installer doesn’t always do this):
    • Open Settings → System → About → Advanced system settings → Environment Variables
    • In User variables, edit PathNew → add C:\Program Files\Tesseract-OCR
  4. Restart PowerShell, verify:
Terminal window
tesseract --version
# expected: tesseract v5.x.x

Needed by pdf2image for PDF rendering. No installer — just unzip + add to PATH.

  1. Download the latest “Release” zip from https://github.com/oschwartz10612/poppler-windows/releases. Pick the Release-XX.YY.0-0.zip file.
  2. Extract to C:\Program Files\poppler\. After extraction you should have C:\Program Files\poppler\Library\bin\pdftoppm.exe.
  3. Add C:\Program Files\poppler\Library\bin to your PATH (same way as Tesseract above).
  4. Restart PowerShell, verify:
Terminal window
pdftoppm -v
# expected: pdftoppm version 24.x.x or similar

Terminal window
mkdir C:\dev
cd C:\dev
git clone https://github.com/corlogic-au/onyx-python-flask-webapp.git
cd onyx-python-flask-webapp

Pick C:\dev\… (or any short root path) rather than C:\Users\<long-name>\OneDrive\Desktop\…. Long ancestor paths consume the path-length budget.

If you’re a workspace user with all 4 sibling repos: place onyx-python-flask-webapp next to omega-python31-restapi, osiris-stenciljs-widget-webapp, and demo-osiris-widget under the same parent.


6. Create + activate the virtual environment

Section titled “6. Create + activate the virtual environment”
Terminal window
py -3.11 -m venv venv
.\venv\Scripts\Activate.ps1

Prompt should now show (venv) at the front.

If activation fails with “running scripts is disabled”

Section titled “If activation fails with “running scripts is disabled””

Windows PowerShell blocks unsigned scripts by default. One-time fix (user-scope, no admin needed):

Terminal window
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

Then re-run .\venv\Scripts\Activate.ps1.

Terminal window
venv\Scripts\activate.bat
Terminal window
source venv/Scripts/activate

Terminal window
python -m pip install --upgrade pip wheel setuptools
pip install -r REQUIREMENTS_DEVELOPMENT.txt

This takes 2–5 minutes. The native-wheel packages (psycopg2-binary, Pillow, opencv-python-headless, lxml, cryptography) all have pre-built Windows wheels on PyPI — no compilers needed.

Almost always a PATH or proxy issue rather than the wheel itself. Try:

Terminal window
pip install --upgrade pip
pip install psycopg2-binary --no-cache-dir

If your network requires a proxy, set it for the session:

Terminal window
$env:HTTP_PROXY = "http://your.proxy:8080"
$env:HTTPS_PROXY = "http://your.proxy:8080"

The repo doesn’t ship .env. Create it at the repo root and fill the values your team uses for the dev environment:

Terminal window
notepad .env

Minimum content for local dev:

# Flask
FLASK_ENV=development
FLASK_DEBUG=True
FLASK_SECRET_KEY=local-dev-not-a-real-secret
# Supabase Postgres — USE PORT 6543 (transaction pooler).
# Do NOT use 5432 (session mode, hard 15-client cap → "EMAXCONNSESSION" failures on any page that fires multiple parallel fetches.)
DATABASE_URL=postgresql://postgres.<project_ref>:<password>@aws-1-ap-northeast-2.pooler.supabase.com:6543/postgres
# Optional integrations — leave the iDrv4 block out unless you actually need to call Ceres
# IDRV4_BASE_URL=https://dev1.ceres.idrv.app/v3
# IDRV4_OAUTH_TOKEN_URL=https://dev1.ceres.idrv.app/oauth/token
# IDRV4_CLIENT_ID=<your sandbox client uuid>
# IDRV4_CLIENT_SECRET=<your sandbox client secret>
# IDRV4_SCOPES=consignment.write consignment.read

Ask your team lead for the actual DATABASE_URL. The currently-active Supabase project is rfyswlrbzyzuaxwvvrrd (host: aws-1-ap-northeast-2.pooler.supabase.com); credentials are shared out-of-band.

⚠️ Port 6543 vs 5432 — non-obvious gotcha. Supabase’s pooler exposes both. Port 5432 is session mode and caps the entire project at 15 concurrent connections — pages that fire several parallel fetches will randomly 500 with FATAL: (EMAXCONNSESSION) max clients reached, which surfaces in the UI as a confusing “Error loading X”. Port 6543 is transaction mode and effectively unbounded for normal traffic. Always use 6543.

⚠️ .env is gitignored. Don’t commit it. There is no .env.example in this repo today; ask a teammate for the dev credentials or copy production_env_template.txt and edit it down.


Terminal window
python main.py --port 5002

You should see something like:

* Running on http://127.0.0.1:5002
* Debugger is active!

Open http://localhost:5002/login in your browser. Sign in with a dev account (ask team lead for credentials — operations1 / password123 works on the shared dev DB at time of writing).


Quick smoke check, all in PowerShell:

Terminal window
# (venv) on, in repo root
python -c "import flask, sqlalchemy, psycopg2, openpyxl, pytesseract, pdf2image; print('imports ok')"
# Tesseract reachable from Python
python -c "from pytesseract import get_tesseract_version; print('tesseract', get_tesseract_version())"
# Poppler reachable from Python (pdf2image checks PATH internally)
python -c "from pdf2image import pdfinfo_from_path; print('poppler ok')" 2>$null
# Database reachable
python -c "from main import app; ctx=app.app_context(); ctx.push(); from models.database import db; from sqlalchemy import text; print('db tip:', db.session.execute(text('SELECT 1')).scalar())"

All four should print without errors. If the database one hangs >10s, you’re almost certainly on port 5432 — re-check .env.


”Activate.ps1 cannot be loaded because running scripts is disabled”

Section titled “”Activate.ps1 cannot be loaded because running scripts is disabled””

See section 6. One-line fix: Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned.

psycopg2.OperationalError: ... could not connect to server

Section titled “psycopg2.OperationalError: ... could not connect to server”

Three usual causes, in order:

  1. Wrong port in DATABASE_URL — must be 6543, not 5432.
  2. Wrong password — Supabase pooler URLs include the password inline; copy/paste from your team’s secrets vault.
  3. Corporate firewall blocking outbound TCP/6543 — try from a phone hotspot to confirm.

Tesseract isn’t on PATH. After install, restart your terminal — PATH changes don’t propagate to existing shells. Verify with tesseract --version in a fresh PowerShell window.

pdf2image errors about “Unable to get page count”

Section titled “pdf2image errors about “Unable to get page count””

Same as Tesseract — Poppler bin folder isn’t on PATH. Or you installed Poppler somewhere other than C:\Program Files\poppler\ and the PATH entry still points at the default.

File-watch hot-reload kicks in constantly under VS Code

Section titled “File-watch hot-reload kicks in constantly under VS Code”

Onyx uses Flask’s debug reloader. On Windows with VS Code’s auto-save, this can trigger a reload every keystroke. Either:

  • Disable VS Code’s Files: Auto Save, or
  • Run with --no-reload:
Terminal window
python main.py --port 5002 --no-reload

You either skipped Disable path length limit in the Python installer, or your project lives somewhere like C:\Users\<name>\OneDrive\Desktop\...\onyx-python-flask-webapp\venv\Lib\site-packages\.... Two fixes:

  1. Re-run the Python installer in “Modify” mode and tick “Disable path length limit”.
  2. Move the project to C:\dev\onyx-python-flask-webapp\ (short ancestor path).

Also: git config --global core.longpaths true (we set this in §2).

.env line endings change every time you save

Section titled “.env line endings change every time you save”

Configure VS Code to use LF for .env and the repo’s Python files:

In VS Code → Status bar (bottom-right) → click “CRLF” → choose “LF” — once per file. Or add to .vscode/settings.json:

{
"files.eol": "\n"
}

For ad-hoc queries against the Supabase dev DB:

Then connect using the same host / port / user / password / database from your DATABASE_URL.


13. Optional: enable Developer Mode (once per machine)

Section titled “13. Optional: enable Developer Mode (once per machine)”

Settings → Privacy & security → For developers → Developer Mode = On

This:

  • Lets PowerShell run unsigned scripts without Set-ExecutionPolicy.
  • Removes the long-path restriction for new processes.
  • Enables symlink creation without admin (some pip packages use symlinks).

Not strictly required, but it removes a class of “huh, that worked on Mac” papercuts.


  • Branching / PR conventions: ONBOARDING.md at the repo root (workflow + PR templates).
  • Architecture overview: docs/QUICK_START.md.
  • Deployment to Railway: docs/DEPLOYMENT.md.
  • iDrv4 / Ceres integration: docs/IDRV4_INTEGRATION.md.
  • The workspace’s CLAUDE.md (one directory up) describes how this repo fits with omega-python31-restapi, osiris-stenciljs-widget-webapp, and demo-osiris-widget.

Terminal window
# 1. system tools (admin PowerShell, once)
winget install --id Python.Python.3.11 --source winget
winget install --id Git.Git --source winget
# install Tesseract + Poppler manually (sections 3 & 4) — add to PATH
# 2. one-time PowerShell setting (user PowerShell)
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
# 3. clone + venv + deps
cd C:\dev
git clone https://github.com/corlogic-au/onyx-python-flask-webapp.git
cd onyx-python-flask-webapp
py -3.11 -m venv venv
.\venv\Scripts\Activate.ps1
python -m pip install --upgrade pip wheel
pip install -r REQUIREMENTS_DEVELOPMENT.txt
# 4. .env — fill from team's dev secrets vault
notepad .env
# 5. run
python main.py --port 5002

Open http://localhost:5002/login.