Skip to content

fix: restore backend startup (could not import) + repair CLI syntax errors, add tests - #8

Merged
OneByJorah merged 3 commits into
masterfrom
hermes/2026-10-08-fix-backend-startup
Oct 8, 2026
Merged

OneByJorah merged 3 commits into
masterfrom
hermes/2026-10-08-fix-backend-startup

Conversation

@OneByJorah

Copy link
Copy Markdown
Owner

Problem

The backend cannot start at all. import main dies with:

AttributeError: 'Settings' object has no attribute 'OPENAI_API_KEY'

Four separate defects each block import or execution.

N1 — CRITICAL: missing Settings fields break startup

backend/config.py reads settings.OPENAI_API_KEY in its validation block, but the
Settings model no longer defines that field (nor OPENAI_MODEL).

Git history pins it: commit 5e43b24 deleted these lines

OPENAI_API_KEY: Optional[str] = None
OPENAI_MODEL: str = "gpt-4o"

and in the same commit added the validation if not settings.OPENAI_API_KEY:. Every
commit up to 9d9c4b6 defined the fields and was importable; 5e43b24 broke startup
completely for API, CLI, Docker and docs alike.

N2 — syntax error in backend/routers/chat.py

Line 18's docstring was indented 8 spaces inside a 4-space function → IndentationError.
This blocked main.py immediately after N1 was cleared.

N3 — syntax error in scripts/cli.py

Line 151 held a string literal split by real newlines → SyntaxError: unterminated string literal.

N4 — syntax error in scripts/nethermind.py

main() read module-global API_BASE (line 251, in the --help f-string) before its
global API_BASE declaration (line 329) → SyntaxError: name 'API_BASE' is used prior to global declaration.

Changes

  • Restore OPENAI_API_KEY / OPENAI_MODEL to Settings (+ comment so they aren't removed again).
  • Fix the mis-indented docstring in chat.py.
  • Restore the \n escapes in cli.py.
  • Move global API_BASE to the top of main().
  • Add a test suite (11 tests) — the repo configured pytest but shipped none.
  • frontend/package-lock.json: npm synced the stale name nethermind → netcore.
  • Add AUDIT.md and PERSONA.md.

Verification (real commands)

Check Before After
import main AttributeError OK — 67 routes
uvicorn main:app crash at import runs
GET /, /api/switches/, /api/dashboard/stats, /docs, /openapi.json — all 200
Syntax errors in tree 3 0
pytest tests/ -q no tests 11 passed
scripts/nethermind.py --help SyntaxError runs
gitleaks clean clean
  • Frontend npm run build → compiled, TypeScript clean, 12 pages.
  • UI served on the documented port 3000 → 0 console errors, dashboard renders live data from this backend.
  • Test DB isolation verified by mtime: the real backend/switches.db was untouched.

Not verified (honest gaps)

  • No real switch was contacted — everything is API-level against an empty database; the Netmiko SSH/serial paths are unexercised.
  • No Docker on the build host, so docker-compose.yml was not run.
  • 285 pre-existing ruff errors (195 auto-fixable) are not touched here — that belongs in its own reviewed PR rather than mixed into a critical fix.
  • AGENTS.md and CLAUDE.md are pre-existing untracked files in the repo root; deliberately left alone.

Publishing mode is draft: this PR is for review, nothing was released.

openhands-agent and others added 3 commits October 7, 2026 09:11
The backend could not start at all. Fixes four defects that each block import
or execution:

1. backend/config.py - Settings no longer defined OPENAI_API_KEY / OPENAI_MODEL,
   but the validation block read settings.OPENAI_API_KEY, raising
   AttributeError: 'Settings' object has no attribute 'OPENAI_API_KEY' at import.
   Regression introduced by 5e43b24, which deleted the two field definitions and
   in the same commit added the validation that reads them. Restored both fields.

2. backend/routers/chat.py:18 - docstring indented 8 spaces inside a 4-space
   function body -> IndentationError, blocking main.py.

3. scripts/cli.py:151 - string literal split across real newlines ->
   SyntaxError: unterminated string literal. Restored the \n escapes.

4. scripts/nethermind.py - main() read global API_BASE (line 251) before its
   global declaration (line 329) -> SyntaxError. Moved the declaration to the
   top of main().

Verified: import main -> OK with 67 routes; uvicorn serves / , /api/switches/,
/api/dashboard/stats, /docs, /openapi.json all 200; scripts/nethermind.py --help
runs; full tree compiles with 0 syntax errors.
The repo declared pytest config (testpaths=["tests"], python_files=["test_*.py"])
but shipped no tests — tests/ contained only a mock_switch.py helper.

- tests/conftest.py — puts backend/ on sys.path and redirects DATABASE_URL to a
  temporary sqlite file *before* main is imported, so the real switches.db is
  never touched. Tests use a per-test TestClient fixture.
- tests/test_api.py — 11 tests: app metadata, OpenAPI route presence, dashboard
  stats shape, switch list/create/read-back, dashboard count reflects a created
  switch, and 5 pure-logic unit tests of the ArubaOS/ProCurve running-config
  parser (scalars, role detection, services, VLAN block parsing, empty input).
- frontend/package-lock.json — npm synced the stale package name "nethermind"
  to "netcore" while building; matches package.json.

Verified: cd . && .venv/bin/python -m pytest tests/ -q -> 11 passed.
DB isolation verified by mtime (real switches.db untouched). ruff clean on both
new files. gitleaks clean.
@OneByJorah
OneByJorah merged commit deb53c8 into master Oct 8, 2026
2 of 3 checks passed
@OneByJorah

Copy link
Copy Markdown
Owner Author

Superseded by #9, which was retargeted to master and merged (ac255d7).

This branch was stacked, and its CI showed Backend Lint: fail — expected, because the lint fix lived in #9 rather than here. Merging this PR on its own would have put a red check on master, so instead #9 (which contains all three commits: the startup fixes, the tests, and the lint cleanup) was merged directly to master.

Verified: git log origin/master..origin/hermes/2026-10-08-fix-backend-startup is empty — every commit here is already in master. Nothing is lost. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants