Installation
bash
pip install nerox # With async support (default, no extra deps needed) # Or install a specific version: pip install "nerox==0.9.2"
Authentication
python
import nerox # From environment variable (recommended) # export NEROX_API_KEY=nrx_sk_... client = nerox.Client() # Or explicitly client = nerox.Client(api_key="nrx_sk_...")
Synchronous client
The sync client is the simplest way to get started. It blocks until the job completes or until you call .stream().
python
import nerox
import numpy as np
client = nerox.Client()
job = client.optimize.tsp(
distance_matrix=matrix,
solver="gpu",
n_runs=50,
)
# Blocking wait
result = job.wait(timeout=120) # raises TimeoutError if exceeded
print(result.objective, result.solution)
# Streaming (non-blocking iteration)
for event in job.stream():
print(event.iteration, event.energy)Async client
python
import asyncio
import nerox
async def main():
async with nerox.AsyncClient() as client:
job = await client.optimize.tsp(
distance_matrix=matrix,
solver="gpu",
)
# Async streaming
async for event in job.astream():
print(event.energy)
result = await job.result()
print(result.objective)
asyncio.run(main())Job object reference
python
job.id # str — unique job identifier job.status # "queued" | "running" | "completed" | "failed" job.wait() # blocks until done, returns Result job.stream() # iterator of StreamEvent job.cancel() # cancel a running job job.result # Result object (after completion) # Result attributes result.objective # float — minimized objective value result.solution # list — binary vector or tour order result.runtime_s # float — wall-clock seconds result.gpu_seconds # float — billed GPU time result.solver # str — solver name result.n_iterations # int — total iterations run result.gap_to_best # float | None — % above known optimal
Batch submission
python
import nerox
client = nerox.Client()
# Submit multiple jobs in parallel
jobs = client.optimize.batch([
dict(problem_type="tsp", distance_matrix=m1, solver="gpu"),
dict(problem_type="tsp", distance_matrix=m2, solver="tabu"),
dict(problem_type="qubo", Q=Q, solver="qaoa", depth=4),
])
results = [j.wait() for j in jobs]Error handling
python
from nerox.exceptions import (
AuthenticationError, # invalid API key
RateLimitError, # quota exceeded
JobFailedError, # solver returned error
TimeoutError, # job.wait(timeout=...) exceeded
ValidationError, # invalid problem input
)
try:
result = job.wait(timeout=60)
except nerox.JobFailedError as e:
print(e.reason) # "matrix_not_square" | "qubo_invalid" | ...
except nerox.RateLimitError:
print("GPU quota exhausted — check /v1/usage")