Mock API Mode¶
Complete guide to using proxmox-sdk in mock mode for development and testing.
Overview¶
Mock mode provides a fully functional Proxmox API simulation with:
- ✅ 675 generated operations across 449 Proxmox API paths
- ✅ Metadata-driven route registration from bundled
route_metadata.json - ✅ Lazy Pydantic model loading from route-group model shards
- ✅ CRUD operations - Create, read, update, delete
- ✅ Automatic data seeding - Sample data generated on first access
- ✅ SQLite/WAL state by default - Changes persist across requests in the active mock namespace
- ✅ Custom mock data - Load your own test data from JSON/YAML
Starting Mock Mode¶
Method 1: Dedicated Mock Server¶
This runs a standalone mock-only server.
Method 2: Main App in Mock Mode (Default)¶
# Mock mode is the default
uvicorn proxmox_sdk.main:app
# Or explicitly set mock mode
export PROXMOX_API_MODE=mock
uvicorn proxmox_sdk.main:app
Both methods provide the same functionality.
How Mock Data Works¶
Automatic Seeding¶
When you make your first GET request to an endpoint, mock data is automatically generated:
import httpx
# First GET request - data doesn't exist yet
response = httpx.get("http://localhost:8000/api2/json/nodes")
# Mock data automatically created and returned:
# [{"node": "pve", "status": "online", ...}]
State Persistence¶
Changes persist during the server lifetime through the configured mock-state backend. The default is SQLite/WAL, which stores objects, collection members, and tombstones as rows in a tempdir-scoped database:
# Create a VM
httpx.post(
"http://localhost:8000/api2/json/nodes/pve/qemu",
json={"vmid": 100, "name": "test-vm"}
)
# Later requests return the same VM
response = httpx.get("http://localhost:8000/api2/json/nodes/pve/qemu/100")
print(response.json()) # Returns the VM we created
Development state, not production persistence
The default SQLite database is scoped by mock namespace and schema
fingerprint. It is designed for development and tests, not as a durable
database. Set PROXMOX_MOCK_STATE_PATH if you need an explicit database
path while debugging.
Mock State Backends¶
| Backend | Configure with | Use case |
|---|---|---|
| SQLite/WAL | PROXMOX_MOCK_STORE=sqlite or unset |
Default; best balance for local dev, tests, and concurrent reads |
| Shared memory | PROXMOX_MOCK_STORE=shared-memory |
Legacy compatibility; uses a shared-memory JSON blob and file locks |
| Dict | PROXMOX_MOCK_STORE=dict |
Process-local tests where isolation matters more than cross-process state |
SQLite avoids serializing the entire mock state for every read/write. Payload
blobs use orjson when it is installed and fall back to the standard json
module otherwise.
Custom Mock Data¶
Load your own test data to simulate specific scenarios.
JSON Format¶
Create mock-data.json:
{
"/api2/json/nodes": [
{
"node": "pve1",
"status": "online",
"cpu": 0.25,
"maxcpu": 16,
"mem": 8589934592,
"maxmem": 68719476736
},
{
"node": "pve2",
"status": "online",
"cpu": 0.50,
"maxcpu": 32,
"mem": 17179869184,
"maxmem": 137438953472
}
],
"/api2/json/cluster/resources": [
{"type": "node", "node": "pve1", "status": "online"},
{"type": "node", "node": "pve2", "status": "online"},
{"type": "qemu", "vmid": 100, "name": "prod-web-01", "node": "pve1"},
{"type": "qemu", "vmid": 101, "name": "prod-db-01", "node": "pve2"}
]
}
YAML Format¶
Create mock-data.yaml:
/api2/json/nodes:
- node: pve1
status: online
cpu: 0.25
maxcpu: 16
- node: pve2
status: online
cpu: 0.50
maxcpu: 32
/api2/json/cluster/resources:
- type: node
node: pve1
status: online
- type: qemu
vmid: 100
name: prod-web-01
node: pve1
Load Custom Data¶
Place your file at the default path:
CRUD Operations in Detail¶
GET Requests¶
Collections (arrays):
# Returns array of items
response = httpx.get("http://localhost:8000/api2/json/nodes")
# [{"node": "pve", ...}]
Single Resources (objects):
# Returns single object
response = httpx.get("http://localhost:8000/api2/json/nodes/pve/status")
# {"uptime": 12345, "cpu": 0.5, ...}
POST Requests¶
Create new items in collections:
response = httpx.post(
"http://localhost:8000/api2/json/nodes/pve/qemu",
json={
"vmid": 100,
"name": "test-vm",
"memory": 2048,
"cores": 2,
}
)
# Item added to collection AND created as individual resource
# Now accessible at:
# - /api2/json/nodes/pve/qemu (in the collection)
# - /api2/json/nodes/pve/qemu/100 (individual resource)
PUT Requests¶
Replace entire resource:
response = httpx.put(
"http://localhost:8000/api2/json/nodes/pve/qemu/100",
json={
"vmid": 100,
"name": "test-vm-renamed",
"memory": 4096, # Changed
"cores": 4, # Changed
}
)
# Entire object replaced with new values
PATCH Requests¶
Partial update (merge):
response = httpx.patch(
"http://localhost:8000/api2/json/nodes/pve/qemu/100",
json={"memory": 8192}
)
# Only 'memory' field updated, other fields unchanged
DELETE Requests¶
Remove resources:
response = httpx.delete("http://localhost:8000/api2/json/nodes/pve/qemu/100")
# Resource removed from:
# - Individual endpoint (/api2/json/nodes/pve/qemu/100)
# - Parent collection (/api2/json/nodes/pve/qemu)
Query Parameters¶
Mock endpoints support query parameter filtering:
# Get all VMs
all_vms = httpx.get("http://localhost:8000/api2/json/cluster/resources?type=qemu")
# Filter by status
running = httpx.get("http://localhost:8000/api2/json/cluster/resources?type=qemu&status=running")
Environment Variables¶
Configure mock mode behavior:
| Variable | Default | Description |
|---|---|---|
PROXMOX_API_MODE |
mock |
Set to mock for mock mode |
PROXMOX_MOCK_SCHEMA_VERSION |
latest |
OpenAPI schema version to use |
PROXMOX_MOCK_DATA_PATH |
/etc/proxmox-sdk/mock-data.json |
Custom mock data file path |
PROXMOX_MOCK_STORE |
sqlite |
Mock state backend: sqlite, shared-memory, or dict |
PROXMOX_MOCK_STATE_PATH |
tempdir scoped by namespace | Optional SQLite mock-state DB path |
HOST |
0.0.0.0 |
Server host to bind |
PORT |
8000 |
Server port |
Use Cases¶
Integration Testing¶
import httpx
import pytest
@pytest.fixture
def proxmox_client():
return httpx.Client(base_url="http://localhost:8000/api2/json")
def test_create_vm(proxmox_client):
response = proxmox_client.post(
"/nodes/pve/qemu",
json={"vmid": 100, "name": "test", "memory": 2048}
)
assert response.status_code == 200
# Verify VM was created
vm = proxmox_client.get("/nodes/pve/qemu/100")
assert vm.json()["vmid"] == 100
CI/CD Pipelines¶
# .github/workflows/test.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start Mock Proxmox API
run: |
pip install proxmox-sdk
proxmox-sdk-mock &
sleep 2
- name: Run Integration Tests
run: pytest tests/integration/
Local Development¶
# Start mock API
proxmox-sdk-mock
# In another terminal, develop your application
python my_proxmox_app.py
Your application can make Proxmox API calls without needing a real cluster!
Limitations¶
Mock Limitations
- No real Proxmox logic - Doesn't validate Proxmox-specific business rules
- Memory-only storage - Data lost on restart
- Simplified state - Doesn't track complex resource relationships
- No async operations - Real Proxmox tasks are immediate in mock mode
For production use or testing against real Proxmox behavior, use Real API Mode.
Next Steps¶
- Real API Mode → - Connect to actual Proxmox servers
- API Reference → - Explore all available endpoints
- Development Guide → - Contribute to the project