[ ~/proxbox-api/developer ]tty0

   ___                _                       _    ___ ___
  | _ \_ _ _____ ___| |__  _____ __  ___    /_\  | _ \_ _|
  |  _/ '_/ _ \ \ /| '_ \/ _ \ \ /(_-<-_)  / _ \ |  _/| |
  |_| |_| \___/_\_\|_.__/\___/_\_\/__/__/ /_/ \_\|_|  |___|
   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)HTTPnetbox-sdk==0.0.8.post1
Proxmox VE (read source)HTTPproxmox-sdk==0.0.3.post1
Next.js admin UIembeddednextjs-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

install
emerson@netdevops:~$ uv sync --extra test --group dev

# pre-PR checks

  • lint

    shell
    uv run ruff check .
  • format

    shell
    uv run ruff format --check .
  • syntax compile

    shell
    uv run python -m compileall proxbox_api tests
  • type check (focused)

    shell
    uv run ty check proxbox_api/types proxbox_api/utils/retry.py proxbox_api/schemas/sync.py
  • unit + integration

    shell
    uv run pytest tests
  • Next.js admin UI

    shell
    cd 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.ymlpush + pull_request + release + manualRuns core pytest checks, Python 3.11 floor checks, free-threaded smoke, Docker bind smoke, and the NetBox E2E matrix.
publish-testpypi.ymlversion tags + GitHub releases + manualPublishes TestPyPI, PyPI rc/final, Docker images, and validates exact installs plus pre/post-publish E2E.
docker-hub-publish.ymlworkflow_call + manualBuilds and publishes raw, nginx, and granian Docker image variants.
release-docker-verify.ymlrelease + manualPulls published Docker tags and verifies each container variant starts.
nightly-schema-refresh.ymlschedule + manualRefreshes 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

    shell
    uv run pytest tests
  • E2E (mock backend, fast)

    shell
    uv run pytest tests/e2e -m mock_backend
  • E2E (mock HTTP, requires Docker)

    shell
    docker 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

emerson@netdevops:~/proxbox-api/developer$ links