Migrate pool-hub app to centralized aitbc package utilities
- Migrate services/sla_collector.py from logging to aitbc.get_logger - Migrate app/routers/sla.py from logging to aitbc.get_logger - Consolidate aitbc imports in services/billing_integration.py
This commit is contained in:
@@ -3,11 +3,11 @@ SLA and Billing API Endpoints for Pool-Hub
|
|||||||
Provides endpoints for SLA metrics, capacity planning, and billing integration.
|
Provides endpoints for SLA metrics, capacity planning, and billing integration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
from aitbc import get_logger
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@@ -17,7 +17,7 @@ from ..services.sla_collector import SLACollector
|
|||||||
from ..services.billing_integration import BillingIntegration
|
from ..services.billing_integration import BillingIntegration
|
||||||
from ..models import SLAMetric, SLAViolation, CapacitySnapshot
|
from ..models import SLAMetric, SLAViolation, CapacitySnapshot
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
router = APIRouter(prefix="/sla", tags=["SLA"])
|
router = APIRouter(prefix="/sla", tags=["SLA"])
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ Integrates pool-hub usage data with coordinator-api's billing system.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
import httpx
|
|
||||||
|
from aitbc import get_logger, AsyncAITBCHTTPClient, NetworkError
|
||||||
|
|
||||||
from sqlalchemy import and_, func, select
|
from sqlalchemy import and_, func, select
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
@@ -16,7 +16,7 @@ from sqlalchemy.orm import Session
|
|||||||
from ..models import Miner, ServiceConfig, MatchRequest, MatchResult, Feedback
|
from ..models import Miner, ServiceConfig, MatchRequest, MatchResult, Feedback
|
||||||
from ..settings import settings
|
from ..settings import settings
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BillingIntegration:
|
class BillingIntegration:
|
||||||
@@ -30,7 +30,7 @@ class BillingIntegration:
|
|||||||
self.coordinator_api_key = getattr(
|
self.coordinator_api_key = getattr(
|
||||||
settings, "coordinator_api_key", None
|
settings, "coordinator_api_key", None
|
||||||
)
|
)
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
|
|
||||||
# Resource type mappings
|
# Resource type mappings
|
||||||
self.resource_type_mapping = {
|
self.resource_type_mapping = {
|
||||||
@@ -231,40 +231,40 @@ class BillingIntegration:
|
|||||||
if self.coordinator_api_key:
|
if self.coordinator_api_key:
|
||||||
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
client = AsyncAITBCHTTPClient(base_url=self.coordinator_billing_url, headers=headers, timeout=30)
|
||||||
response = await client.post(url, json=billing_event, headers=headers)
|
response = await client.async_post("/api/billing/usage", json=billing_event)
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
return response.json()
|
if response:
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
raise NetworkError("Failed to send billing event")
|
||||||
|
|
||||||
async def get_billing_metrics(
|
async def get_billing_metrics(
|
||||||
self, tenant_id: Optional[str] = None, hours: int = 24
|
self, tenant_id: Optional[str] = None, hours: int = 24
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""Get billing metrics from coordinator-api"""
|
"""Get billing metrics from coordinator-api"""
|
||||||
|
|
||||||
url = f"{self.coordinator_billing_url}/api/billing/metrics"
|
|
||||||
|
|
||||||
params = {"hours": hours}
|
|
||||||
if tenant_id:
|
|
||||||
params["tenant_id"] = tenant_id
|
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
if self.coordinator_api_key:
|
if self.coordinator_api_key:
|
||||||
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
client = AsyncAITBCHTTPClient(base_url=self.coordinator_billing_url, headers=headers, timeout=30)
|
||||||
response = await client.get(url, params=params, headers=headers)
|
params = {"hours": hours}
|
||||||
response.raise_for_status()
|
if tenant_id:
|
||||||
|
params["tenant_id"] = tenant_id
|
||||||
|
|
||||||
return response.json()
|
response = await client.async_get("/api/billing/metrics", params=params)
|
||||||
|
|
||||||
|
if response:
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
raise NetworkError("Failed to get billing metrics")
|
||||||
|
|
||||||
async def trigger_invoice_generation(
|
async def trigger_invoice_generation(
|
||||||
self, tenant_id: str, period_start: datetime, period_end: datetime
|
self, tenant_id: str, period_start: datetime, period_end: datetime
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""Trigger invoice generation in coordinator-api"""
|
"""Trigger invoice generation in coordinator-api"""
|
||||||
|
|
||||||
url = f"{self.coordinator_billing_url}/api/billing/invoice"
|
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"tenant_id": tenant_id,
|
"tenant_id": tenant_id,
|
||||||
"period_start": period_start.isoformat(),
|
"period_start": period_start.isoformat(),
|
||||||
@@ -275,11 +275,13 @@ class BillingIntegration:
|
|||||||
if self.coordinator_api_key:
|
if self.coordinator_api_key:
|
||||||
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
headers["Authorization"] = f"Bearer {self.coordinator_api_key}"
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
client = AsyncAITBCHTTPClient(base_url=self.coordinator_billing_url, headers=headers, timeout=30)
|
||||||
response = await client.post(url, json=payload, headers=headers)
|
response = await client.async_post("/api/billing/invoice", json=payload)
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
return response.json()
|
if response:
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
raise NetworkError("Failed to trigger invoice generation")
|
||||||
|
|
||||||
|
|
||||||
class BillingIntegrationScheduler:
|
class BillingIntegrationScheduler:
|
||||||
@@ -287,7 +289,7 @@ class BillingIntegrationScheduler:
|
|||||||
|
|
||||||
def __init__(self, billing_integration: BillingIntegration):
|
def __init__(self, billing_integration: BillingIntegration):
|
||||||
self.billing_integration = billing_integration
|
self.billing_integration = billing_integration
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
async def start(self, sync_interval_hours: int = 1):
|
async def start(self, sync_interval_hours: int = 1):
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ Collects and tracks SLA metrics for miners including uptime, response time, job
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
|
|
||||||
|
from aitbc import get_logger
|
||||||
from sqlalchemy import and_, desc, func, select
|
from sqlalchemy import and_, desc, func, select
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ from ..models import (
|
|||||||
CapacitySnapshot,
|
CapacitySnapshot,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SLACollector:
|
class SLACollector:
|
||||||
@@ -369,7 +369,7 @@ class SLACollectorScheduler:
|
|||||||
|
|
||||||
def __init__(self, sla_collector: SLACollector):
|
def __init__(self, sla_collector: SLACollector):
|
||||||
self.sla_collector = sla_collector
|
self.sla_collector = sla_collector
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = get_logger(__name__)
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
async def start(self, collection_interval_seconds: int = 300):
|
async def start(self, collection_interval_seconds: int = 300):
|
||||||
|
|||||||
Reference in New Issue
Block a user