From fd93b70217e00ce769dde9aa8e616281746f4607 Mon Sep 17 00:00:00 2001 From: namedfarouk Date: Sat, 4 Apr 2026 05:13:52 +0100 Subject: [PATCH] docs: add alpha inference error-handling examples --- README.md | 39 +++++++++++ examples/README.md | 31 +++++++++ examples/alpha/README.md | 12 ++++ .../run_inference_with_error_handling.py | 69 +++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 examples/alpha/run_inference_with_error_handling.py diff --git a/README.md b/README.md index f278d67f..df40ec45 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,45 @@ result = alpha.infer( print(f"Output: {result.model_output}") ``` +#### Error Handling for Inference + +Inference requests can fail due to invalid inputs, contract reverts, network/API issues, or wallet funding problems. +Wrap calls in `try/except` so failures are easier to debug: + +```python +import os + +import opengradient as og +from web3.exceptions import ContractLogicError + +alpha = og.Alpha(private_key=os.environ["OG_PRIVATE_KEY"]) + +try: + result = alpha.infer( + model_cid="your-model-cid", + model_input={"input": [1.0, 2.0, 3.0]}, + inference_mode=og.InferenceMode.VANILLA, + ) + print(f"Output: {result.model_output}") + print(f"Tx hash: {result.transaction_hash}") +except ValueError as e: + print(f"Invalid request: {e}") +except ContractLogicError as e: + print(f"Contract reverted: {e}") +except RuntimeError as e: + message = str(e).lower() + if "timeout" in message: + print(f"Inference timed out: {e}") + elif "insufficient" in message or "balance" in message: + print(f"Insufficient wallet funds: {e}") + elif "network" in message or "connection" in message: + print(f"Network/API failure: {e}") + elif "cid" in message or "model" in message: + print(f"Invalid model CID or model output format: {e}") + else: + print(f"Inference failed: {e}") +``` + ### Workflow Deployment Deploy on-chain AI workflows with optional scheduling: diff --git a/examples/README.md b/examples/README.md index cdd321ff..b9a9400d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -169,6 +169,37 @@ print(f"Output: {result.model_output}") print(f"Tx hash: {result.transaction_hash}") ``` +#### Running Inference with Error Handling + +Add `try/except` handling to make common failures actionable: + +```python +import os + +import opengradient as og +from web3.exceptions import ContractLogicError + +alpha = og.Alpha(private_key=os.environ["OG_PRIVATE_KEY"]) + +try: + result = alpha.infer( + model_cid="your-model-cid", + model_input={"input_key": "input_value"}, + inference_mode=og.InferenceMode.VANILLA, + ) + print(f"Output: {result.model_output}") + print(f"Tx hash: {result.transaction_hash}") +except ValueError as e: + print(f"Invalid input or retry configuration: {e}") +except ContractLogicError as e: + print(f"Contract reverted: {e}") +except RuntimeError as e: + print(f"Inference failed: {e}") +``` + +For a complete retry + error classification example, see: +`examples/alpha/run_inference_with_error_handling.py` + ### LLM Chat LLM chat methods are async: diff --git a/examples/alpha/README.md b/examples/alpha/README.md index ccbfc8af..a39c97a0 100644 --- a/examples/alpha/README.md +++ b/examples/alpha/README.md @@ -23,6 +23,18 @@ python examples/alpha/run_inference.py - Demonstrates passing structured input data (e.g., OHLC price data) - Returns model predictions along with the transaction hash +### `run_inference_with_error_handling.py` +Runs inference with explicit error handling and retry logic. + +```bash +python examples/alpha/run_inference_with_error_handling.py +``` + +**What it does:** +- Demonstrates `try/except` handling for invalid input, contract revert, and runtime failures +- Classifies runtime failures (network, timeout, insufficient funds, model/CID issues) +- Retries transient failures with exponential backoff + ### `run_embeddings_model.py` Runs inference on an embeddings model for semantic search. diff --git a/examples/alpha/run_inference_with_error_handling.py b/examples/alpha/run_inference_with_error_handling.py new file mode 100644 index 00000000..08f155e1 --- /dev/null +++ b/examples/alpha/run_inference_with_error_handling.py @@ -0,0 +1,69 @@ +import os +import time + +import opengradient as og +from web3.exceptions import ContractLogicError + +MODEL_CID = "hJD2Ja3akZFt1A2LT-D_1oxOCz_OtuGYw4V9eE1m39M" + + +def _classify_runtime_error(exc: RuntimeError) -> tuple[str, bool]: + """Map RuntimeError messages to actionable labels and retryability.""" + message = str(exc).lower() + if "timeout" in message: + return "Request timed out while waiting for inference result.", True + if "network" in message or "connection" in message: + return "Network/API connectivity issue while fetching inference result.", True + if "insufficient" in message or "balance" in message: + return "Insufficient wallet funds for gas or execution.", False + if "cid" in message or "model" in message: + return "Invalid model CID or model output mismatch.", False + return f"Inference failed: {exc}", False + + +def run_inference_with_retry(max_attempts: int = 3) -> None: + """Run alpha inference with structured error handling and retry logic.""" + alpha = og.Alpha(private_key=os.environ["OG_PRIVATE_KEY"]) + + for attempt in range(1, max_attempts + 1): + try: + result = alpha.infer( + model_cid=MODEL_CID, + model_input={ + "open_high_low_close": [ + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + ] + }, + inference_mode=og.InferenceMode.VANILLA, + ) + print(f"Output: {result.model_output}") + print(f"Tx hash: {result.transaction_hash}") + return + except ValueError as exc: + print(f"Invalid input or retry configuration: {exc}") + return + except ContractLogicError as exc: + print(f"Contract reverted during simulation/execution: {exc}") + return + except RuntimeError as exc: + reason, retryable = _classify_runtime_error(exc) + print(reason) + if not retryable or attempt == max_attempts: + return + + backoff_seconds = 2 ** (attempt - 1) + print(f"Retrying in {backoff_seconds}s (attempt {attempt}/{max_attempts})...") + time.sleep(backoff_seconds) + + +if __name__ == "__main__": + run_inference_with_retry()