___ _ _ ___ ___ | _ \_ _ _____ ___| |__ _____ __ ___ /_\ | _ \_ _| | _/ '_/ _ \ \ /| '_ \/ _ \ \ /(_-<-_) / _ \ | _/| | |_| |_| \___/_\_\|_.__/\___/_\_\/__/__/ /_/ \_\|_| |___| p r o x m o x ⇄ n e t b o x · f a s t a p i
emerson@netdevops:~/proxbox-api$ ./describe.sh proxbox-api
Developer guide — FastAPI orchestration, SDK boundaries, contribution workflow and the Docker E2E matrix.
proxbox-api is the FastAPI service that bridges Proxmox VE and NetBox. It owns the sync workflow that the netbox-proxbox plugin triggers from inside NetBox and exposes REST + Server-Sent Events + WebSocket endpoints to stream live progress back.
This page covers the layered architecture, what proxbox-api takes as a dependency vs. proxies at runtime, the contribution workflow, and the multi-mode E2E matrix that exercises every transport before a release ships.
›intro
emerson@netdevops:~/proxbox-api/developer$ cat README.md | head
proxbox-api is the FastAPI service that bridges Proxmox VE and NetBox. It owns the sync workflow that the netbox-proxbox plugin triggers from inside NetBox and exposes REST + Server-Sent Events + WebSocket endpoints to stream live progress back.
This page covers the layered architecture, what proxbox-api takes as a dependency vs. proxies at runtime, the contribution workflow, and the multi-mode E2E matrix that exercises every transport before a release ships.
›architecture
emerson@netdevops:~/proxbox-api/developer$ tree -L 2 src/
- ├─ASGI entrypoint: uvicorn proxbox_api.main:app. The app is assembled by proxbox_api.app.factory.create_app() — initializes the SQLite database (sqlmodel + aiosqlite), builds the default NetBox session, and registers the generated Proxmox proxy routes.
- ├─Layers: routes/ (FastAPI routers — auth, dcim, extras, netbox, proxbox, proxmox, sync, virtualization) → services/sync/ (workflow orchestration) → schemas/ + enum/ (Pydantic 2 validation at every I/O boundary) → proxmox_to_netbox/ (transformation) → session/ (NetBox + Proxmox client factories as FastAPI dependencies).
- ├─Sync runs stream Server-Sent Events plus optional WebSocket progress. /full-update/stream drives the complete chain: devices → storage → VMs → disks → backups → snapshots → interfaces → IPs → backup routines → replications.
- ├─Auth: bcrypt-hashed API key in the X-Proxbox-API-Key header with brute-force lockout (proxbox_api/auth.py). Credentials at rest are Fernet-encrypted (PROXBOX_ENCRYPTION_KEY required in production).
- ├─Persistence: SQLModel + aiosqlite for endpoint and key storage; no PostgreSQL dependency on the proxbox-api side.
- ├─Concurrency knobs: PROXBOX_NETBOX_TIMEOUT (120s), PROXBOX_NETBOX_MAX_CONCURRENT (default 1, intentionally low), PROXBOX_VM_SYNC_MAX_CONCURRENCY, PROXBOX_NETBOX_GET_CACHE_TTL (60s GET cache, 0 disables), PROXBOX_RATE_LIMIT (60 req/min/IP via SlowAPI).
- ├─Embedded admin UI: nextjs-ui/ — a Next.js frontend used to administer endpoints, separate build target.
- ├─Generated proxy routes: proxbox_api/generated/ holds 646 typed Proxmox endpoints crawled from the Proxmox API Viewer. Do not edit by hand — regenerate from proxbox-api/proxmox_codegen/.
›integrations
emerson@netdevops:~/proxbox-api/developer$ ./describe-integrations
| › target | › protocol | › library |
|---|---|---|
| netbox-proxbox (NetBox plugin) | HTTP REST + SSE + WebSocket (inbound) | consumer — auth via X-Proxbox-API-Key |
| NetBox REST API (write target) | HTTP | netbox-sdk==0.0.8.post1 |
| Proxmox VE (read source) | HTTP | proxmox-sdk==0.0.3.post1 |
| Next.js admin UI | embedded | nextjs-ui/ (separate build) |
- › netbox-proxbox (NetBox plugin): Every Full Update click in the plugin lands here as a request to /full-update/stream.
- › NetBox REST API (write target): Async aiohttp client sessions in proxbox_api/session/ + helpers in proxbox_api/netbox_rest.py. Cached GET layer (60s TTL) shared across the workflow.
- › Proxmox VE (read source): Read-only — the workflow never POST/PUT/DELETEs back into Proxmox. Mock backend (MockBackend) used for fast tests.
- › Next.js admin UI: Manages bcrypt API keys, encrypted credentials and endpoint records via the same FastAPI surface.
›contributing
emerson@netdevops:~/proxbox-api/developer$ ./contributing --help
# dev install
# pre-PR checks
› lint
shelluv run ruff check .
› format
shelluv run ruff format --check .
› syntax compile
shelluv run python -m compileall proxbox_api tests
› type check (focused)
shelluv run ty check proxbox_api/types proxbox_api/utils/retry.py proxbox_api/schemas/sync.py
› unit + integration
shelluv run pytest tests
› Next.js admin UI
shellcd nextjs-ui && npm run lint && npm run build
# code style
- ├─Linter: ruff (select E4/E7/E9/F/I/ANN201/D103/W/C90, max complexity 10).
- ├─Formatter: ruff format.
- ├─Type checker: ty.
- ├─PRs must include a passing run of all the checks above; the CI core job runs pytest tests/ -v --ignore=tests/e2e on every push and PR.
# issue tracker https://github.com/emersonfelipesp/proxbox-api/issues
›ci
emerson@netdevops:~/proxbox-api/developer$ gh workflow list
The backend CI is layered: fast Python checks, Docker image startup checks, generated E2E matrix setup, NetBox image fallback handling, and full NetBox-backed sync validation.
The publish workflow validates TestPyPI first, promotes PyPI release candidates only after candidate checks, then publishes Docker images and runs post-publish E2E against the released artifacts.
# workflows
| › workflow | › trigger | › purpose |
|---|---|---|
| ci.yml | push + pull_request + release + manual | Runs core pytest checks, Python 3.11 floor checks, free-threaded smoke, Docker bind smoke, and the NetBox E2E matrix. |
| publish-testpypi.yml | version tags + GitHub releases + manual | Publishes TestPyPI, PyPI rc/final, Docker images, and validates exact installs plus pre/post-publish E2E. |
| docker-hub-publish.yml | workflow_call + manual | Builds and publishes raw, nginx, and granian Docker image variants. |
| release-docker-verify.yml | release + manual | Pulls published Docker tags and verifies each container variant starts. |
| nightly-schema-refresh.yml | schedule + manual | Refreshes generated Proxmox schemas and opens a PR when artifacts change. |
# notes
- ├─E2E jobs wait up to 20 minutes for NetBox migrations/search indexing and require /api/status/ before token setup.
- ├─The E2E job pulls public NetBox images first and downloads the source-built artifact only when registry pull fails.
- ├─Docker-backed Proxmox E2E uses mock_http; the in-process MockBackend pass uses mock_backend.
- ├─The public MkDocs source of truth is docs/development/ci-e2e-workflows.md.
›e2e
emerson@netdevops:~/proxbox-api/developer$ ./run-e2e --report
› framework
pytest + pytest-asyncio + httpx.AsyncClient. Two marker modes — mock_backend (in-process, no HTTP) and mock_http (against a running proxmox-sdk container).
The fast loop runs entirely in-process against MockBackend; no Docker, no network. The full loop spins up proxmox-sdk on 8006/8007 and a live NetBox container, and exercises every supported transport combination.
The release workflow is staged: normal and post tags publish to TestPyPI, PyPI release candidates use vX.Y.ZrcN, and the final PyPI package plus Docker images publish only after package reinstall validation and E2E gates pass.
# commands
› all unit + integration
shelluv run pytest tests
› E2E (mock backend, fast)
shelluv run pytest tests/e2e -m mock_backend
› E2E (mock HTTP, requires Docker)
shelldocker compose up -d && uv run pytest tests/e2e -m mock_http
# coverage
- ├─Spec files: tests/e2e/conftest.py, test_vm_sync.py, test_devices_sync.py, test_backups_sync.py, test_demo_auth.py.
- ├─Markers: @pytest.mark.mock_backend (in-process MockBackend) and @pytest.mark.mock_http (proxmox-sdk Docker container on ports 8006/8007).
- ├─Auth helpers in proxbox_api/e2e/ are the only place Playwright is used in the backend.
- ├─CI: ci.yml runs the core test job (pytest excluding tests/e2e) plus an E2E Docker matrix of 6 transport combos × netbox_proxbox_mode.
- ├─Release gate: publish-testpypi.yml validates TestPyPI installs first, then PyPI rc/final installs, Docker image publish, and post-publish E2E.
› ci workflow: .github/workflows/ci.yml
›links
emerson@netdevops:~/proxbox-api/developer$ links
- repo → https://github.com/emersonfelipesp/proxbox-api
- docs → https://emersonfelipesp.github.io/proxbox-api/
- plugin → https://github.com/N-Multifibra/netbox-proxbox
- netbox-sdk → https://github.com/emersonfelipesp/netbox-sdk
- proxmox-sdk → https://github.com/emersonfelipesp/proxmox-sdk
- issues → https://github.com/emersonfelipesp/proxbox-api/issues