feat: migrate coordinator-api bitcoin wallet and explorer services to use centralized aitbc package HTTP client
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 18s
Integration Tests / test-service-integration (push) Successful in 40s
Python Tests / test-python (push) Failing after 37s
Security Scanning / security-scan (push) Has been cancelled

- Replace httpx.Client with aitbc.AITBCHTTPClient in BitcoinWallet class
- Remove HTTP_CLIENT_AVAILABLE check and httpx import guard
- Replace logging.getLogger with aitbc.get_logger in bitcoin_wallet.py
- Migrate explorer.py from httpx to aitbc.AITBCHTTPClient
- Add NetworkError exception handling in explorer service
- Remove async context manager and status code checks in favor of AITBCHTTPClient
- Remove httpx imports from both services
- Consistent
This commit is contained in:
aitbc
2026-04-24 23:51:48 +02:00
parent 92ca4daaa7
commit f912fa131d
2 changed files with 10 additions and 25 deletions

View File

@@ -5,18 +5,11 @@ Uses RPC to connect to Bitcoin Core (or alternative like Block.io)
""" """
import json import json
import logging
import os import os
logger = logging.getLogger(__name__) from aitbc import get_logger, AITBCHTTPClient, NetworkError
try: logger = get_logger(__name__)
import httpx
HTTP_CLIENT_AVAILABLE = True
except ImportError:
HTTP_CLIENT_AVAILABLE = False
logging.warning("httpx not available, bitcoin wallet functions will be disabled")
# Bitcoin wallet configuration (credentials from environment) # Bitcoin wallet configuration (credentials from environment)
@@ -33,12 +26,7 @@ WALLET_CONFIG = {
class BitcoinWallet: class BitcoinWallet:
def __init__(self): def __init__(self):
self.config = WALLET_CONFIG self.config = WALLET_CONFIG
if not HTTP_CLIENT_AVAILABLE: self.client = AITBCHTTPClient(timeout=30.0)
logger.error("httpx not available - bitcoin wallet functions disabled")
self.session = None
else:
self.session = httpx.Client()
self.session.auth = (self.config["rpc_user"], self.config["rpc_password"])
def get_balance(self) -> float: def get_balance(self) -> float:
"""Get the current Bitcoin balance""" """Get the current Bitcoin balance"""

View File

@@ -3,9 +3,9 @@ from __future__ import annotations
from collections import defaultdict, deque from collections import defaultdict, deque
from datetime import datetime from datetime import datetime
import httpx
from sqlmodel import Session, select from sqlmodel import Session, select
from aitbc import AITBCHTTPClient, NetworkError
from ..config import settings from ..config import settings
from ..domain import Job, JobReceipt from ..domain import Job, JobReceipt
from ..schemas import ( from ..schemas import (
@@ -42,23 +42,18 @@ class ExplorerService:
# Fetch real blockchain data via /rpc/head and /rpc/blocks-range # Fetch real blockchain data via /rpc/head and /rpc/blocks-range
rpc_base = settings.blockchain_rpc_url.rstrip("/") rpc_base = settings.blockchain_rpc_url.rstrip("/")
try: try:
with httpx.Client(timeout=10.0) as client: client = AITBCHTTPClient(timeout=10.0)
head_resp = client.get(f"{rpc_base}/rpc/head") try:
if head_resp.status_code == 404: head = client.get(f"{rpc_base}/rpc/head")
return BlockListResponse(items=[], next_offset=None)
head_resp.raise_for_status()
head = head_resp.json()
height = head.get("height", 0) height = head.get("height", 0)
start = max(0, height - offset - limit + 1) start = max(0, height - offset - limit + 1)
end = height - offset end = height - offset
if start > end: if start > end:
return BlockListResponse(items=[], next_offset=None) return BlockListResponse(items=[], next_offset=None)
range_resp = client.get( rpc_data = client.get(
f"{rpc_base}/rpc/blocks-range", f"{rpc_base}/rpc/blocks-range",
params={"start": start, "end": end}, params={"start": start, "end": end},
) )
range_resp.raise_for_status()
rpc_data = range_resp.json()
raw_blocks = rpc_data.get("blocks", []) raw_blocks = rpc_data.get("blocks", [])
# Node returns ascending by height; explorer expects newest first # Node returns ascending by height; explorer expects newest first
raw_blocks = list(reversed(raw_blocks)) raw_blocks = list(reversed(raw_blocks))
@@ -78,6 +73,8 @@ class ExplorerService:
) )
next_offset = offset + len(items) if len(items) == limit else None next_offset = offset + len(items) if len(items) == limit else None
return BlockListResponse(items=items, next_offset=next_offset) return BlockListResponse(items=items, next_offset=next_offset)
except NetworkError as e:
return BlockListResponse(items=[], next_offset=None)
except Exception as e: except Exception as e:
# Fallback to fake data if RPC is unavailable # Fallback to fake data if RPC is unavailable
print(f"Warning: Failed to fetch blocks from RPC: {e}, falling back to fake data") print(f"Warning: Failed to fetch blocks from RPC: {e}, falling back to fake data")