NVIDIANVIDIA-Certified Professional: Agentic AI2026-100 Prerequisites
Bound async calls and classify failures
Completed by the knowledge check
Learning objective
Call OpenAI-compatible LLM endpoints from Python with async I/O and structured error handling.
Core idea
An asynchronous call lets a Python task yield while it waits for network I/O. It does not make model inference faster or create GPU capacity. Your integration must still select the endpoint, bound its wait, and translate failures into outcomes the caller can handle.
OpenAI compatibility describes an API interface. NVIDIA NIM for LLM and VLM documents POST /v1/chat/completions and GET /v1/models; use the deployed model’s identifier rather than assuming a model name from another provider works. See 7.2.1 for NIM startup, health validation, and API calls.
How it works
The OpenAI Python SDK exposes AsyncOpenAI. Set base_url to the approved API root ending in /v1, supply the credential required by that deployment, and await client.chat.completions.create(...). An async with block closes the client when work finishes.
This non-streaming example accepts deployment-specific values and returns a small outcome object:
import asyncio
import openai
async def ask(base_url: str, api_key: str, model: str, prompt: str):
async with openai.AsyncOpenAI(
base_url=base_url, api_key=api_key,
timeout=8.0, max_retries=0,
) as client:
try:
async with asyncio.timeout(8.0):
reply = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
return {"kind": "response", "response": reply}
except TimeoutError:
return {"kind": "deadline_exceeded"}
except openai.APITimeoutError:
return {"kind": "timeout"}
except openai.APIConnectionError:
return {"kind": "connection_failure"}
except openai.APIStatusError as error:
return {"kind": "http_error", "status": error.status_code}Call ask(...) with await from an asynchronous entry point on Python 3.11 or later. The eight-second application allowance is an example setting, not a NIM limit. max_retries=0 makes this one SDK attempt; it does not disable retries elsewhere in your system.
The exception order matters: APITimeoutError is a connection-error subtype. APIStatusError means an HTTP error response arrived and exposes status_code; RateLimitError represents HTTP 429. A timeout means you stopped waiting, not that the server never processed the request. Keep the response object for application validation rather than equating receipt with task success.
Key distinctions and trade-offs
The SDK timeout controls network waits, including connection, read, and write waits; it is not a total wall-clock deadline. The example uses asyncio.timeout(8.0) around the call to enforce its application allowance by cancelling overdue work and raising TimeoutError outside the context manager. Preserve cancellation after cleanup rather than swallowing asyncio.CancelledError.
The application allowance wraps the one SDK attempt: the attempt ends as APITimeoutError, APIConnectionError or APIStatusError, or as a response kept for application validation, and overdue work ends as TimeoutError outside it.
For concurrent calls, Python 3.11+ provides asyncio.TaskGroup and its create_task(...) method. A shared asyncio.Semaphore acquired with async with around each call caps the requests in flight to one inference service. Set that cap from the service’s tested capacity rather than creating unbounded tasks.
The SDK retries eligible failures twice by default. Explicit retry settings prevent an unnoticed SDK policy from multiplying an outer retry loop. See 2.4.1 for failure classification, 2.4.2 for bounded retry design, and 2.4.4 for side effects and idempotency. A broad except Exception that turns everything into empty text discards the distinctions those mechanisms require.
Architecture / decision scenario
A logistics employee assistant has a ten-second response budget, with two seconds reserved for authorization and rendering. The integration owner uses the example eight-second asyncio.timeout(...) allowance around inference and disables SDK retries while the application owns the overall deadline.
A colleague proposes three sequential attempts to hide intermittent failures. If each attempt exhausts its eight-second application allowance, three attempts consume at least 24 seconds before other work, so that proposal violates the budget. The owner returns a typed unavailable outcome after a connection failure, surfaces HTTP 400 for input correction, and sends 429 to the bounded-retry policy only when remaining time permits. The owner caps concurrent calls with a shared asyncio.Semaphore; adding coroutines cannot resolve this deadline conflict.
Common exam traps
- Treating
asyncas GPU parallelism or unlimited admission capacity. - Assuming a timeout proves the server did no work.
- Retrying every HTTP error unchanged or hiding it as an empty answer.
- Forgetting retries already configured in the SDK.
What to remember
Use AsyncOpenAI, an explicit deployment URL, and await. Keep timeout, connection failure, HTTP failure, and response validation separate. Retry policy must fit the caller’s total deadline.
Knowledge check
An employee assistant gives inference an eight-second slice of its response budget. The integration constructs AsyncOpenAI(timeout=8.0, max_retries=0), yet traces show some calls still running well past eight seconds. Which change enforces the eight-second allowance on the whole call?
timeout to a fraction of eight secondsasyncio.timeout(8.0)asyncio.TaskGroupTimeoutError around the awaited calltimeout bounds individual network waits — connecting, reading, writing — not the call’s total wall-clock time, so a smaller value still sets no overall deadline. asyncio.timeout(8.0) cancels overdue work and raises TimeoutError outside the context manager. A TaskGroup schedules concurrent tasks without a deadline, and catching TimeoutError only handles a deadline that something else must raise.The integration classifies failures with these handlers, in this order:
except openai.APIConnectionError:
return {"kind": "connection_failure"}
except openai.APITimeoutError:
return {"kind": "timeout"}The dashboard has never recorded a timeout outcome, although client logs show the SDK’s own request timeouts. What explains it?
asyncio.TimeoutErrorAPIStatusErrorAPITimeoutErrormax_retries=0 hides request timeouts from the callerAPITimeoutError is a subtype of APIConnectionError , and Python runs the first matching except clause, so every SDK timeout is labeled a connection failure; the more specific clause must come first. asyncio.TimeoutError comes from an application deadline such as asyncio.timeout(...) , not from the SDK’s own timeout, and APIStatusError means an HTTP error response actually arrived.A worker wraps each inference call in its own loop of three attempts, using a client built as AsyncOpenAI(base_url=..., api_key=...) with no other options. While the inference service restarts and answers HTTP 503, its access log shows up to nine requests per user call. Which change makes the worker’s loop the only retry policy?
timeout so each attempt fails soonerasyncio.Semaphoreasyncio.timeout(...) allowancemax_retries=0 on the client explicitlymax_retries=0 removes the hidden inner policy. A semaphore limits how many calls run at once, not how often one call repeats, and a shorter timeout or deadline changes when attempts end without removing the SDK’s retries.A nightly job summarizes 2,000 tickets by creating one task per ticket in an asyncio.TaskGroup. The inference service was load-tested at 32 concurrent requests, and the job now drives it into HTTP 429 responses and long queues. Which change keeps the job asynchronous and within the tested capacity?
asyncio.Semaphore(32)asyncio.Semaphore(32)max_retries to absorb the 429 responsestimeout so queued requests can finishReferences
- OpenAI, OpenAI Python API library
- Python Software Foundation, Coroutines and Tasks
- Python Software Foundation, Synchronization Primitives
- NVIDIA, API Reference