fix: replace datetime.UTC with timezone.utc for Python 3.12+ compatibility
Some checks failed
API Endpoint Tests / test-api-endpoints (push) Successful in 22s
Blockchain Synchronization Verification / sync-verification (push) Successful in 3s
CLI Tests / test-cli (push) Failing after 13s
Cross-Chain Functionality Tests / test-cross-chain-sync (push) Failing after 3s
Cross-Chain Functionality Tests / test-cross-chain-transactions (push) Successful in 3s
Cross-Chain Functionality Tests / test-cross-chain-bridge (push) Has been skipped
Cross-Chain Functionality Tests / test-multi-chain-consensus (push) Failing after 3s
Cross-Chain Functionality Tests / aggregate-results (push) Has been skipped
Cross-Node Transaction Testing / transaction-test (push) Successful in 2s
Deploy to Testnet / deploy-testnet (push) Successful in 1m34s
Documentation Validation / validate-docs (push) Failing after 10s
Documentation Validation / validate-policies-strict (push) Successful in 3s
Multi-Node Stress Testing / stress-test (push) Has been cancelled
Node Failover Simulation / failover-test (push) Has been cancelled
Python Tests / test-python (push) Has been cancelled
Integration Tests / test-service-integration (push) Successful in 2m42s
Multi-Chain Island Architecture Tests / test-multi-chain-island (push) Successful in 3s
Multi-Node Blockchain Health Monitoring / health-check (push) Successful in 5s
P2P Network Verification / p2p-verification (push) Successful in 3s
Package Tests / Python package - aitbc-agent-sdk (push) Failing after 33s
Package Tests / Python package - aitbc-core (push) Successful in 17s
Package Tests / Python package - aitbc-crypto (push) Successful in 11s
Security Scanning / security-scan (push) Has been cancelled
Package Tests / Python package - aitbc-sdk (push) Successful in 13s
Package Tests / JavaScript package - aitbc-sdk-js (push) Successful in 9s
Package Tests / JavaScript package - aitbc-token (push) Successful in 17s
Staking Tests / test-staking-service (push) Failing after 6s
Staking Tests / test-staking-integration (push) Has been skipped
Staking Tests / test-staking-contract (push) Has been skipped
Staking Tests / run-staking-test-runner (push) Has been skipped

This commit is contained in:
aitbc
2026-05-09 12:03:26 +02:00
parent 14449b0758
commit d26e6d3772
152 changed files with 848 additions and 848 deletions

View File

@@ -8,7 +8,7 @@ import asyncio
import aiohttp
import json
from typing import Dict, Any, List, Optional
from datetime import datetime, UTC
from datetime import datetime, timezone
class AITBCServiceIntegration:
"""Integration layer for AITBC services"""
@@ -110,7 +110,7 @@ class AgentServiceBridge:
self.active_agents[agent_id] = {
"config": agent_config,
"registration": registration_result,
"started_at": datetime.now(datetime.UTC)
"started_at": datetime.now(timezone.utc)
}
return True
else:
@@ -182,7 +182,7 @@ class AgentServiceBridge:
"volatility": "medium",
"recommendation": "hold"
},
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
return {"status": "success", "result": analysis_result}
@@ -221,7 +221,7 @@ class AgentServiceBridge:
"check_type": task_data.get("check_type", "basic"),
"status": "passed",
"checks_performed": ["kyc", "aml", "sanctions"],
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
return {"status": "success", "result": compliance_result}

View File

@@ -9,7 +9,7 @@ import json
import logging
import time
from typing import Dict, Any, List
from datetime import datetime, UTC
from datetime import datetime, timezone
import sys
import os
@@ -112,7 +112,7 @@ class ComplianceAgent:
"alert_type": "compliance_failure",
"severity": "high",
"details": result,
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
# In a real implementation, this would send to alert system

View File

@@ -10,7 +10,7 @@ from typing import List, Optional, Dict, Any
import json
import uuid
import os
from datetime import datetime, UTC
from datetime import datetime, timezone
import sqlite3
from contextlib import contextmanager
from contextlib import asynccontextmanager
@@ -247,7 +247,7 @@ async def get_task_status():
},
"queue_sizes": queue_sizes
},
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
# Agent Management Endpoints
@@ -272,7 +272,7 @@ async def register_agent(request: AgentRegistrationRequest):
json.dumps(request.services),
json.dumps(request.endpoints),
json.dumps(request.metadata),
datetime.now(datetime.UTC),
datetime.now(timezone.utc),
1.0
))
conn.commit()
@@ -284,7 +284,7 @@ async def register_agent(request: AgentRegistrationRequest):
"status": "success",
"message": f"Agent {request.agent_id} registered successfully",
"agent_id": request.agent_id,
"registered_at": datetime.now(datetime.UTC).isoformat()
"registered_at": datetime.now(timezone.utc).isoformat()
}
except Exception as e:
print(f"ERROR: Failed to register agent: {str(e)}")
@@ -345,7 +345,7 @@ async def discover_agents(query: Dict[str, Any]):
for agent in agents
],
"count": len(agents),
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error discovering agents: {str(e)}")
@@ -374,7 +374,7 @@ async def get_agent(agent_id: str):
"registration_time": agent["registration_time"],
"health_score": agent["health_score"]
},
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
except HTTPException:
raise
@@ -390,7 +390,7 @@ async def update_agent_status(agent_id: str, request: AgentStatusUpdate):
conn.execute('''
UPDATE agents SET status = ?, last_heartbeat = ?
WHERE id = ?
''', (request.status, datetime.now(datetime.UTC), agent_id))
''', (request.status, datetime.now(timezone.utc), agent_id))
# Update load metrics if provided
if request.load_metrics:
@@ -404,7 +404,7 @@ async def update_agent_status(agent_id: str, request: AgentStatusUpdate):
"message": f"Agent {agent_id} status updated",
"agent_id": agent_id,
"new_status": request.status,
"updated_at": datetime.now(datetime.UTC).isoformat()
"updated_at": datetime.now(timezone.utc).isoformat()
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error updating agent status: {str(e)}")
@@ -417,12 +417,12 @@ async def agent_heartbeat(agent_id: str):
conn.execute('''
UPDATE agents SET last_heartbeat = ?
WHERE id = ?
''', (datetime.now(datetime.UTC), agent_id))
''', (datetime.now(timezone.utc), agent_id))
return {
"status": "success",
"message": f"Heartbeat received for agent {agent_id}",
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Error updating heartbeat: {str(e)}")

View File

@@ -5,7 +5,7 @@ Handles message creation, routing, and delivery between agents
import json
import uuid
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, Any, Optional, List
from enum import Enum
@@ -43,7 +43,7 @@ class MessageProtocol:
"receiver_id": receiver_id,
"message_type": message_type.value,
"content": content,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"status": "pending"
}
@@ -54,7 +54,7 @@ class MessageProtocol:
"""Send a message to the receiver"""
try:
message["status"] = "sent"
message["sent_timestamp"] = datetime.now(datetime.UTC).isoformat()
message["sent_timestamp"] = datetime.now(timezone.utc).isoformat()
return True
except Exception:
message["status"] = "failed"
@@ -65,7 +65,7 @@ class MessageProtocol:
for message in self.messages:
if message["message_id"] == message_id:
message["status"] = "received"
message["received_timestamp"] = datetime.now(datetime.UTC).isoformat()
message["received_timestamp"] = datetime.now(timezone.utc).isoformat()
return message
return None

View File

@@ -4,7 +4,7 @@ Handles task creation, assignment, and tracking
"""
import uuid
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, Optional, List
from enum import Enum
@@ -42,8 +42,8 @@ class Task:
self.priority = priority
self.created_by = created_by or assigned_to
self.status = TaskStatus.PENDING
self.created_at = datetime.now(datetime.UTC)
self.updated_at = datetime.now(datetime.UTC)
self.created_at = datetime.now(timezone.utc)
self.updated_at = datetime.now(timezone.utc)
self.completed_at = None
self.result = None
self.error = None
@@ -94,10 +94,10 @@ class TaskManager:
return False
task.status = status
task.updated_at = datetime.now(datetime.UTC)
task.updated_at = datetime.now(timezone.utc)
if status == TaskStatus.COMPLETED:
task.completed_at = datetime.now(datetime.UTC)
task.completed_at = datetime.now(timezone.utc)
task.result = result
elif status == TaskStatus.FAILED:
task.error = error
@@ -120,7 +120,7 @@ class TaskManager:
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
"""Get tasks that are overdue"""
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
return [
task for task in self.tasks.values()
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and

View File

@@ -11,7 +11,7 @@ import json
import time
import uuid
import os
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
import sqlite3
from contextlib import contextmanager
from contextlib import asynccontextmanager
@@ -149,7 +149,7 @@ async def list_agents(
@app.get("/api/health")
async def health_check():
"""Health check endpoint"""
return {"status": "ok", "timestamp": datetime.now(datetime.UTC)}
return {"status": "ok", "timestamp": datetime.now(timezone.utc)}
if __name__ == "__main__":
import uvicorn

View File

@@ -7,7 +7,7 @@ Basic AI-powered trading and analytics
import asyncio
import json
import numpy as np
from datetime import datetime, UTC
from datetime import datetime, timezone
from fastapi import FastAPI
from pydantic import BaseModel
from typing import Dict, Any, List
@@ -58,7 +58,7 @@ class SimpleAITradingEngine:
'overall_sentiment': np.random.choice(['bullish', 'bearish', 'neutral'])
}
},
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
async def make_trading_decision(self, symbol: str) -> Dict[str, Any]:
@@ -90,7 +90,7 @@ class SimpleAITradingEngine:
'quantity': quantity,
'price': analysis['current_price'],
'reasoning': f"Signal strength: {signal_strength:.3f}",
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
# Global AI engine
@@ -104,7 +104,7 @@ async def analyze_market(request: AnalysisRequest):
return {
"status": "success",
"analysis": analysis,
"timestamp": datetime.now(datetime.UTC)
"timestamp": datetime.now(timezone.utc)
}
except Exception as e:
return {"status": "error", "message": "Analysis failed"}
@@ -118,7 +118,7 @@ async def execute_ai_trade(request: TradingRequest):
return {
"status": "success",
"decision": decision,
"timestamp": datetime.now(datetime.UTC)
"timestamp": datetime.now(timezone.utc)
}
except Exception as e:
return {"status": "error", "message": "Analysis failed"}
@@ -136,7 +136,7 @@ async def predict_market(symbol: str):
"risk": analysis['ai_predictions']['risk_assessment'],
"sentiment": analysis['ai_predictions']['sentiment_analysis']
},
"timestamp": datetime.now(datetime.UTC)
"timestamp": datetime.now(timezone.utc)
}
except Exception as e:
return {"status": "error", "message": "Analysis failed"}
@@ -152,7 +152,7 @@ async def get_ai_dashboard():
'total_volume': np.random.uniform(100000, 1000000),
'active_symbols': len(symbols),
'ai_models_active': 3,
'last_update': datetime.now(datetime.UTC)
'last_update': datetime.now(timezone.utc)
},
'symbol_analysis': {}
}
@@ -169,7 +169,7 @@ async def get_ai_dashboard():
return {
"status": "success",
"dashboard": dashboard_data,
"timestamp": datetime.now(datetime.UTC)
"timestamp": datetime.now(timezone.utc)
}
except Exception as e:
return {"status": "error", "message": "Analysis failed"}
@@ -192,13 +192,13 @@ async def get_ai_status():
"risk_assessment",
"sentiment_analysis"
],
"timestamp": datetime.now(datetime.UTC)
"timestamp": datetime.now(timezone.utc)
}
@app.get("/api/health")
async def health_check():
"""Health check endpoint"""
return {"status": "ok", "timestamp": datetime.now(datetime.UTC)}
return {"status": "ok", "timestamp": datetime.now(timezone.utc)}
if __name__ == "__main__":
import uvicorn

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
from datetime import datetime, UTC
from datetime import datetime, timezone
# Mock numpy before importing
@@ -68,7 +68,7 @@ async def test_make_trading_decision_extreme_confidence():
'risk_assessment': {'risk_score': 0.0, 'volatility': 0.01},
'sentiment_analysis': {'sentiment_score': 1.0, 'overall_sentiment': 'bullish'}
},
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
result = await engine.make_trading_decision('AITBC/BTC')
@@ -155,7 +155,7 @@ async def test_signal_strength_boundary_buy():
'risk_assessment': {'risk_score': 0.0, 'volatility': 0.01},
'sentiment_analysis': {'sentiment_score': 0.5, 'overall_sentiment': 'bullish'}
},
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
result = await engine.make_trading_decision('AITBC/BTC')

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from unittest.mock import Mock, patch, MagicMock
from fastapi.testclient import TestClient
@@ -98,7 +98,7 @@ def test_get_ai_dashboard_endpoint():
'risk_assessment': {'risk_score': 0.5, 'volatility': 0.03},
'sentiment_analysis': {'sentiment_score': 0.5, 'overall_sentiment': 'bullish'}
},
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
mock_decision.return_value = {
@@ -108,7 +108,7 @@ def test_get_ai_dashboard_endpoint():
'quantity': 500,
'price': 0.005,
'reasoning': 'Test reasoning',
'timestamp': datetime.now(datetime.UTC)
'timestamp': datetime.now(timezone.utc)
}
response = client.get("/api/ai/dashboard")

View File

@@ -8,7 +8,7 @@ sys.path.insert(0, 'src')
from aitbc_chain.database import session_scope, init_db
from aitbc_chain.models import Block
from datetime import datetime, UTC
from datetime import datetime, timezone
import hashlib
def compute_block_hash(height: int, parent_hash: str, timestamp: datetime) -> str:
@@ -31,7 +31,7 @@ def create_genesis():
return
# Create genesis block
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
genesis_hash = compute_block_hash(0, "0x00", timestamp)
genesis = Block(
height=0,

View File

@@ -1,11 +1,11 @@
from aitbc_chain.database import session_scope, init_db
from aitbc_chain.models import Account
from datetime import datetime, UTC
from datetime import datetime, timezone
def fix():
init_db()
with session_scope() as session:
acc = Account(chain_id="ait-mainnet", address="aitbc1genesis", balance=10000000, nonce=0, updated_at=datetime.now(datetime.UTC), account_type="regular", metadata="{}")
acc = Account(chain_id="ait-mainnet", address="aitbc1genesis", balance=10000000, nonce=0, updated_at=datetime.now(timezone.utc), account_type="regular", metadata="{}")
session.merge(acc)
session.commit()
print("Added aitbc1genesis to mainnet")

View File

@@ -18,7 +18,7 @@ import base64
import os
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, List, Any, Optional
from cryptography.hazmat.primitives.asymmetric import ed25519
@@ -233,7 +233,7 @@ def initialize_genesis_database(genesis_block: Dict, allocations: List[Dict], db
alloc["address"],
alloc["balance"],
alloc["nonce"],
datetime.now(datetime.UTC).isoformat()
datetime.now(timezone.utc).isoformat()
)
)

View File

@@ -8,7 +8,7 @@ of agent compromise.
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
import json
from eth_account import Account
from eth_utils import to_checksum_address
@@ -37,7 +37,7 @@ class AgentSecurityProfile:
def __post_init__(self):
if self.created_at is None:
self.created_at = datetime.now(datetime.UTC)
self.created_at = datetime.now(timezone.utc)
class AgentWalletSecurity:
@@ -423,7 +423,7 @@ class AgentWalletSecurity:
def _log_security_event(self, **kwargs):
"""Log a security event"""
event = {
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
**kwargs
}
self.security_events.append(event)
@@ -469,7 +469,7 @@ class AgentWalletSecurity:
return {
"status": "disabled",
"agent_address": agent_address,
"disabled_at": datetime.now(datetime.UTC).isoformat(),
"disabled_at": datetime.now(timezone.utc).isoformat(),
"guardian": guardian_address
}
@@ -527,7 +527,7 @@ def generate_security_report() -> Dict:
recent_events = agent_wallet_security.get_security_events(limit=20)
return {
"generated_at": datetime.now(datetime.UTC).isoformat(),
"generated_at": datetime.now(timezone.utc).isoformat(),
"summary": {
"total_protected_agents": total_agents,
"active_agents": active_agents,
@@ -580,5 +580,5 @@ def detect_suspicious_activity(agent_address: str, hours: int = 24) -> Dict:
"suspicious_activity": len(suspicious_patterns) > 0,
"suspicious_patterns": suspicious_patterns,
"analysis_period_hours": hours,
"analyzed_at": datetime.now(datetime.UTC).isoformat()
"analyzed_at": datetime.now(timezone.utc).isoformat()
}

View File

@@ -12,7 +12,7 @@ wallets from unlimited spending in case of compromise. It provides:
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
import json
import os
import sqlite3
@@ -248,7 +248,7 @@ class GuardianContract:
def _get_spent_in_period(self, period: str, timestamp: datetime = None) -> int:
"""Calculate total spent in given period"""
if timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
period_key = self._get_period_key(timestamp, period)
@@ -265,7 +265,7 @@ class GuardianContract:
def _check_spending_limits(self, amount: int, timestamp: datetime = None) -> Tuple[bool, str]:
"""Check if amount exceeds spending limits"""
if timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
# Check per-transaction limit
if amount > self.config.limits.per_transaction:
@@ -350,7 +350,7 @@ class GuardianContract:
"to": to_address,
"amount": amount,
"data": data,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"nonce": self.nonce,
"status": "pending"
}
@@ -360,7 +360,7 @@ class GuardianContract:
# Check if time lock is required
if self._requires_time_lock(amount):
unlock_time = datetime.now(datetime.UTC) + timedelta(hours=self.config.time_lock.delay_hours)
unlock_time = datetime.now(timezone.utc) + timedelta(hours=self.config.time_lock.delay_hours)
operation["unlock_time"] = unlock_time.isoformat()
operation["status"] = "time_locked"
@@ -406,7 +406,7 @@ class GuardianContract:
# Check if operation is time locked
if operation["status"] == "time_locked":
unlock_time = datetime.fromisoformat(operation["unlock_time"])
if datetime.now(datetime.UTC) < unlock_time:
if datetime.now(timezone.utc) < unlock_time:
return {
"status": "error",
"reason": f"Operation locked until {unlock_time.isoformat()}"
@@ -432,7 +432,7 @@ class GuardianContract:
"amount": operation["amount"],
"data": operation.get("data", ""),
"timestamp": operation["timestamp"],
"executed_at": datetime.now(datetime.UTC).isoformat(),
"executed_at": datetime.now(timezone.utc).isoformat(),
"status": "completed",
"nonce": operation["nonce"]
}
@@ -479,7 +479,7 @@ class GuardianContract:
return {
"status": "paused",
"paused_at": datetime.now(datetime.UTC).isoformat(),
"paused_at": datetime.now(timezone.utc).isoformat(),
"guardian": guardian_address,
"message": "Emergency pause activated - all operations halted"
}
@@ -513,7 +513,7 @@ class GuardianContract:
return {
"status": "unpaused",
"unpaused_at": datetime.now(datetime.UTC).isoformat(),
"unpaused_at": datetime.now(timezone.utc).isoformat(),
"message": "Emergency pause lifted - operations resumed"
}
@@ -541,13 +541,13 @@ class GuardianContract:
"status": "updated",
"old_limits": old_limits,
"new_limits": new_limits,
"updated_at": datetime.now(datetime.UTC).isoformat(),
"updated_at": datetime.now(timezone.utc).isoformat(),
"guardian": guardian_address
}
def get_spending_status(self) -> Dict:
"""Get current spending status and limits"""
now = datetime.now(datetime.UTC)
now = datetime.now(timezone.utc)
return {
"agent_address": self.agent_address,

View File

@@ -5,7 +5,7 @@ Fixes the critical vulnerability where spending limits were lost on restart
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from sqlalchemy import create_engine, Column, String, Integer, Float, DateTime, Index
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
@@ -25,7 +25,7 @@ class SpendingRecord(Base):
period_key = Column(String, index=True)
amount = Column(Float)
transaction_hash = Column(String)
timestamp = Column(DateTime, default=datetime.now(datetime.UTC))
timestamp = Column(DateTime, default=datetime.now(timezone.utc))
# Composite indexes for performance
__table_args__ = (
@@ -45,7 +45,7 @@ class SpendingLimit(Base):
per_week = Column(Float)
time_lock_threshold = Column(Float)
time_lock_delay_hours = Column(Integer)
updated_at = Column(DateTime, default=datetime.now(datetime.UTC))
updated_at = Column(DateTime, default=datetime.now(timezone.utc))
updated_by = Column(String) # Guardian who updated
@@ -57,7 +57,7 @@ class GuardianAuthorization(Base):
agent_address = Column(String, index=True)
guardian_address = Column(String, index=True)
is_active = Column(Boolean, default=True)
added_at = Column(DateTime, default=datetime.now(datetime.UTC))
added_at = Column(DateTime, default=datetime.now(timezone.utc))
added_by = Column(String)
@@ -112,7 +112,7 @@ class PersistentSpendingTracker:
Total amount spent in period
"""
if timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
period_key = self._get_period_key(timestamp, period)
agent_address = to_checksum_address(agent_address)
@@ -140,7 +140,7 @@ class PersistentSpendingTracker:
True if recorded successfully
"""
if timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
agent_address = to_checksum_address(agent_address)
@@ -184,7 +184,7 @@ class PersistentSpendingTracker:
Spending check result
"""
if timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
agent_address = to_checksum_address(agent_address)
@@ -312,7 +312,7 @@ class PersistentSpendingTracker:
limits.per_week = new_limits.get("per_week", limits.per_week)
limits.time_lock_threshold = new_limits.get("time_lock_threshold", limits.time_lock_threshold)
limits.time_lock_delay_hours = new_limits.get("time_lock_delay_hours", limits.time_lock_delay_hours)
limits.updated_at = datetime.now(datetime.UTC)
limits.updated_at = datetime.now(timezone.utc)
limits.updated_by = guardian_address
else:
limits = SpendingLimit(
@@ -323,7 +323,7 @@ class PersistentSpendingTracker:
per_week=new_limits.get("per_week", 100000.0),
time_lock_threshold=new_limits.get("time_lock_threshold", 5000.0),
time_lock_delay_hours=new_limits.get("time_lock_delay_hours", 24),
updated_at=datetime.now(datetime.UTC),
updated_at=datetime.now(timezone.utc),
updated_by=guardian_address
)
session.add(limits)
@@ -361,7 +361,7 @@ class PersistentSpendingTracker:
if existing:
existing.is_active = True
existing.added_at = datetime.now(datetime.UTC)
existing.added_at = datetime.now(timezone.utc)
existing.added_by = added_by
else:
auth = GuardianAuthorization(
@@ -369,7 +369,7 @@ class PersistentSpendingTracker:
agent_address=agent_address,
guardian_address=guardian_address,
is_active=True,
added_at=datetime.now(datetime.UTC),
added_at=datetime.now(timezone.utc),
added_by=added_by
)
session.add(auth)
@@ -415,7 +415,7 @@ class PersistentSpendingTracker:
Spending summary
"""
agent_address = to_checksum_address(agent_address)
now = datetime.now(datetime.UTC)
now = datetime.now(timezone.utc)
# Get current spending
current_spent = {

View File

@@ -1,7 +1,7 @@
"""Cross-chain synchronization for testing multi-chain scenarios."""
import asyncio
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any, Dict, List

View File

@@ -4,7 +4,7 @@ import asyncio
import json
import time
from typing import Any, Dict, Optional, List
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from fastapi import APIRouter, HTTPException, status
from pydantic import BaseModel, Field, model_validator
@@ -478,12 +478,12 @@ async def submit_marketplace_transaction(tx_data: Dict[str, Any]) -> Dict[str, A
sender=sender_addr,
recipient=recipient_addr,
payload=tx_data.get("payload", {}),
created_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
nonce=tx_nonce,
value=amount,
fee=fee,
status="pending",
timestamp=datetime.now(datetime.UTC).isoformat()
timestamp=datetime.now(timezone.utc).isoformat()
)
session.add(transaction)
@@ -798,9 +798,9 @@ async def import_block(block_data: dict) -> Dict[str, Any]:
try:
timestamp = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
except ValueError:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
elif timestamp is None:
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
with session_scope(chain_id) as session:
# Check for hash conflicts across chains
@@ -1046,7 +1046,7 @@ async def import_chain(import_data: dict) -> Dict[str, Any]:
_logger.info(f"Importing {len(unique_blocks)} unique blocks (filtered from {len(blocks)} total)")
for block_data in unique_blocks:
block_timestamp = _parse_datetime_value(block_data.get("timestamp"), "block timestamp") or datetime.now(datetime.UTC)
block_timestamp = _parse_datetime_value(block_data.get("timestamp"), "block timestamp") or datetime.now(timezone.utc)
block = Block(
chain_id=chain_id,
height=block_data["height"],

View File

@@ -11,7 +11,7 @@ from typing import Dict, List, Optional, Tuple
from sqlmodel import Session, select
from sqlalchemy import select, text
from datetime import datetime, UTC
from datetime import datetime, timezone
from ..models import Account, Transaction, Receipt
from ..logger import get_logger
@@ -242,7 +242,7 @@ class StateTransition:
# Update receipt status
receipt.status = "claimed"
receipt.claimed_at = datetime.now(datetime.UTC)
receipt.claimed_at = datetime.now(timezone.utc)
receipt.claimed_by = sender_addr
logger.info(

View File

@@ -8,7 +8,7 @@ import hmac
import json
import time
from dataclasses import dataclass
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any, Dict, List, Optional, Tuple
import httpx
@@ -508,9 +508,9 @@ class ChainSync:
block_hash = block_data["hash"]
timestamp_str = block_data.get("timestamp", "")
try:
timestamp = datetime.fromisoformat(timestamp_str) if timestamp_str else datetime.now(datetime.UTC)
timestamp = datetime.fromisoformat(timestamp_str) if timestamp_str else datetime.now(timezone.utc)
except (ValueError, TypeError):
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
tx_count = block_data.get("tx_count", 0)
if transactions:

View File

@@ -5,7 +5,7 @@ from __future__ import annotations
import sys
import asyncio
import pytest
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from unittest.mock import AsyncMock, Mock, patch
from typing import Generator
@@ -192,7 +192,7 @@ class TestPoAProposer:
hash="0xparent",
parent_hash="0x00",
proposer="previous-proposer",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tx_count=0,
)
test_db.add(parent)
@@ -231,16 +231,16 @@ class TestPoAProposer:
hash="0xhead",
parent_hash="0x00",
proposer="test-proposer",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tx_count=0,
)
test_db.add(head)
test_db.commit()
# Should wait for the configured interval
start_time = datetime.now(datetime.UTC)
start_time = datetime.now(timezone.utc)
await proposer._wait_until_next_slot()
elapsed = (datetime.now(datetime.UTC) - start_time).total_seconds()
elapsed = (datetime.now(timezone.utc) - start_time).total_seconds()
# Should wait at least some time (but less than full interval since block is recent)
assert elapsed >= 0.1
@@ -255,7 +255,7 @@ class TestPoAProposer:
hash="0xhead",
parent_hash="0x00",
proposer="test-proposer",
timestamp=datetime.now(datetime.UTC) - timedelta(seconds=10),
timestamp=datetime.now(timezone.utc) - timedelta(seconds=10),
tx_count=0,
)
test_db.add(head)
@@ -263,9 +263,9 @@ class TestPoAProposer:
# Set stop event and wait
proposer._stop_event.set()
start_time = datetime.now(datetime.UTC)
start_time = datetime.now(timezone.utc)
await proposer._wait_until_next_slot()
elapsed = (datetime.now(datetime.UTC) - start_time).total_seconds()
elapsed = (datetime.now(timezone.utc) - start_time).total_seconds()
# Should return immediately due to stop event
assert elapsed < 0.1
@@ -290,7 +290,7 @@ class TestPoAProposer:
"""Test block hash computation."""
height = 1
parent_hash = "0xparent"
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
processed_txs = []
block_hash = proposer._compute_block_hash(height, parent_hash, timestamp, processed_txs)
@@ -303,7 +303,7 @@ class TestPoAProposer:
"""Test block hash computation with transactions."""
height = 1
parent_hash = "0xparent"
timestamp = datetime.now(datetime.UTC)
timestamp = datetime.now(timezone.utc)
mock_tx = Mock()
mock_tx.tx_hash = "0xtx"
@@ -324,7 +324,7 @@ class TestPoAProposer:
hash="0xexisting",
parent_hash="0x00",
proposer="test-proposer",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tx_count=0,
)
test_db.add(block)

View File

@@ -6,7 +6,7 @@ import sys
import pytest
import tempfile
import shutil
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from unittest.mock import patch, Mock
from typing import Generator
@@ -113,7 +113,7 @@ class TestGuardianContract:
def test_spending_limit_check_hourly(self, guardian_contract: GuardianContract) -> None:
"""Test hourly spending limit."""
# Add some spending history
base_time = datetime.now(datetime.UTC)
base_time = datetime.now(timezone.utc)
guardian_contract.spending_history = [
{
"operation_id": "op1",
@@ -139,7 +139,7 @@ class TestGuardianContract:
def test_spending_limit_check_daily(self, guardian_contract: GuardianContract) -> None:
"""Test daily spending limit."""
# Add spending history across the day
base_time = datetime.now(datetime.UTC)
base_time = datetime.now(timezone.utc)
guardian_contract.spending_history = [
{
"operation_id": "op1",
@@ -165,7 +165,7 @@ class TestGuardianContract:
def test_spending_limit_check_weekly(self, guardian_contract: GuardianContract) -> None:
"""Test weekly spending limit."""
# Add spending history across the week
base_time = datetime.now(datetime.UTC)
base_time = datetime.now(timezone.utc)
guardian_contract.spending_history = [
{
"operation_id": "op1",

View File

@@ -4,7 +4,7 @@ import hashlib
import time
import sys
import pytest
from datetime import datetime, UTC
from datetime import datetime, timezone
from contextlib import contextmanager
from unittest.mock import AsyncMock, Mock
@@ -70,7 +70,7 @@ class TestProposerSignatureValidator:
def test_valid_block(self):
v = ProposerSignatureValidator()
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 1, "0x00", ts)
ok, reason = v.validate_block_signature({
"height": 1, "hash": bh, "parent_hash": "0x00",
@@ -83,7 +83,7 @@ class TestProposerSignatureValidator:
v = ProposerSignatureValidator()
ok, reason = v.validate_block_signature({
"height": 1, "hash": "0x" + "a" * 64, "parent_hash": "0x00",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
})
assert ok is False
assert "Missing proposer" in reason
@@ -92,7 +92,7 @@ class TestProposerSignatureValidator:
v = ProposerSignatureValidator()
ok, reason = v.validate_block_signature({
"height": 1, "hash": "badhash", "parent_hash": "0x00",
"proposer": "node-a", "timestamp": datetime.now(datetime.UTC).isoformat(),
"proposer": "node-a", "timestamp": datetime.now(timezone.utc).isoformat(),
})
assert ok is False
assert "Invalid block hash" in reason
@@ -101,14 +101,14 @@ class TestProposerSignatureValidator:
v = ProposerSignatureValidator()
ok, reason = v.validate_block_signature({
"height": 1, "hash": "0xabc", "parent_hash": "0x00",
"proposer": "node-a", "timestamp": datetime.now(datetime.UTC).isoformat(),
"proposer": "node-a", "timestamp": datetime.now(timezone.utc).isoformat(),
})
assert ok is False
assert "Invalid hash length" in reason
def test_untrusted_proposer_rejected(self):
v = ProposerSignatureValidator(trusted_proposers=["node-a", "node-b"])
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 1, "0x00", ts)
ok, reason = v.validate_block_signature({
"height": 1, "hash": bh, "parent_hash": "0x00",
@@ -119,7 +119,7 @@ class TestProposerSignatureValidator:
def test_trusted_proposer_accepted(self):
v = ProposerSignatureValidator(trusted_proposers=["node-a"])
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 1, "0x00", ts)
ok, reason = v.validate_block_signature({
"height": 1, "hash": bh, "parent_hash": "0x00",
@@ -149,7 +149,7 @@ class TestChainSyncAppend:
def test_append_to_empty_chain(self, session_factory):
sync = ChainSync(session_factory, chain_id="test", validate_signatures=False)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
result = sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",
@@ -316,7 +316,7 @@ class TestChainSyncSignatureValidation:
def test_untrusted_proposer_rejected_on_import(self, session_factory):
validator = ProposerSignatureValidator(trusted_proposers=["node-a"])
sync = ChainSync(session_factory, chain_id="test", validator=validator, validate_signatures=True)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
result = sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",
@@ -328,7 +328,7 @@ class TestChainSyncSignatureValidation:
def test_trusted_proposer_accepted_on_import(self, session_factory):
validator = ProposerSignatureValidator(trusted_proposers=["node-a"])
sync = ChainSync(session_factory, chain_id="test", validator=validator, validate_signatures=True)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
result = sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",
@@ -339,7 +339,7 @@ class TestChainSyncSignatureValidation:
def test_validation_disabled(self, session_factory):
validator = ProposerSignatureValidator(trusted_proposers=["node-a"])
sync = ChainSync(session_factory, chain_id="test", validator=validator, validate_signatures=False)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
result = sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",
@@ -379,7 +379,7 @@ class TestSyncMetrics:
def test_accepted_block_increments_metrics(self, session_factory):
sync = ChainSync(session_factory, chain_id="test", validate_signatures=False)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",
@@ -392,7 +392,7 @@ class TestSyncMetrics:
def test_rejected_block_increments_metrics(self, session_factory):
validator = ProposerSignatureValidator(trusted_proposers=["node-a"])
sync = ChainSync(session_factory, chain_id="test", validator=validator, validate_signatures=True)
ts = datetime.now(datetime.UTC)
ts = datetime.now(timezone.utc)
bh = _make_block_hash("test", 0, "0x00", ts)
sync.import_block({
"height": 0, "hash": bh, "parent_hash": "0x00",

View File

@@ -5,7 +5,7 @@ Handles KYC/AML, regulatory compliance, and monitoring
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
@@ -68,7 +68,7 @@ async def root():
return {
"service": "AITBC Compliance Service",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -97,7 +97,7 @@ async def submit_kyc(kyc_request: KYCRequest):
"document_number": kyc_request.document_number,
"address": kyc_request.address,
"status": "pending",
"submitted_at": datetime.now(datetime.UTC).isoformat(),
"submitted_at": datetime.now(timezone.utc).isoformat(),
"reviewed_at": None,
"approved_at": None,
"risk_score": "medium",
@@ -111,8 +111,8 @@ async def submit_kyc(kyc_request: KYCRequest):
# Auto-approve for demo (in production, this would involve actual verification)
kyc_record["status"] = "approved"
kyc_record["reviewed_at"] = datetime.now(datetime.UTC).isoformat()
kyc_record["approved_at"] = datetime.now(datetime.UTC).isoformat()
kyc_record["reviewed_at"] = datetime.now(timezone.utc).isoformat()
kyc_record["approved_at"] = datetime.now(timezone.utc).isoformat()
kyc_record["risk_score"] = "low"
logger.info(f"KYC approved for user: {kyc_request.user_id}")
@@ -146,7 +146,7 @@ async def list_kyc_records():
@app.post("/api/v1/compliance/report")
async def create_compliance_report(report: ComplianceReport):
"""Create a compliance report"""
report_id = f"report_{int(datetime.now(datetime.UTC).timestamp())}"
report_id = f"report_{int(datetime.now(timezone.utc).timestamp())}"
compliance_record = {
"report_id": report_id,
@@ -155,7 +155,7 @@ async def create_compliance_report(report: ComplianceReport):
"severity": report.severity,
"details": report.details,
"status": "open",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"assigned_to": None,
"resolved_at": None,
"resolution": None
@@ -195,7 +195,7 @@ async def monitor_transaction(transaction: TransactionMonitoring):
"currency": transaction.currency,
"counterparty": transaction.counterparty,
"timestamp": transaction.timestamp.isoformat(),
"monitored_at": datetime.now(datetime.UTC).isoformat(),
"monitored_at": datetime.now(timezone.utc).isoformat(),
"risk_score": calculate_transaction_risk(transaction),
"flags": [],
"status": "monitored"
@@ -232,7 +232,7 @@ async def list_monitored_transactions():
@app.post("/api/v1/rules/create")
async def create_compliance_rule(rule_data: Dict[str, Any]):
"""Create a new compliance rule"""
rule_id = f"rule_{int(datetime.now(datetime.UTC).timestamp())}"
rule_id = f"rule_{int(datetime.now(timezone.utc).timestamp())}"
rule = {
"rule_id": rule_id,
@@ -243,7 +243,7 @@ async def create_compliance_rule(rule_data: Dict[str, Any]):
"actions": rule_data.get("actions", []),
"severity": rule_data.get("severity", "medium"),
"active": True,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"trigger_count": 0
}
@@ -294,7 +294,7 @@ async def compliance_dashboard():
},
"risk_distribution": get_risk_distribution(),
"recent_activity": get_recent_activity(),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Helper functions
@@ -337,7 +337,7 @@ def check_suspicious_patterns(transaction: TransactionMonitoring) -> List[str]:
recent_transactions = [t for t in user_transactions
if datetime.fromisoformat(t["monitored_at"]) >
datetime.now(datetime.UTC) - timedelta(hours=1)]
datetime.now(timezone.utc) - timedelta(hours=1)]
if len(recent_transactions) > 5:
flags.append("rapid_transactions")
@@ -385,7 +385,7 @@ def get_recent_activity() -> List[Dict]:
recent_kyc = [r for r in kyc_records.values()
if r.get("approved_at") and
datetime.fromisoformat(r["approved_at"]) >
datetime.now(datetime.UTC) - timedelta(hours=24)]
datetime.now(timezone.utc) - timedelta(hours=24)]
for kyc in recent_kyc[:5]:
activities.append({
@@ -397,7 +397,7 @@ def get_recent_activity() -> List[Dict]:
# Recent compliance reports
recent_reports = [r for r in compliance_reports.values()
if datetime.fromisoformat(r["created_at"]) >
datetime.now(datetime.UTC) - timedelta(hours=24)]
datetime.now(timezone.utc) - timedelta(hours=24)]
for report in recent_reports[:5]:
activities.append({
@@ -418,7 +418,7 @@ async def periodic_compliance_checks():
await asyncio.sleep(300) # Check every 5 minutes
# Check for expired KYC records
current_time = datetime.now(datetime.UTC)
current_time = datetime.now(timezone.utc)
for user_id, kyc_record in kyc_records.items():
if kyc_record["status"] == "approved":
approved_time = datetime.fromisoformat(kyc_record["approved_at"])

View File

@@ -6,7 +6,7 @@ import sys
from pathlib import Path
from unittest.mock import Mock, patch
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, KYCRequest, ComplianceReport, TransactionMonitoring, kyc_records, compliance_reports, suspicious_transactions, compliance_rules
@@ -62,7 +62,7 @@ def test_transaction_monitoring_zero_amount():
amount=0.0,
currency="BTC",
counterparty="counterparty1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert tx.amount == 0.0
@@ -76,7 +76,7 @@ def test_transaction_monitoring_negative_amount():
amount=-1000.0,
currency="BTC",
counterparty="counterparty1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert tx.amount == -1000.0

View File

@@ -6,7 +6,7 @@ import sys
from pathlib import Path
from unittest.mock import Mock, patch
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, KYCRequest, ComplianceReport, TransactionMonitoring, kyc_records, compliance_reports, suspicious_transactions, compliance_rules
@@ -171,7 +171,7 @@ def test_monitor_transaction():
amount=1000.0,
currency="BTC",
counterparty="counterparty1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/monitoring/transaction", json=tx.model_dump(mode='json'))
assert response.status_code == 200
@@ -190,7 +190,7 @@ def test_monitor_suspicious_transaction():
amount=100000.0,
currency="BTC",
counterparty="high_risk_entity_1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/monitoring/transaction", json=tx.model_dump(mode='json'))
assert response.status_code == 200

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from unittest.mock import Mock, patch
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, KYCRequest, ComplianceReport, TransactionMonitoring, calculate_transaction_risk, check_suspicious_patterns
@@ -62,7 +62,7 @@ def test_transaction_monitoring_model():
amount=1000.0,
currency="BTC",
counterparty="counterparty1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert tx.transaction_id == "tx123"
assert tx.user_id == "user123"
@@ -125,7 +125,7 @@ def test_check_suspicious_patterns_high_value():
amount=100000.0,
currency="BTC",
counterparty="counterparty1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
flags = check_suspicious_patterns(tx)
assert "high_value_transaction" in flags
@@ -140,7 +140,7 @@ def test_check_suspicious_patterns_high_risk_counterparty():
amount=1000.0,
currency="BTC",
counterparty="high_risk_entity_1",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
flags = check_suspicious_patterns(tx)
assert "high_risk_counterparty" in flags
@@ -155,7 +155,7 @@ def test_check_suspicious_patterns_none():
amount=1000.0,
currency="BTC",
counterparty="safe_counterparty",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
flags = check_suspicious_patterns(tx)
assert len(flags) == 0

View File

@@ -6,7 +6,7 @@ Demonstrates basic usage of the Agent Identity SDK
import asyncio
import json
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, Any
# Import SDK components
@@ -94,7 +94,7 @@ async def basic_identity_example():
"agent_id": identity.agent_id,
"chain_id": mapping.chain_id,
"chain_address": mapping.chain_address,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"verification_method": "demo"
}
@@ -234,7 +234,7 @@ async def advanced_transaction_example():
"description": "Updated description with new capabilities",
"metadata": {
"version": "1.1.0",
"last_updated": datetime.now(datetime.UTC).isoformat()
"last_updated": datetime.now(timezone.utc).isoformat()
},
"tags": ["demo", "ai", "updated"]
}

View File

@@ -6,7 +6,7 @@ Complete deployment procedures for the agent orchestration system
import asyncio
import json
from aitbc.logging import get_logger
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, List, Optional, Any
from pathlib import Path
@@ -30,7 +30,7 @@ class AgentOrchestrationDeployment:
"""Deploy complete agent orchestration system to production"""
deployment_result = {
"deployment_id": f"prod_deploy_{datetime.now(datetime.UTC).strftime('%Y%m%d_%H%M%S')}",
"deployment_id": f"prod_deploy_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}",
"status": "in_progress",
"steps_completed": [],
"steps_failed": [],

View File

@@ -6,7 +6,7 @@ Ongoing maintenance, monitoring, and enhancement of the complete system
import asyncio
import json
from aitbc.logging import get_logger
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, List, Optional, Any
from enum import Enum
@@ -73,7 +73,7 @@ class SystemMaintenanceManager:
"""Perform comprehensive maintenance cycle"""
maintenance_result = {
"maintenance_cycle": f"maintenance_{datetime.now(datetime.UTC).strftime('%Y%m%d_%H%M%S')}",
"maintenance_cycle": f"maintenance_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}",
"status": "in_progress",
"categories_completed": [],
"enhancements_implemented": [],

View File

@@ -5,7 +5,7 @@ Provides unified agent identification and cross-chain compatibility
import hashlib
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from uuid import uuid4
@@ -90,7 +90,7 @@ class AgentIdentityCore:
if hasattr(identity, field):
setattr(identity, field, value)
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
self.session.commit()
self.session.refresh(identity)
@@ -133,7 +133,7 @@ class AgentIdentityCore:
# Update identity's supported chains
if chain_id not in identity.supported_chains:
identity.supported_chains.append(str(chain_id))
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
self.session.commit()
logger.info(f"Registered cross-chain identity: {identity_id} -> {chain_id}:{chain_address}")
@@ -190,7 +190,7 @@ class AgentIdentityCore:
# Update mapping verification status
mapping.is_verified = True
mapping.verified_at = datetime.now(datetime.UTC)
mapping.verified_at = datetime.now(timezone.utc)
mapping.verification_proof = proof_data
self.session.commit()
@@ -198,7 +198,7 @@ class AgentIdentityCore:
identity = await self.get_identity(identity_id)
if identity and chain_id == identity.primary_chain:
identity.is_verified = True
identity.verified_at = datetime.now(datetime.UTC)
identity.verified_at = datetime.now(timezone.utc)
identity.verification_level = verification_type
self.session.commit()
@@ -242,7 +242,7 @@ class AgentIdentityCore:
else:
setattr(mapping, field, value)
mapping.updated_at = datetime.now(datetime.UTC)
mapping.updated_at = datetime.now(timezone.utc)
self.session.commit()
self.session.refresh(mapping)
@@ -260,11 +260,11 @@ class AgentIdentityCore:
# Update identity status
identity.status = IdentityStatus.REVOKED
identity.is_verified = False
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
# Add revocation reason to identity_data
identity.identity_data["revocation_reason"] = reason
identity.identity_data["revoked_at"] = datetime.now(datetime.UTC).isoformat()
identity.identity_data["revoked_at"] = datetime.now(timezone.utc).isoformat()
self.session.commit()
@@ -280,11 +280,11 @@ class AgentIdentityCore:
# Update identity status
identity.status = IdentityStatus.SUSPENDED
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
# Add suspension reason to identity_data
identity.identity_data["suspension_reason"] = reason
identity.identity_data["suspended_at"] = datetime.now(datetime.UTC).isoformat()
identity.identity_data["suspended_at"] = datetime.now(timezone.utc).isoformat()
self.session.commit()
@@ -303,7 +303,7 @@ class AgentIdentityCore:
# Update identity status
identity.status = IdentityStatus.ACTIVE
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
# Clear suspension identity_data
if "suspension_reason" in identity.identity_data:
@@ -336,8 +336,8 @@ class AgentIdentityCore:
volume_factor = min(amount / 1000.0, 1.0) # Cap at 1.0 for amounts > 1000
identity.reputation_score = base_score * (0.7 + 0.3 * volume_factor)
identity.last_activity = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(datetime.UTC)
identity.last_activity = datetime.now(timezone.utc)
identity.updated_at = datetime.now(timezone.utc)
self.session.commit()
self.session.refresh(identity)
@@ -452,7 +452,7 @@ class AgentIdentityCore:
"owner_address": identity.owner_address,
"chain_id": chain_id,
"chain_address": mapping.chain_address,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"nonce": str(uuid4()),
}
@@ -463,5 +463,5 @@ class AgentIdentityCore:
return {
"proof_data": proof_data,
"proof_hash": proof_hash,
"expires_at": (datetime.now(datetime.UTC) + timedelta(hours=24)).isoformat(),
"expires_at": (datetime.now(timezone.utc) + timedelta(hours=24)).isoformat(),
}

View File

@@ -3,7 +3,7 @@ Agent Identity Manager Implementation
High-level manager for agent identity operations and cross-chain management
"""
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any
from uuid import uuid4
@@ -171,7 +171,7 @@ class AgentIdentityManager:
# Update identity reputation
await self.core.update_reputation(agent_id, True, 0) # This will recalculate based on new data
identity.reputation_score = aggregated_score
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
self.session.commit()
else:
aggregated_score = identity.reputation_score
@@ -181,7 +181,7 @@ class AgentIdentityManager:
"aggregated_reputation": aggregated_score,
"chain_reputations": reputation_scores,
"verified_chains": list(verified_chains) if "verified_chains" in locals() else [],
"sync_timestamp": datetime.now(datetime.UTC).isoformat(),
"sync_timestamp": datetime.now(timezone.utc).isoformat(),
}
except Exception as e:
@@ -449,12 +449,12 @@ class AgentIdentityManager:
"supported_chains": supported_chains,
"cleaned_verifications": cleaned_count,
"issues": issues,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
except Exception as e:
logger.error(f"Failed to get registry health: {e}")
return {"status": "error", "error": "Health check failed", "timestamp": datetime.now(datetime.UTC).isoformat()}
return {"status": "error", "error": "Health check failed", "timestamp": datetime.now(timezone.utc).isoformat()}
async def export_agent_identity(self, agent_id: str, format: str = "json") -> dict[str, Any]:
"""Export agent identity data for backup or migration"""
@@ -469,7 +469,7 @@ class AgentIdentityManager:
# Prepare export data
export_data = {
"export_version": "1.0",
"export_timestamp": datetime.now(datetime.UTC).isoformat(),
"export_timestamp": datetime.now(timezone.utc).isoformat(),
"agent_id": agent_id,
"identity": summary["identity"],
"cross_chain_mappings": summary["cross_chain"]["mappings"],
@@ -541,7 +541,7 @@ class AgentIdentityManager:
"identity_id": identity.id,
"import_successful": True,
"restored_mappings": len(chain_mappings),
"import_timestamp": datetime.now(datetime.UTC).isoformat(),
"import_timestamp": datetime.now(timezone.utc).isoformat(),
}
except Exception as e:

View File

@@ -5,7 +5,7 @@ Registry for cross-chain agent identity mapping and synchronization
import hashlib
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from uuid import uuid4
@@ -97,7 +97,7 @@ class CrossChainRegistry:
registration_results.append({"chain_id": chain_id, "chain_address": chain_address, "error": str(e)})
# Update identity
identity.updated_at = datetime.now(datetime.UTC)
identity.updated_at = datetime.now(timezone.utc)
self.session.commit()
return {
@@ -143,7 +143,7 @@ class CrossChainRegistry:
old_address = mapping.chain_address
mapping.chain_address = new_address.lower()
mapping.updated_at = datetime.now(datetime.UTC)
mapping.updated_at = datetime.now(timezone.utc)
# Reset verification status since address changed
mapping.is_verified = False
@@ -195,7 +195,7 @@ class CrossChainRegistry:
proof_hash=proof_hash,
proof_data=proof_data,
verification_result="approved",
expires_at=datetime.now(datetime.UTC) + timedelta(days=30),
expires_at=datetime.now(timezone.utc) + timedelta(days=30),
)
self.session.add(verification)
@@ -204,7 +204,7 @@ class CrossChainRegistry:
# Update mapping verification status
mapping.is_verified = True
mapping.verified_at = datetime.now(datetime.UTC)
mapping.verified_at = datetime.now(timezone.utc)
mapping.verification_proof = proof_data
self.session.commit()
@@ -212,7 +212,7 @@ class CrossChainRegistry:
if self._is_higher_verification_level(verification_type, identity.verification_level):
identity.verification_level = verification_type
identity.is_verified = True
identity.verified_at = datetime.now(datetime.UTC)
identity.verified_at = datetime.now(timezone.utc)
self.session.commit()
logger.info(f"Verified cross-chain identity: {identity_id} on chain {chain_id}")
@@ -229,14 +229,14 @@ class CrossChainRegistry:
mapping.is_verified = False
mapping.verified_at = None
mapping.verification_proof = None
mapping.updated_at = datetime.now(datetime.UTC)
mapping.updated_at = datetime.now(timezone.utc)
# Add revocation to metadata
if not mapping.chain_metadata:
mapping.chain_metadata = {}
mapping.chain_metadata["verification_revoked"] = True
mapping.chain_metadata["revocation_reason"] = reason
mapping.chain_metadata["revoked_at"] = datetime.now(datetime.UTC).isoformat()
mapping.chain_metadata["revoked_at"] = datetime.now(timezone.utc).isoformat()
self.session.commit()
@@ -453,7 +453,7 @@ class CrossChainRegistry:
async def cleanup_expired_verifications(self) -> int:
"""Clean up expired verification records"""
current_time = datetime.now(datetime.UTC)
current_time = datetime.now(timezone.utc)
# Find expired verifications
stmt = select(IdentityVerification).where(IdentityVerification.expires_at < current_time)

View File

@@ -4,7 +4,7 @@ Provides blockchain-agnostic wallet interface for agents
"""
from abc import ABC, abstractmethod
from datetime import datetime, UTC
from datetime import datetime, timezone
from decimal import Decimal
from typing import Any
@@ -69,7 +69,7 @@ class EthereumWalletAdapter(WalletAdapter):
"wallet_address": f"0x{'0' * 40}", # Mock address
"contract_address": f"0x{'1' * 40}", # Mock contract
"transaction_hash": f"0x{'2' * 64}", # Mock tx hash
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
}
async def get_balance(self, wallet_address: str) -> Decimal:
@@ -91,7 +91,7 @@ class EthereumWalletAdapter(WalletAdapter):
"gas_price": "20000000000",
"status": "success",
"block_number": 12345,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
async def get_transaction_history(self, wallet_address: str, limit: int = 50, offset: int = 0) -> list[dict[str, Any]]:
@@ -105,7 +105,7 @@ class EthereumWalletAdapter(WalletAdapter):
"amount": "0.1",
"gas_used": "21000",
"block_number": 12344,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
]
@@ -269,7 +269,7 @@ class MultiChainWalletAdapter:
# Update wallet in database
wallet.total_spent += float(amount)
wallet.last_transaction = datetime.now(datetime.UTC)
wallet.last_transaction = datetime.now(timezone.utc)
wallet.transaction_count += 1
self.session.commit()
@@ -312,7 +312,7 @@ class MultiChainWalletAdapter:
if hasattr(wallet, field):
setattr(wallet, field, value)
wallet.updated_at = datetime.now(datetime.UTC)
wallet.updated_at = datetime.now(timezone.utc)
self.session.commit()
self.session.refresh(wallet)
@@ -338,7 +338,7 @@ class MultiChainWalletAdapter:
# Deactivate wallet
wallet.is_active = False
wallet.updated_at = datetime.now(datetime.UTC)
wallet.updated_at = datetime.now(timezone.utc)
self.session.commit()

View File

@@ -7,7 +7,7 @@ import hashlib
import json
import secrets
from abc import ABC, abstractmethod
from datetime import datetime, UTC
from datetime import datetime, timezone
from decimal import Decimal
from enum import StrEnum
from typing import Any
@@ -124,7 +124,7 @@ class EnhancedWalletAdapter(ABC):
"""Securely sign a message"""
try:
# Add timestamp and nonce for replay protection
timestamp = str(int(datetime.now(datetime.UTC).timestamp()))
timestamp = str(int(datetime.now(timezone.utc).timestamp()))
nonce = secrets.token_hex(16)
message_to_sign = f"{message}:{timestamp}:{nonce}"
@@ -194,7 +194,7 @@ class EthereumWalletAdapter(EnhancedWalletAdapter):
"chain_type": self.chain_type.value,
"owner_address": owner_address,
"security_level": self.security_level.value,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"status": WalletStatus.ACTIVE.value,
"security_config": security_config,
"nonce": 0,
@@ -227,7 +227,7 @@ class EthereumWalletAdapter(EnhancedWalletAdapter):
"chain_id": self.chain_id,
"eth_balance": eth_balance,
"token_balances": {},
"last_updated": datetime.now(datetime.UTC).isoformat(),
"last_updated": datetime.now(timezone.utc).isoformat(),
}
# Get token balances if specified
@@ -304,7 +304,7 @@ class EthereumWalletAdapter(EnhancedWalletAdapter):
"gas_limit": gas_limit,
"gas_price": gas_price,
"status": TransactionStatus.PENDING.value,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
}
logger.info(f"Executed Ethereum transaction {tx_hash} from {from_address} to {to_address}")
@@ -331,7 +331,7 @@ class EthereumWalletAdapter(EnhancedWalletAdapter):
"gas_used": None,
"effective_gas_price": None,
"logs": [],
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
}
# Get transaction details
@@ -348,7 +348,7 @@ class EthereumWalletAdapter(EnhancedWalletAdapter):
"from": tx_data.get("from"),
"to": tx_data.get("to"),
"value": int(tx_data.get("value", "0x0"), 16),
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
}
return result

View File

@@ -4,7 +4,7 @@ Exception classes and error response schemas for AITBC coordinator
Provides structured error responses for consistent API error handling.
"""
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any
from pydantic import BaseModel, Field

View File

@@ -122,7 +122,7 @@ class ServiceRegistry(BaseModel):
"""Service registry containing all available services"""
version: str = Field("1.0.0", description="Registry version")
last_updated: datetime = Field(default_factory=datetime.now(datetime.UTC), description="Last update time")
last_updated: datetime = Field(default_factory=datetime.now(timezone.utc), description="Last update time")
services: dict[str, ServiceDefinition] = Field(..., description="Service definitions by ID")
def get_service(self, service_id: str) -> ServiceDefinition | None:

View File

@@ -3,7 +3,7 @@ Repository layer for confidential transactions
"""
from base64 import b64decode
from datetime import datetime, UTC
from datetime import datetime, timezone
from sqlalchemy import and_, delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
@@ -131,7 +131,7 @@ class ParticipantKeyRepository:
stmt = (
update(ParticipantKeyDB)
.where(ParticipantKeyDB.participant_id == participant_id)
.values(active=active, revoked_at=datetime.now(datetime.UTC) if not active else None, revoke_reason=reason)
.values(active=active, revoked_at=datetime.now(timezone.utc) if not active else None, revoke_reason=reason)
)
result = await session.execute(stmt)
@@ -309,7 +309,7 @@ class AuditAuthorizationRepository:
and_(
AuditAuthorizationDB.id == authorization_id,
AuditAuthorizationDB.active,
AuditAuthorizationDB.expires_at > datetime.now(datetime.UTC),
AuditAuthorizationDB.expires_at > datetime.now(timezone.utc),
)
)
@@ -321,7 +321,7 @@ class AuditAuthorizationRepository:
stmt = (
update(AuditAuthorizationDB)
.where(AuditAuthorizationDB.id == authorization_id)
.values(active=False, revoked_at=datetime.now(datetime.UTC))
.values(active=False, revoked_at=datetime.now(timezone.utc))
)
result = await session.execute(stmt)
@@ -331,7 +331,7 @@ class AuditAuthorizationRepository:
async def cleanup_expired(self, session: AsyncSession) -> int:
"""Clean up expired authorizations"""
stmt = update(AuditAuthorizationDB).where(AuditAuthorizationDB.expires_at < datetime.now(datetime.UTC)).values(active=False)
stmt = update(AuditAuthorizationDB).where(AuditAuthorizationDB.expires_at < datetime.now(timezone.utc)).values(active=False)
result = await session.execute(stmt)
await session.commit()

View File

@@ -3,7 +3,7 @@ Cross-Chain Reputation Aggregator
Aggregates reputation data from multiple blockchains and normalizes scores
"""
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any
from aitbc import get_logger
@@ -147,7 +147,7 @@ class CrossChainReputationAggregator:
{
"agent_id": agent_id,
"anomaly_type": "low_consistency",
"detected_at": datetime.now(datetime.UTC),
"detected_at": datetime.now(timezone.utc),
"description": f"Low consistency score: {aggregation.consistency_score:.2f}",
"severity": "high" if aggregation.consistency_score < 0.5 else "medium",
"consistency_score": aggregation.consistency_score,
@@ -162,7 +162,7 @@ class CrossChainReputationAggregator:
{
"agent_id": agent_id,
"anomaly_type": "high_variance",
"detected_at": datetime.now(datetime.UTC),
"detected_at": datetime.now(timezone.utc),
"description": f"High score variance: {aggregation.score_variance:.2f}",
"severity": "high" if aggregation.score_variance > 0.5 else "medium",
"score_variance": aggregation.score_variance,
@@ -180,7 +180,7 @@ class CrossChainReputationAggregator:
{
"agent_id": agent_id,
"anomaly_type": "missing_chain_data",
"detected_at": datetime.now(datetime.UTC),
"detected_at": datetime.now(timezone.utc),
"description": f"Missing data for chains: {list(missing_chains)}",
"severity": "medium",
"missing_chains": list(missing_chains),
@@ -221,7 +221,7 @@ class CrossChainReputationAggregator:
# Update reputation
reputation.trust_score = new_score * 1000 # Convert to 0-1000 scale
reputation.reputation_level = self._determine_reputation_level(new_score)
reputation.updated_at = datetime.now(datetime.UTC)
reputation.updated_at = datetime.now(timezone.utc)
# Create event record
event = ReputationEvent(
@@ -231,7 +231,7 @@ class CrossChainReputationAggregator:
trust_score_before=reputation.trust_score,
trust_score_after=reputation.trust_score,
event_data=update,
occurred_at=datetime.now(datetime.UTC),
occurred_at=datetime.now(timezone.utc),
)
self.session.add(event)
@@ -242,8 +242,8 @@ class CrossChainReputationAggregator:
agent_id=agent_id,
trust_score=new_score * 1000,
reputation_level=self._determine_reputation_level(new_score),
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
)
self.session.add(reputation)
@@ -316,7 +316,7 @@ class CrossChainReputationAggregator:
"reputation_distribution": distribution,
"total_transactions": total_transactions,
"success_rate": success_rate,
"last_updated": datetime.now(datetime.UTC),
"last_updated": datetime.now(timezone.utc),
}
except Exception as e:
@@ -430,7 +430,7 @@ class CrossChainReputationAggregator:
aggregation.score_variance = variance
aggregation.score_range = score_range
aggregation.consistency_score = consistency_score
aggregation.last_updated = datetime.now(datetime.UTC)
aggregation.last_updated = datetime.now(timezone.utc)
else:
aggregation = CrossChainReputationAggregation(
agent_id=agent_id,
@@ -441,8 +441,8 @@ class CrossChainReputationAggregator:
score_range=score_range,
consistency_score=consistency_score,
verification_status="pending",
created_at=datetime.now(datetime.UTC),
last_updated=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
last_updated=datetime.now(timezone.utc),
)
self.session.add(aggregation)

View File

@@ -3,7 +3,7 @@ Cross-Chain Reputation Engine
Core reputation calculation and aggregation engine for multi-chain agent reputation
"""
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from aitbc import get_logger
@@ -57,8 +57,8 @@ class CrossChainReputationEngine:
agent_id=agent_id,
trust_score=score * 1000, # Convert to 0-1000 scale
reputation_level=self._determine_reputation_level(score),
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
)
self.session.add(new_reputation)
@@ -152,8 +152,8 @@ class CrossChainReputationEngine:
agent_id=agent_id,
trust_score=max(0, min(1000, (base_score + impact_score) * 1000)),
reputation_level=self._determine_reputation_level(base_score + impact_score),
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
)
self.session.add(reputation)
@@ -164,7 +164,7 @@ class CrossChainReputationEngine:
reputation.trust_score = new_score * 1000
reputation.reputation_level = self._determine_reputation_level(new_score)
reputation.updated_at = datetime.now(datetime.UTC)
reputation.updated_at = datetime.now(timezone.utc)
# Create reputation event record
event = ReputationEvent(
@@ -174,7 +174,7 @@ class CrossChainReputationEngine:
trust_score_before=reputation.trust_score - (impact_score * 1000),
trust_score_after=reputation.trust_score,
event_data=event_data,
occurred_at=datetime.now(datetime.UTC),
occurred_at=datetime.now(timezone.utc),
)
self.session.add(event)
@@ -195,7 +195,7 @@ class CrossChainReputationEngine:
try:
# Get reputation events for the period
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=days)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days)
stmt = (
select(ReputationEvent)
@@ -295,7 +295,7 @@ class CrossChainReputationEngine:
reputation.trust_score = new_score * 1000
reputation.reputation_level = self._determine_reputation_level(new_score)
reputation.updated_at = datetime.now(datetime.UTC)
reputation.updated_at = datetime.now(timezone.utc)
# Update transaction metrics if available
if "transaction_count" in transaction_data:
@@ -364,7 +364,7 @@ class CrossChainReputationEngine:
aggregation.score_variance = variance
aggregation.score_range = score_range
aggregation.consistency_score = consistency_score
aggregation.last_updated = datetime.now(datetime.UTC)
aggregation.last_updated = datetime.now(timezone.utc)
else:
# Create new aggregation
aggregation = CrossChainReputationAggregation(
@@ -376,8 +376,8 @@ class CrossChainReputationEngine:
score_range=score_range,
consistency_score=consistency_score,
verification_status="pending",
created_at=datetime.now(datetime.UTC),
last_updated=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
last_updated=datetime.now(timezone.utc),
)
self.session.add(aggregation)
@@ -440,7 +440,7 @@ class CrossChainReputationEngine:
"total_transactions": getattr(reputation, "transaction_count", 0),
"success_rate": getattr(reputation, "success_rate", 0.0),
"dispute_count": getattr(reputation, "dispute_count", 0),
"last_activity": getattr(reputation, "last_activity", datetime.now(datetime.UTC)),
"last_activity": getattr(reputation, "last_activity", datetime.now(timezone.utc)),
"cross_chain": {
"aggregated_score": aggregation.aggregated_score if aggregation else 0.0,
"chain_count": aggregation.chain_count if aggregation else 0,

View File

@@ -358,7 +358,7 @@ class PricingError(BaseModel):
error_code: str = Field(..., description="Error code")
message: str = Field(..., description="Error message")
details: dict[str, Any] | None = Field(None, description="Additional error details")
timestamp: datetime = Field(default_factory=datetime.now(datetime.UTC), description="Error timestamp")
timestamp: datetime = Field(default_factory=datetime.now(timezone.utc), description="Error timestamp")
class Config:
json_encoders = {datetime: lambda v: v.isoformat()}

View File

@@ -6,7 +6,7 @@ Python SDK for enterprise clients to integrate with AITBC platform
import hashlib
import secrets
from dataclasses import dataclass, field
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from enum import StrEnum
from typing import Any
@@ -162,7 +162,7 @@ class EnterpriseClient:
# Store tokens
self.access_token = auth_data["access_token"]
self.refresh_token = auth_data.get("refresh_token")
self.token_expires_at = datetime.now(datetime.UTC) + timedelta(seconds=auth_data["expires_in"])
self.token_expires_at = datetime.now(timezone.utc) + timedelta(seconds=auth_data["expires_in"])
# Update session headers
self.session.headers["Authorization"] = f"Bearer {self.access_token}"
@@ -175,7 +175,7 @@ class EnterpriseClient:
async def _ensure_valid_token(self):
"""Ensure we have a valid access token"""
if not self.access_token or (self.token_expires_at and datetime.now(datetime.UTC) >= self.token_expires_at):
if not self.access_token or (self.token_expires_at and datetime.now(timezone.utc) >= self.token_expires_at):
await self.authenticate()
async def create_integration(self, integration_config: IntegrationConfig) -> APIResponse:

View File

@@ -5,7 +5,7 @@ Base interfaces for cross-chain settlement bridges
import json
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime, UTC
from datetime import datetime, timezone
from enum import Enum
from typing import Any
@@ -51,7 +51,7 @@ class SettlementMessage:
def __post_init__(self):
if self.created_at is None:
self.created_at = datetime.now(datetime.UTC)
self.created_at = datetime.now(timezone.utc)
@dataclass
@@ -69,7 +69,7 @@ class SettlementResult:
def __post_init__(self):
if self.created_at is None:
self.created_at = datetime.now(datetime.UTC)
self.created_at = datetime.now(timezone.utc)
class BridgeAdapter(ABC):
@@ -220,7 +220,7 @@ class EthereumBridge(BridgeAdapter):
transaction_hash="0x" + "0" * 64, # Mock hash
gas_used=gas_estimate,
fee_paid=int(self.config.default_fee),
completed_at=datetime.now(datetime.UTC)
completed_at=datetime.now(timezone.utc)
)
return result

View File

@@ -3,7 +3,7 @@ Settlement hooks for coordinator API integration
"""
import asyncio
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Any
from aitbc import get_logger
@@ -210,7 +210,7 @@ class SettlementHook:
"""Generate a unique nonce for settlement"""
# This would generate a unique nonce
# For now, use timestamp
return int(datetime.now(datetime.UTC).timestamp())
return int(datetime.now(timezone.utc).timestamp())
async def _sign_settlement_message(self, job: Job) -> str:
"""Sign the settlement message"""

View File

@@ -4,7 +4,7 @@ Bridge manager for cross-chain settlements
import asyncio
from dataclasses import asdict
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from .bridges.base import BridgeAdapter, BridgeConfig, BridgeError, BridgeStatus, SettlementMessage, SettlementResult
@@ -240,9 +240,9 @@ class BridgeManager:
async def _monitor_settlement(self, message_id: str) -> None:
"""Monitor settlement until completion"""
max_wait_time = timedelta(hours=1)
start_time = datetime.now(datetime.UTC)
start_time = datetime.now(timezone.utc)
while datetime.now(datetime.UTC) - start_time < max_wait_time:
while datetime.now(timezone.utc) - start_time < max_wait_time:
# Check status
result = await self.get_settlement_status(message_id)

View File

@@ -4,7 +4,7 @@ Storage layer for cross-chain settlements
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from .bridges.base import BridgeStatus, SettlementMessage
@@ -49,7 +49,7 @@ class SettlementStorage:
message.signature,
bridge_name,
status.value,
message.created_at or datetime.now(datetime.UTC),
message.created_at or datetime.now(timezone.utc),
),
)
@@ -90,7 +90,7 @@ class SettlementStorage:
return
updates.append(f"updated_at = ${param_count}")
params.append(datetime.now(datetime.UTC))
params.append(datetime.now(timezone.utc))
param_count += 1
params.append(message_id)
@@ -258,8 +258,8 @@ class InMemorySettlementStorage(SettlementStorage):
"signature": message.signature,
"bridge_name": bridge_name,
"status": status.value,
"created_at": message.created_at or datetime.now(datetime.UTC),
"updated_at": datetime.now(datetime.UTC),
"created_at": message.created_at or datetime.now(timezone.utc),
"updated_at": datetime.now(timezone.utc),
}
async def update_settlement(
@@ -285,7 +285,7 @@ class InMemorySettlementStorage(SettlementStorage):
if completed_at is not None:
settlement["completed_at"] = completed_at
settlement["updated_at"] = datetime.now(datetime.UTC)
settlement["updated_at"] = datetime.now(timezone.utc)
async def get_settlement(self, message_id: str) -> dict[str, Any] | None:
async with self._lock:
@@ -316,7 +316,7 @@ class InMemorySettlementStorage(SettlementStorage):
# Time range filtering
if time_range is not None:
cutoff = datetime.now(datetime.UTC) - timedelta(hours=time_range)
cutoff = datetime.now(timezone.utc) - timedelta(hours=time_range)
if settlement["created_at"] < cutoff:
continue
@@ -345,7 +345,7 @@ class InMemorySettlementStorage(SettlementStorage):
async def cleanup_old_settlements(self, days: int = 30) -> int:
async with self._lock:
cutoff = datetime.now(datetime.UTC) - timedelta(days=days)
cutoff = datetime.now(timezone.utc) - timedelta(days=days)
to_delete = [
msg_id

View File

@@ -13,7 +13,7 @@ from sqlalchemy.orm import Session, sessionmaker
from aitbc import get_logger
logger = get_logger(__name__)
from datetime import datetime, UTC
from datetime import datetime, timezone
from .config_pg import settings
@@ -237,6 +237,6 @@ def check_db_health() -> dict[str, Any]:
try:
adapter = get_db_adapter()
adapter.execute_query("SELECT 1 as health_check")
return {"status": "healthy", "database": "postgresql", "timestamp": datetime.now(datetime.UTC).isoformat()}
return {"status": "healthy", "database": "postgresql", "timestamp": datetime.now(timezone.utc).isoformat()}
except Exception as e:
return {"status": "unhealthy", "error": str(e), "timestamp": datetime.now(datetime.UTC).isoformat()}
return {"status": "unhealthy", "error": str(e), "timestamp": datetime.now(timezone.utc).isoformat()}

View File

@@ -20,7 +20,7 @@ class GovernanceProposal(SQLModel, table=True):
target: dict[str, Any] | None = Field(default_factory=dict, sa_column=Column(JSON))
proposer: str = Field(max_length=255, index=True)
status: str = Field(default="active", max_length=20) # active, passed, rejected, executed, expired
created_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
created_at: datetime = Field(default_factory=datetime.now(timezone.utc))
voting_deadline: datetime
quorum_threshold: float = Field(default=0.1) # Percentage of total voting power
approval_threshold: float = Field(default=0.5) # Percentage of votes in favor
@@ -40,7 +40,7 @@ class ProposalVote(SQLModel, table=True):
vote: str = Field(max_length=10) # for, against, abstain
voting_power: int = Field(default=0) # Amount of voting power at time of vote
reason: str | None = Field(max_length=500)
voted_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
voted_at: datetime = Field(default_factory=datetime.now(timezone.utc))
# Relationships
proposal: GovernanceProposal = Relationship(back_populates="votes")
@@ -57,7 +57,7 @@ class TreasuryTransaction(SQLModel, table=True):
token: str = Field(default="AITBC", max_length=20)
transaction_hash: str | None = Field(max_length=255)
status: str = Field(default="pending", max_length=20) # pending, confirmed, failed
created_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
created_at: datetime = Field(default_factory=datetime.now(timezone.utc))
confirmed_at: datetime | None = None
memo: str | None = Field(max_length=500)
@@ -72,7 +72,7 @@ class GovernanceParameter(SQLModel, table=True):
min_value: str | None = Field(max_length=100)
max_value: str | None = Field(max_length=100)
value_type: str = Field(max_length=20) # string, number, boolean, json
updated_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
updated_at: datetime = Field(default_factory=datetime.now(timezone.utc))
updated_by_proposal: str | None = Field(foreign_key="governanceproposal.id")
@@ -82,7 +82,7 @@ class VotingPowerSnapshot(SQLModel, table=True):
id: str = Field(default_factory=lambda: str(uuid4()), primary_key=True)
user_id: str = Field(max_length=255, index=True)
voting_power: int
snapshot_time: datetime = Field(default_factory=datetime.now(datetime.UTC), index=True)
snapshot_time: datetime = Field(default_factory=datetime.now(timezone.utc), index=True)
block_number: int | None = Field(index=True)
model_config = ConfigDict(
@@ -101,7 +101,7 @@ class ProtocolUpgrade(SQLModel, table=True):
upgrade_type: str = Field(max_length=50) # hard_fork, soft_fork, patch
activation_block: int | None
status: str = Field(default="pending", max_length=20) # pending, active, failed
created_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
created_at: datetime = Field(default_factory=datetime.now(timezone.utc))
activated_at: datetime | None = None
rollback_available: bool = Field(default=False)

View File

@@ -1,7 +1,7 @@
import json
import os
from collections import deque
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Any
from urllib import error, request
@@ -36,7 +36,7 @@ class AlertDispatcher:
try:
self._deliver(name, alert)
self._last_sent[name] = datetime.now(datetime.UTC)
self._last_sent[name] = datetime.now(timezone.utc)
results["sent"].append(name)
self._record_alert(name, alert, delivery_status="sent")
except Exception as exc:
@@ -62,7 +62,7 @@ class AlertDispatcher:
last_sent = self._last_sent.get(name)
if last_sent is None:
return False
return datetime.now(datetime.UTC) - last_sent < timedelta(seconds=self.cooldown_seconds)
return datetime.now(timezone.utc) - last_sent < timedelta(seconds=self.cooldown_seconds)
def _record_alert(
self,
@@ -71,9 +71,9 @@ class AlertDispatcher:
delivery_status: str,
error_message: str | None = None,
) -> None:
timestamp = datetime.now(datetime.UTC).isoformat()
timestamp = datetime.now(timezone.utc).isoformat()
record = {
"id": f"metrics_alert_{name}_{int(datetime.now(datetime.UTC).timestamp() * 1000)}",
"id": f"metrics_alert_{name}_{int(datetime.now(timezone.utc).timestamp() * 1000)}",
"deployment_id": None,
"severity": alert.get("status", "critical"),
"message": f"Threshold triggered for {name}",
@@ -96,7 +96,7 @@ class AlertDispatcher:
"status": alert.get("status", "critical"),
"value": alert.get("value"),
"threshold": alert.get("threshold"),
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
if webhook_url:

View File

@@ -7,7 +7,7 @@ import sys
import pytest
import asyncio
from unittest.mock import AsyncMock, patch
from datetime import datetime, UTC
from datetime import datetime, timezone
from app.agent_identity.sdk.client import AgentIdentityClient
from app.agent_identity.sdk.models import (
@@ -328,16 +328,16 @@ class TestModels:
status=IdentityStatus.ACTIVE,
verification_level=VerificationType.BASIC,
is_verified=True,
verified_at=datetime.now(datetime.UTC),
verified_at=datetime.now(timezone.utc),
supported_chains=['1', '137'],
primary_chain=1,
reputation_score=85.5,
total_transactions=100,
successful_transactions=95,
success_rate=0.95,
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC),
last_activity=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
last_activity=datetime.now(timezone.utc),
metadata={'key': 'value'},
tags=['test', 'agent']
)
@@ -358,14 +358,14 @@ class TestModels:
chain_type=ChainType.ETHEREUM,
chain_address='0x123...',
is_verified=True,
verified_at=datetime.now(datetime.UTC),
verified_at=datetime.now(timezone.utc),
wallet_address='0x456...',
wallet_type='agent-wallet',
chain_metadata={'test': 'data'},
last_transaction=datetime.now(datetime.UTC),
last_transaction=datetime.now(timezone.utc),
transaction_count=10,
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
assert mapping.id == 'mapping_123'
@@ -391,10 +391,10 @@ class TestModels:
requires_multisig=False,
multisig_threshold=1,
multisig_signers=['0x123...'],
last_transaction=datetime.now(datetime.UTC),
last_transaction=datetime.now(timezone.utc),
transaction_count=5,
created_at=datetime.now(datetime.UTC),
updated_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
assert wallet.id == 'wallet_123'

View File

@@ -7,7 +7,7 @@ import sys
import asyncio
import uuid
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from unittest.mock import MagicMock, AsyncMock, patch
from dataclasses import dataclass
@@ -51,9 +51,9 @@ class FakeQuota:
def __post_init__(self):
if self.period_start is None:
self.period_start = datetime.now(datetime.UTC) - timedelta(hours=1)
self.period_start = datetime.now(timezone.utc) - timedelta(hours=1)
if self.period_end is None:
self.period_end = datetime.now(datetime.UTC) + timedelta(hours=23)
self.period_end = datetime.now(timezone.utc) + timedelta(hours=23)
@dataclass
@@ -93,7 +93,7 @@ class InMemoryBillingStore:
return self.tenants.get(tenant_id)
def get_active_quota(self, tenant_id: str, resource_type: str):
now = datetime.now(datetime.UTC)
now = datetime.now(timezone.utc)
for q in self.quotas:
if (q.tenant_id == tenant_id
and q.resource_type == resource_type
@@ -119,7 +119,7 @@ async def apply_credit(store: InMemoryBillingStore, tenant_id: str, amount: Deci
"tenant_id": tenant_id,
"amount": amount,
"reason": reason,
"timestamp": datetime.now(datetime.UTC),
"timestamp": datetime.now(timezone.utc),
})
return True
@@ -138,7 +138,7 @@ async def apply_charge(store: InMemoryBillingStore, tenant_id: str, amount: Deci
"tenant_id": tenant_id,
"amount": amount,
"reason": reason,
"timestamp": datetime.now(datetime.UTC),
"timestamp": datetime.now(timezone.utc),
})
return True
@@ -161,7 +161,7 @@ async def adjust_quota(
async def reset_daily_quotas(store: InMemoryBillingStore) -> int:
"""Reset used_value to 0 for all daily quotas whose period has ended."""
now = datetime.now(datetime.UTC)
now = datetime.now(timezone.utc)
count = 0
for q in store.quotas:
if q.period_type == "daily" and q.is_active and q.period_end <= now:
@@ -197,7 +197,7 @@ async def generate_monthly_invoices(store: InMemoryBillingStore) -> list[str]:
if not tenant_usage:
continue
total = sum(r.total_cost for r in tenant_usage)
inv_id = f"INV-{tenant.slug}-{datetime.now(datetime.UTC).strftime('%Y%m')}-{len(generated)+1:04d}"
inv_id = f"INV-{tenant.slug}-{datetime.now(timezone.utc).strftime('%Y%m')}-{len(generated)+1:04d}"
store.invoices_generated.append(inv_id)
generated.append(inv_id)
return generated
@@ -254,8 +254,8 @@ def store():
id="q2", tenant_id="t1", resource_type="api_calls",
limit_value=Decimal("10000"), used_value=Decimal("5000"),
period_type="daily",
period_start=datetime.now(datetime.UTC) - timedelta(days=2),
period_end=datetime.now(datetime.UTC) - timedelta(hours=1), # expired
period_start=datetime.now(timezone.utc) - timedelta(days=2),
period_end=datetime.now(timezone.utc) - timedelta(hours=1), # expired
))
return s
@@ -345,7 +345,7 @@ class TestResetDailyQuotas:
assert count == 1 # q2 is expired daily
q2 = store.quotas[1]
assert q2.used_value == Decimal("0")
assert q2.period_end > datetime.now(datetime.UTC)
assert q2.period_end > datetime.now(timezone.utc)
@pytest.mark.asyncio
async def test_does_not_reset_active_quotas(self, store):

View File

@@ -5,7 +5,7 @@ Handles real exchange connections and trading operations
import asyncio
import json
from datetime import datetime, UTC
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, Any, List, Optional
import aiohttp
@@ -54,7 +54,7 @@ async def root():
return {
"service": "AITBC Exchange Integration",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -83,7 +83,7 @@ async def register_exchange(registration: ExchangeRegistration):
"sandbox": registration.sandbox,
"description": registration.description,
"connected": False,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"last_sync": None,
"trading_pairs": []
}
@@ -116,7 +116,7 @@ async def connect_exchange(exchange_id: str):
await asyncio.sleep(1) # Simulate connection delay
exchange["connected"] = True
exchange["last_sync"] = datetime.now(datetime.UTC).isoformat()
exchange["last_sync"] = datetime.now(timezone.utc).isoformat()
logger.info(f"Exchange connected: {exchange_id}")
@@ -144,7 +144,7 @@ async def create_trading_pair(pair: TradingPair):
"price_precision": pair.price_precision,
"quantity_precision": pair.quantity_precision,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"current_price": None,
"volume_24h": 0.0,
"orders": []
@@ -186,7 +186,7 @@ async def create_order(order: OrderRequest):
raise HTTPException(status_code=404, detail="Trading pair not found")
# Generate order ID
order_id = f"order_{int(datetime.now(datetime.UTC).timestamp())}"
order_id = f"order_{int(datetime.now(timezone.utc).timestamp())}"
# Create order
order_data = {
@@ -197,7 +197,7 @@ async def create_order(order: OrderRequest):
"quantity": order.quantity,
"price": order.price,
"status": "submitted",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"filled_quantity": 0.0,
"remaining_quantity": order.quantity,
"average_price": None
@@ -216,7 +216,7 @@ async def create_order(order: OrderRequest):
order_data["filled_quantity"] = order.quantity
order_data["remaining_quantity"] = 0.0
order_data["average_price"] = order.price or 0.00001 # Default price for demo
order_data["filled_at"] = datetime.now(datetime.UTC).isoformat()
order_data["filled_at"] = datetime.now(timezone.utc).isoformat()
logger.info(f"Order created and filled: {order_id}")
@@ -263,7 +263,7 @@ async def update_market_price(pair_id: str, price_data: Dict[str, Any]):
pair = trading_pairs[pair_id]
pair["current_price"] = price_data.get("price")
pair["volume_24h"] = price_data.get("volume", pair["volume_24h"])
pair["last_price_update"] = datetime.now(datetime.UTC).isoformat()
pair["last_price_update"] = datetime.now(timezone.utc).isoformat()
return {
"pair_id": pair_id,
@@ -286,7 +286,7 @@ async def get_market_data():
return {
"market_data": market_data,
"total_pairs": len(market_data),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Background task for simulating market data
@@ -305,7 +305,7 @@ async def simulate_market_data():
pair["current_price"] = new_price
pair["volume_24h"] += random.uniform(100, 1000)
pair["last_price_update"] = datetime.now(datetime.UTC).isoformat()
pair["last_price_update"] = datetime.now(timezone.utc).isoformat()
# Start background task on startup
@app.on_event("startup")

View File

@@ -3,7 +3,7 @@
FastAPI backend for the AITBC Trade Exchange
"""
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import List, Optional
from fastapi import FastAPI, Depends, HTTPException, status, Header
from fastapi.middleware.cors import CORSMiddleware
@@ -123,7 +123,7 @@ def create_mock_trades(db: Session):
import random
# Create mock trades over the last hour
now = datetime.now(datetime.UTC)
now = datetime.now(timezone.utc)
trades = []
for i in range(20):
@@ -278,7 +278,7 @@ def try_match_order(order: Order, db: Session):
amount=trade_amount,
price=match.price,
total=trade_total,
trade_hash=f"trade_{datetime.now(datetime.UTC).timestamp()}"
trade_hash=f"trade_{datetime.now(timezone.utc).timestamp()}"
)
db.add(trade)
@@ -344,7 +344,7 @@ def logout_user(token: str = Header(..., alias="Authorization")):
@app.get("/api/health")
def health_check():
"""Health check endpoint"""
return {"status": "ok", "timestamp": datetime.now(datetime.UTC)}
return {"status": "ok", "timestamp": datetime.now(timezone.utc)}
if __name__ == "__main__":
import uvicorn

View File

@@ -22,7 +22,7 @@ class User(Base):
password_hash = Column(String(255), nullable=False)
bitcoin_address = Column(String(100), unique=True, nullable=False)
aitbc_address = Column(String(100), unique=True, nullable=False)
created_at = Column(DateTime, default=datetime.now(datetime.UTC))
created_at = Column(DateTime, default=datetime.now(timezone.utc))
is_active = Column(Boolean, default=True)
# Relationships
@@ -46,8 +46,8 @@ class Order(Base):
filled = Column(Float, default=0.0) # Amount filled
remaining = Column(Float, nullable=False) # Amount remaining to fill
status = Column(String(20), default='OPEN') # OPEN, PARTIALLY_FILLED, FILLED, CANCELLED
created_at = Column(DateTime, default=datetime.now(datetime.UTC))
updated_at = Column(DateTime, default=datetime.now(datetime.UTC), onupdate=datetime.now(datetime.UTC))
created_at = Column(DateTime, default=datetime.now(timezone.utc))
updated_at = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
# Relationships
user = relationship("User", back_populates="orders")
@@ -74,7 +74,7 @@ class Trade(Base):
price = Column(Float, nullable=False) # Trade price in BTC
total = Column(Float, nullable=False) # Total value in BTC
trade_hash = Column(String(100), unique=True, nullable=False) # Blockchain transaction hash
created_at = Column(DateTime, default=datetime.now(datetime.UTC))
created_at = Column(DateTime, default=datetime.now(timezone.utc))
# Relationships
buyer = relationship("User", back_populates="trades", foreign_keys=[buyer_id])
@@ -100,7 +100,7 @@ class Balance(Base):
aitbc_balance = Column(Float, default=0.0)
btc_locked = Column(Float, default=0.0) # Locked in open orders
aitbc_locked = Column(Float, default=0.0) # Locked in open orders
updated_at = Column(DateTime, default=datetime.now(datetime.UTC), onupdate=datetime.now(datetime.UTC))
updated_at = Column(DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc))
# Relationship
user = relationship("User")

View File

@@ -8,7 +8,7 @@ import asyncio
import ccxt
import json
import time
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Dict, List, Optional, Any, Tuple
from dataclasses import dataclass
from enum import Enum
@@ -105,7 +105,7 @@ class RealExchangeManager:
self.health_status[exchange_name] = ExchangeHealth(
status=ExchangeStatus.CONNECTED,
latency_ms=0.0,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
logger.info(f"✅ Connected to {exchange_name}")
@@ -116,7 +116,7 @@ class RealExchangeManager:
self.health_status[exchange_name] = ExchangeHealth(
status=ExchangeStatus.ERROR,
latency_ms=0.0,
last_check=datetime.now(datetime.UTC),
last_check=datetime.now(timezone.utc),
error_message=str(e)
)
return False

View File

@@ -2,7 +2,7 @@
"""Seed initial market price for the exchange"""
import sqlite3
from datetime import datetime, UTC
from datetime import datetime, timezone
from aitbc.constants import DATA_DIR
def seed_initial_price():
@@ -27,7 +27,7 @@ def seed_initial_price():
cursor.execute('''
INSERT INTO trades (amount, price, total, created_at)
VALUES (?, ?, ?, ?)
''', (amount, price, total, datetime.now(datetime.UTC)))
''', (amount, price, total, datetime.now(timezone.utc)))
# Also create some initial orders for liquidity
initial_orders = [

View File

@@ -5,7 +5,7 @@ Simple FastAPI backend for the AITBC Trade Exchange (Python 3.13 compatible)
import sqlite3
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from http.server import HTTPServer, BaseHTTPRequestHandler
import urllib.parse
import random

View File

@@ -7,7 +7,7 @@ import json
import urllib.request
import psycopg2
from psycopg2.extras import RealDictCursor
from datetime import datetime, UTC
from datetime import datetime, timezone
from decimal import Decimal
import random
@@ -151,7 +151,7 @@ class ExchangeAPIHandler(BaseHTTPRequestHandler):
self.send_json_response({
'status': 'ok',
'database': 'postgresql',
'timestamp': datetime.now(datetime.UTC).isoformat()
'timestamp': datetime.now(timezone.utc).isoformat()
})
except Exception as e:
self.send_json_response({

View File

@@ -7,7 +7,7 @@ from pathlib import Path
from exchange_api import OrderCreate, OrderResponse, TradeResponse, OrderBookResponse
from datetime import datetime, UTC
from datetime import datetime, timezone
@pytest.mark.unit
@@ -55,7 +55,7 @@ def test_order_response_zero_remaining():
filled=100.0,
remaining=0.0,
status="FILLED",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
assert order.remaining == 0.0
assert order.status == "FILLED"
@@ -73,7 +73,7 @@ def test_order_response_empty_status():
filled=0.0,
remaining=100.0,
status="",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
assert order.status == ""
@@ -86,7 +86,7 @@ def test_trade_response_zero_amount():
amount=0.0,
price=0.00001,
total=0.0,
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
assert trade.amount == 0.0
assert trade.total == 0.0
@@ -103,7 +103,7 @@ def test_order_book_empty_buys():
@pytest.mark.unit
def test_order_book_empty_sells():
"""Test OrderBookResponse with empty sells"""
from datetime import datetime, UTC
from datetime import datetime, timezone
buy_order = OrderResponse(
id=1,
order_type="BUY",
@@ -113,7 +113,7 @@ def test_order_book_empty_sells():
filled=0.0,
remaining=100.0,
status="OPEN",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
orderbook = OrderBookResponse(buys=[buy_order], sells=[])
assert len(orderbook.buys) == 1

View File

@@ -45,7 +45,7 @@ def test_order_create_model_sell():
@pytest.mark.unit
def test_order_response_model():
"""Test OrderResponse model"""
from datetime import datetime, UTC
from datetime import datetime, timezone
order = OrderResponse(
id=1,
order_type="BUY",
@@ -55,7 +55,7 @@ def test_order_response_model():
filled=0.0,
remaining=100.0,
status="OPEN",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
assert order.id == 1
assert order.order_type == "BUY"
@@ -66,13 +66,13 @@ def test_order_response_model():
@pytest.mark.unit
def test_trade_response_model():
"""Test TradeResponse model"""
from datetime import datetime, UTC
from datetime import datetime, timezone
trade = TradeResponse(
id=1,
amount=50.0,
price=0.00001,
total=0.0005,
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
assert trade.id == 1
assert trade.amount == 50.0
@@ -82,7 +82,7 @@ def test_trade_response_model():
@pytest.mark.unit
def test_order_book_response_model():
"""Test OrderBookResponse model"""
from datetime import datetime, UTC
from datetime import datetime, timezone
buy_order = OrderResponse(
id=1,
order_type="BUY",
@@ -92,7 +92,7 @@ def test_order_book_response_model():
filled=0.0,
remaining=100.0,
status="OPEN",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
sell_order = OrderResponse(
id=2,
@@ -103,7 +103,7 @@ def test_order_book_response_model():
filled=0.0,
remaining=50.0,
status="OPEN",
created_at=datetime.now(datetime.UTC)
created_at=datetime.now(timezone.utc)
)
orderbook = OrderBookResponse(buys=[buy_order], sells=[sell_order])
assert len(orderbook.buys) == 1

View File

@@ -5,7 +5,7 @@ Handles cross-chain and cross-region AI agent communication with global optimiza
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
@@ -74,7 +74,7 @@ async def root():
return {
"service": "AITBC Global AI Agent Communication Service",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -105,8 +105,8 @@ async def register_agent(agent: Agent):
"languages": agent.languages,
"specialization": agent.specialization,
"performance_score": agent.performance_score,
"created_at": datetime.now(datetime.UTC).isoformat(),
"last_active": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"last_active": datetime.now(timezone.utc).isoformat(),
"total_messages_sent": 0,
"total_messages_received": 0,
"collaborations_participated": 0,
@@ -188,7 +188,7 @@ async def send_message(message: AgentMessage):
"timestamp": message.timestamp.isoformat(),
"encryption_key": message.encryption_key,
"status": "delivered",
"delivered_at": datetime.now(datetime.UTC).isoformat(),
"delivered_at": datetime.now(timezone.utc).isoformat(),
"read_at": None
}
@@ -285,16 +285,16 @@ async def create_collaboration(session: CollaborationSession):
for participant_id in session.participants:
message_record = {
"message_id": f"collab_{int(datetime.now(datetime.UTC).timestamp())}",
"message_id": f"collab_{int(datetime.now(timezone.utc).timestamp())}",
"sender_id": "system",
"recipient_id": participant_id,
"message_type": "notification",
"content": notification,
"priority": "medium",
"language": "english",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"status": "delivered",
"delivered_at": datetime.now(datetime.UTC).isoformat()
"delivered_at": datetime.now(timezone.utc).isoformat()
}
if participant_id not in agent_messages:
@@ -330,11 +330,11 @@ async def send_collaboration_message(session_id: str, sender_id: str, content: D
# Create collaboration message
message_record = {
"message_id": f"collab_msg_{int(datetime.now(datetime.UTC).timestamp())}",
"message_id": f"collab_msg_{int(datetime.now(timezone.utc).timestamp())}",
"sender_id": sender_id,
"session_id": session_id,
"content": content,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"type": "collaboration_message"
}
@@ -351,16 +351,16 @@ async def send_collaboration_message(session_id: str, sender_id: str, content: D
}
msg_record = {
"message_id": f"notif_{int(datetime.now(datetime.UTC).timestamp())}",
"message_id": f"notif_{int(datetime.now(timezone.utc).timestamp())}",
"sender_id": "system",
"recipient_id": participant_id,
"message_type": "notification",
"content": notification,
"priority": "medium",
"language": "english",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"status": "delivered",
"delivered_at": datetime.now(datetime.UTC).isoformat()
"delivered_at": datetime.now(timezone.utc).isoformat()
}
if participant_id not in agent_messages:
@@ -381,7 +381,7 @@ async def record_agent_performance(performance: AgentPerformance):
# Create performance record
performance_record = {
"performance_id": f"perf_{int(datetime.now(datetime.UTC).timestamp())}",
"performance_id": f"perf_{int(datetime.now(timezone.utc).timestamp())}",
"agent_id": performance.agent_id,
"timestamp": performance.timestamp.isoformat(),
"tasks_completed": performance.tasks_completed,
@@ -421,7 +421,7 @@ async def get_agent_performance(agent_id: str, hours: int = 24):
if agent_id not in global_agents:
raise HTTPException(status_code=404, detail="Agent not found")
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
performance_records = agent_performance.get(agent_id, [])
recent_performance = [
p for p in performance_records
@@ -448,7 +448,7 @@ async def get_agent_performance(agent_id: str, hours: int = 24):
"total_tasks_completed": int(total_tasks),
"total_records": len(recent_performance)
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/network/dashboard")
@@ -476,7 +476,7 @@ async def get_network_dashboard():
# Recent activity
recent_messages = 0
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=1)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=1)
for messages in agent_messages.values():
recent_messages += len([m for m in messages if datetime.fromisoformat(m["timestamp"]) > cutoff_time])
@@ -503,7 +503,7 @@ async def get_network_dashboard():
"total_tasks_completed": sum(a["tasks_completed"] for a in global_agents.values())
}
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/network/optimize")
@@ -554,7 +554,7 @@ async def optimize_network():
return {
"optimization_results": optimization_results,
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Background task for network monitoring
@@ -564,12 +564,12 @@ async def network_monitoring_task():
await asyncio.sleep(300) # Monitor every 5 minutes
# Update network statistics
global_network_stats["last_update"] = datetime.now(datetime.UTC).isoformat()
global_network_stats["last_update"] = datetime.now(timezone.utc).isoformat()
global_network_stats["total_agents"] = len(global_agents)
global_network_stats["active_agents"] = len([a for a in global_agents.values() if a["status"] == "active"])
# Check for expired collaboration sessions
current_time = datetime.now(datetime.UTC)
current_time = datetime.now(timezone.utc)
for session_id, session in collaboration_sessions.items():
if datetime.fromisoformat(session["expires_at"]) < current_time and session["status"] == "active":
session["status"] = "expired"
@@ -637,8 +637,8 @@ async def startup_event():
"languages": agent.languages,
"specialization": agent.specialization,
"performance_score": agent.performance_score,
"created_at": datetime.now(datetime.UTC).isoformat(),
"last_active": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"last_active": datetime.now(timezone.utc).isoformat(),
"total_messages_sent": 0,
"total_messages_received": 0,
"collaborations_participated": 0,

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from main import app, Agent, AgentMessage, CollaborationSession, AgentPerformance, global_agents, agent_messages, collaboration_sessions, agent_performance
@@ -64,7 +64,7 @@ def test_agent_performance_out_of_range_score():
"""Test AgentPerformance with out of range scores"""
performance = AgentPerformance(
agent_id="agent_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tasks_completed=10,
response_time_ms=50.5,
accuracy_score=2.0,
@@ -86,7 +86,7 @@ def test_agent_message_empty_content():
content={},
priority="high",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert message.content == {}
@@ -148,8 +148,8 @@ def test_send_collaboration_message_sender_not_participant():
participants=["agent_123"],
session_type="research",
objective="Research task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC) + timedelta(hours=1),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
status="active"
)
client.post("/api/v1/collaborations/create", json=session.model_dump(mode='json'))

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from main import app, Agent, AgentMessage, CollaborationSession, AgentPerformance, global_agents, agent_messages, collaboration_sessions, agent_performance
@@ -194,7 +194,7 @@ def test_send_direct_message():
content={"data": "test"},
priority="high",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/messages/send", json=message.model_dump(mode='json'))
assert response.status_code == 200
@@ -241,7 +241,7 @@ def test_send_broadcast_message():
content={"data": "test"},
priority="medium",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/messages/send", json=message.model_dump(mode='json'))
assert response.status_code == 200
@@ -261,7 +261,7 @@ def test_send_message_sender_not_found():
content={"data": "test"},
priority="high",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/messages/send", json=message.model_dump(mode='json'))
assert response.status_code == 400
@@ -292,7 +292,7 @@ def test_send_message_recipient_not_found():
content={"data": "test"},
priority="high",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/messages/send", json=message.model_dump(mode='json'))
assert response.status_code == 400
@@ -377,8 +377,8 @@ def test_create_collaboration():
participants=["agent_123", "agent_456"],
session_type="task_force",
objective="Complete task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC) + timedelta(hours=1),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
status="active"
)
response = client.post("/api/v1/collaborations/create", json=session.model_dump(mode='json'))
@@ -396,8 +396,8 @@ def test_create_collaboration_participant_not_found():
participants=["nonexistent"],
session_type="task_force",
objective="Complete task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC) + timedelta(hours=1),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
status="active"
)
response = client.post("/api/v1/collaborations/create", json=session.model_dump(mode='json'))
@@ -427,8 +427,8 @@ def test_get_collaboration():
participants=["agent_123"],
session_type="research",
objective="Research task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC) + timedelta(hours=1),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
status="active"
)
client.post("/api/v1/collaborations/create", json=session.model_dump(mode='json'))
@@ -462,8 +462,8 @@ def test_send_collaboration_message():
participants=["agent_123"],
session_type="research",
objective="Research task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC) + timedelta(hours=1),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc) + timedelta(hours=1),
status="active"
)
client.post("/api/v1/collaborations/create", json=session.model_dump(mode='json'))
@@ -493,7 +493,7 @@ def test_record_agent_performance():
performance = AgentPerformance(
agent_id="agent_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tasks_completed=10,
response_time_ms=50.5,
accuracy_score=0.95,
@@ -513,7 +513,7 @@ def test_record_performance_agent_not_found():
client = TestClient(app)
performance = AgentPerformance(
agent_id="nonexistent",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tasks_completed=10,
response_time_ms=50.5,
accuracy_score=0.95,

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, Agent, AgentMessage, CollaborationSession, AgentPerformance
@@ -67,7 +67,7 @@ def test_agent_message_model():
content={"data": "test"},
priority="high",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert message.message_id == "msg_123"
assert message.sender_id == "agent_123"
@@ -87,7 +87,7 @@ def test_agent_message_broadcast():
content={"data": "test"},
priority="medium",
language="english",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert message.recipient_id is None
@@ -100,8 +100,8 @@ def test_collaboration_session_model():
participants=["agent_123", "agent_456"],
session_type="task_force",
objective="Complete trading task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc),
status="active"
)
assert session.session_id == "session_123"
@@ -117,8 +117,8 @@ def test_collaboration_session_empty_participants():
participants=[],
session_type="research",
objective="Research task",
created_at=datetime.now(datetime.UTC),
expires_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
expires_at=datetime.now(timezone.utc),
status="active"
)
assert session.participants == []
@@ -129,7 +129,7 @@ def test_agent_performance_model():
"""Test AgentPerformance model"""
performance = AgentPerformance(
agent_id="agent_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tasks_completed=10,
response_time_ms=50.5,
accuracy_score=0.95,
@@ -147,7 +147,7 @@ def test_agent_performance_negative_values():
"""Test AgentPerformance with negative values"""
performance = AgentPerformance(
agent_id="agent_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
tasks_completed=-10,
response_time_ms=-50.5,
accuracy_score=-0.95,

View File

@@ -5,7 +5,7 @@ Handles multi-region deployment, load balancing, and global optimization
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
@@ -72,7 +72,7 @@ async def root():
return {
"service": "AITBC Global Infrastructure Service",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -103,7 +103,7 @@ async def register_region(region: Region):
"current_load": region.current_load,
"latency_ms": region.latency_ms,
"compliance_level": region.compliance_level,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"last_health_check": None,
"services_deployed": [],
"performance_history": []
@@ -148,7 +148,7 @@ async def get_region(region_id: str):
@app.post("/api/v1/deployments/create")
async def create_deployment(deployment: GlobalDeployment):
"""Create a new global deployment"""
deployment_id = f"deploy_{int(datetime.now(datetime.UTC).timestamp())}"
deployment_id = f"deploy_{int(datetime.now(timezone.utc).timestamp())}"
# Validate target regions
for region_id in deployment.target_regions:
@@ -164,7 +164,7 @@ async def create_deployment(deployment: GlobalDeployment):
"deployment_strategy": deployment.deployment_strategy,
"health_checks": deployment.health_checks,
"status": "pending",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"started_at": None,
"completed_at": None,
"deployment_progress": {},
@@ -214,7 +214,7 @@ async def list_deployments(status: Optional[str] = None):
@app.post("/api/v1/load-balancers/create")
async def create_load_balancer(balancer: LoadBalancer):
"""Create a new load balancer"""
balancer_id = f"lb_{int(datetime.now(datetime.UTC).timestamp())}"
balancer_id = f"lb_{int(datetime.now(timezone.utc).timestamp())}"
# Validate target regions
for region_id in balancer.target_regions:
@@ -230,7 +230,7 @@ async def create_load_balancer(balancer: LoadBalancer):
"health_check_interval": balancer.health_check_interval,
"failover_threshold": balancer.failover_threshold,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"current_weights": {region_id: 1.0 for region_id in balancer.target_regions},
"health_status": {region_id: "healthy" for region_id in balancer.target_regions},
"total_requests": 0,
@@ -265,7 +265,7 @@ async def list_load_balancers():
async def record_performance_metrics(metrics: PerformanceMetrics):
"""Record performance metrics for a region"""
metrics_record = {
"metrics_id": f"metrics_{int(datetime.now(datetime.UTC).timestamp())}",
"metrics_id": f"metrics_{int(datetime.now(timezone.utc).timestamp())}",
"region_id": metrics.region_id,
"timestamp": metrics.timestamp.isoformat(),
"cpu_usage": metrics.cpu_usage,
@@ -310,7 +310,7 @@ async def get_region_performance(region_id: str, hours: int = 24):
if region_id not in performance_metrics:
raise HTTPException(status_code=404, detail="No performance data for region")
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
recent_metrics = [
m for m in performance_metrics[region_id]
if datetime.fromisoformat(m["timestamp"]) > cutoff_time
@@ -334,7 +334,7 @@ async def get_region_performance(region_id: str, hours: int = 24):
"average_response_time_ms": round(avg_response_time, 2),
"total_samples": len(recent_metrics)
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/compliance/{region_id}")
@@ -350,8 +350,8 @@ async def get_region_compliance(region_id: str):
"compliance_level": global_regions[region_id]["compliance_level"],
"certifications": ["SOC2", "ISO27001", "GDPR"],
"data_residency": "compliant",
"last_audit": (datetime.now(datetime.UTC) - timedelta(days=90)).isoformat(),
"next_audit": (datetime.now(datetime.UTC) + timedelta(days=275)).isoformat(),
"last_audit": (datetime.now(timezone.utc) - timedelta(days=90)).isoformat(),
"next_audit": (datetime.now(timezone.utc) + timedelta(days=275)).isoformat(),
"regulations": ["GDPR", "CCPA", "PDPA"],
"data_protection": "end-to-end-encryption",
"access_controls": "role-based-access",
@@ -410,7 +410,7 @@ async def get_global_dashboard():
"partial_compliance": len([r for r in global_regions.values() if r["compliance_level"] == "partial"])
}
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Core deployment and load balancing functions
@@ -418,13 +418,13 @@ async def execute_deployment(deployment_id: str):
"""Execute a global deployment"""
deployment = deployments[deployment_id]
deployment["status"] = "in_progress"
deployment["started_at"] = datetime.now(datetime.UTC).isoformat()
deployment["started_at"] = datetime.now(timezone.utc).isoformat()
try:
for region_id in deployment["target_regions"]:
deployment["deployment_progress"][region_id] = {
"status": "deploying",
"started_at": datetime.now(datetime.UTC).isoformat(),
"started_at": datetime.now(timezone.utc).isoformat(),
"progress": 0
}
@@ -433,7 +433,7 @@ async def execute_deployment(deployment_id: str):
deployment["deployment_progress"][region_id].update({
"status": "completed",
"completed_at": datetime.now(datetime.UTC).isoformat(),
"completed_at": datetime.now(timezone.utc).isoformat(),
"progress": 100
})
@@ -443,7 +443,7 @@ async def execute_deployment(deployment_id: str):
global_regions[region_id]["services_deployed"].append(deployment["service_name"])
deployment["status"] = "completed"
deployment["completed_at"] = datetime.now(datetime.UTC).isoformat()
deployment["completed_at"] = datetime.now(timezone.utc).isoformat()
logger.info(f"Deployment completed: {deployment_id}")
@@ -516,7 +516,7 @@ async def global_monitoring_task():
await asyncio.sleep(60) # Monitor every minute
# Update global monitoring data
global_monitoring["last_update"] = datetime.now(datetime.UTC).isoformat()
global_monitoring["last_update"] = datetime.now(timezone.utc).isoformat()
global_monitoring["total_requests"] = sum(lb.get("total_requests", 0) for lb in load_balancers.values())
global_monitoring["failed_requests"] = sum(lb.get("failed_requests", 0) for lb in load_balancers.values())
@@ -582,7 +582,7 @@ async def startup_event():
"current_load": region.current_load,
"latency_ms": region.latency_ms,
"compliance_level": region.compliance_level,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"last_health_check": None,
"services_deployed": [],
"performance_history": []

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, Region, GlobalDeployment, LoadBalancer, PerformanceMetrics, global_regions, deployments, load_balancers, performance_metrics
@@ -93,7 +93,7 @@ def test_performance_metrics_negative_values():
"""Test PerformanceMetrics with negative values"""
metrics = PerformanceMetrics(
region_id="us-east-1",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
cpu_usage=-50.5,
memory_usage=-60.2,
network_io=-1000.5,

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, Region, GlobalDeployment, LoadBalancer, PerformanceMetrics, global_regions, deployments, load_balancers, performance_metrics
@@ -278,7 +278,7 @@ def test_record_performance_metrics():
client = TestClient(app)
metrics = PerformanceMetrics(
region_id="us-west-1",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
cpu_usage=50.5,
memory_usage=60.2,
network_io=1000.5,
@@ -300,7 +300,7 @@ def test_get_region_performance():
# Record metrics first
metrics = PerformanceMetrics(
region_id="us-west-1",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
cpu_usage=50.5,
memory_usage=60.2,
network_io=1000.5,

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, Region, GlobalDeployment, LoadBalancer, PerformanceMetrics
@@ -78,7 +78,7 @@ def test_performance_metrics_model():
"""Test PerformanceMetrics model"""
metrics = PerformanceMetrics(
region_id="us-east-1",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
cpu_usage=50.5,
memory_usage=60.2,
network_io=1000.5,

View File

@@ -8,7 +8,7 @@ import time
import sys
import subprocess
import os
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, Optional
from aitbc import get_logger, AITBCHTTPClient, NetworkError
@@ -216,7 +216,7 @@ def send_heartbeat():
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.now(datetime.UTC).isoformat(),
"last_seen": datetime.now(timezone.utc).isoformat(),
"gpu_utilization": gpu_info["utilization"],
"memory_used": gpu_info["memory_used"],
"memory_total": gpu_info["memory_total"],
@@ -228,7 +228,7 @@ def send_heartbeat():
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.now(datetime.UTC).isoformat(),
"last_seen": datetime.now(timezone.utc).isoformat(),
"gpu_utilization": 0,
"memory_used": 0,
"memory_total": 0,

View File

@@ -8,7 +8,7 @@ import time
import sys
import subprocess
import os
from datetime import datetime, UTC
from datetime import datetime, timezone
from typing import Dict, Optional
from aitbc import get_logger, AITBCHTTPClient, NetworkError, LOG_DIR
@@ -209,7 +209,7 @@ def send_heartbeat():
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.now(datetime.UTC).isoformat(),
"last_seen": datetime.now(timezone.utc).isoformat(),
"gpu_utilization": gpu_info["utilization"],
"memory_used": gpu_info["memory_used"],
"memory_total": gpu_info["memory_total"],
@@ -221,7 +221,7 @@ def send_heartbeat():
heartbeat_data = {
"status": "active",
"current_jobs": 0,
"last_seen": datetime.now(datetime.UTC).isoformat(),
"last_seen": datetime.now(timezone.utc).isoformat(),
"gpu_utilization": 0,
"memory_used": 0,
"memory_total": 0,

View File

@@ -5,7 +5,7 @@ Handles intelligent load distribution across global regions
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
@@ -68,7 +68,7 @@ async def root():
return {
"service": "AITBC Multi-Region Load Balancer",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -99,10 +99,10 @@ async def create_load_balancing_rule(rule: LoadBalancingRule):
"failover_enabled": rule.failover_enabled,
"session_affinity": rule.session_affinity,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"total_requests": 0,
"failed_requests": 0,
"last_updated": datetime.now(datetime.UTC).isoformat()
"last_updated": datetime.now(timezone.utc).isoformat()
}
load_balancing_rules[rule.rule_id] = rule_record
@@ -167,7 +167,7 @@ async def update_rule_weights(rule_id: str, weights: Dict[str, float]):
# Update rule weights
rule["weights"] = normalized_weights
rule["last_updated"] = datetime.now(datetime.UTC).isoformat()
rule["last_updated"] = datetime.now(timezone.utc).isoformat()
logger.info(f"Weights updated for rule {rule_id}: {normalized_weights}")
@@ -193,7 +193,7 @@ async def register_region_health(health: RegionHealth):
return {
"region_id": health.region_id,
"status": health.status,
"registered_at": datetime.now(datetime.UTC).isoformat()
"registered_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/health")
@@ -224,7 +224,7 @@ async def create_geographic_rule(rule: GeographicRule):
"priority": rule.priority,
"latency_threshold_ms": rule.latency_threshold_ms,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"usage_count": 0
}
@@ -256,14 +256,14 @@ async def get_optimal_region(client_region: str, rule_id: Optional[str] = None):
"optimal_region": optimal_region,
"rule_id": rule_id,
"selection_reason": get_selection_reason(optimal_region, client_region, rule_id),
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
@app.post("/api/v1/metrics/record")
async def record_balancing_metrics(metrics: LoadBalancingMetrics):
"""Record load balancing performance metrics"""
metrics_record = {
"metrics_id": f"metrics_{int(datetime.now(datetime.UTC).timestamp())}",
"metrics_id": f"metrics_{int(datetime.now(timezone.utc).timestamp())}",
"balancer_id": metrics.balancer_id,
"timestamp": metrics.timestamp.isoformat(),
"total_requests": metrics.total_requests,
@@ -294,7 +294,7 @@ async def get_balancing_metrics(rule_id: str, hours: int = 24):
if rule_id not in load_balancing_rules:
raise HTTPException(status_code=404, detail="Load balancing rule not found")
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
recent_metrics = [
m for m in balancing_metrics.get(rule_id, [])
if datetime.fromisoformat(m["timestamp"]) > cutoff_time
@@ -320,7 +320,7 @@ async def get_balancing_metrics(rule_id: str, hours: int = 24):
"total_requests": int(total_requests),
"total_samples": len(recent_metrics)
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/dashboard")
@@ -368,7 +368,7 @@ async def get_load_balancing_dashboard():
"performance": performance_summary,
"recent_activity": get_recent_activity()
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Core load balancing functions
@@ -534,7 +534,7 @@ def get_recent_activity() -> List[Dict]:
# Recent health changes
for region_id, health in region_health_status.items():
if (datetime.now(datetime.UTC) - health.last_check).total_seconds() < 3600: # Last hour
if (datetime.now(timezone.utc) - health.last_check).total_seconds() < 3600: # Last hour
activity.append({
"type": "health_check",
"region": region_id,
@@ -544,7 +544,7 @@ def get_recent_activity() -> List[Dict]:
# Recent rule updates
for rule_id, rule in load_balancing_rules.items():
if (datetime.now(datetime.UTC) - datetime.fromisoformat(rule["last_updated"])).total_seconds() < 3600:
if (datetime.now(timezone.utc) - datetime.fromisoformat(rule["last_updated"])).total_seconds() < 3600:
activity.append({
"type": "rule_update",
"rule_id": rule_id,
@@ -598,7 +598,7 @@ async def check_region_health(region_id: str):
response_time_ms=response_time,
success_rate=success_rate,
active_connections=active_connections,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
region_health_status[region_id] = health
@@ -644,10 +644,10 @@ async def startup_event():
"failover_enabled": rule.failover_enabled,
"session_affinity": rule.session_affinity,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"total_requests": 0,
"failed_requests": 0,
"last_updated": datetime.now(datetime.UTC).isoformat()
"last_updated": datetime.now(timezone.utc).isoformat()
}
load_balancing_rules[rule.rule_id] = rule_record
@@ -681,7 +681,7 @@ async def startup_event():
"priority": geo_rule.priority,
"latency_threshold_ms": geo_rule.latency_threshold_ms,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"usage_count": 0
}
geographic_rules[geo_rule.rule_id] = geo_rule_record

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, LoadBalancingRule, RegionHealth, LoadBalancingMetrics, GeographicRule, load_balancing_rules, region_health_status, balancing_metrics, geographic_rules
@@ -50,7 +50,7 @@ def test_region_health_negative_success_rate():
response_time_ms=45.5,
success_rate=-0.5,
active_connections=100,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
assert health.success_rate == -0.5
@@ -64,7 +64,7 @@ def test_region_health_negative_connections():
response_time_ms=45.5,
success_rate=0.99,
active_connections=-100,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
assert health.active_connections == -100
@@ -74,7 +74,7 @@ def test_load_balancing_metrics_negative_requests():
"""Test LoadBalancingMetrics with negative requests"""
metrics = LoadBalancingMetrics(
balancer_id="lb_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
total_requests=-1000,
requests_per_region={},
average_response_time=50.5,
@@ -89,7 +89,7 @@ def test_load_balancing_metrics_negative_response_time():
"""Test LoadBalancingMetrics with negative response time"""
metrics = LoadBalancingMetrics(
balancer_id="lb_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
total_requests=1000,
requests_per_region={},
average_response_time=-50.5,

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, LoadBalancingRule, RegionHealth, LoadBalancingMetrics, GeographicRule, load_balancing_rules, region_health_status, balancing_metrics, geographic_rules
@@ -193,7 +193,7 @@ def test_register_region_health():
response_time_ms=45.5,
success_rate=0.99,
active_connections=100,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
response = client.post("/api/v1/health/register", json=health.model_dump(mode='json'))
assert response.status_code == 200
@@ -286,7 +286,7 @@ def test_record_balancing_metrics():
client = TestClient(app)
metrics = LoadBalancingMetrics(
balancer_id="lb_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
total_requests=1000,
requests_per_region={"us-east-1": 500},
average_response_time=50.5,

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, LoadBalancingRule, RegionHealth, LoadBalancingMetrics, GeographicRule
@@ -47,7 +47,7 @@ def test_region_health_model():
response_time_ms=45.5,
success_rate=0.99,
active_connections=100,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
assert health.region_id == "us-east-1"
assert health.status == "healthy"
@@ -61,7 +61,7 @@ def test_load_balancing_metrics_model():
"""Test LoadBalancingMetrics model"""
metrics = LoadBalancingMetrics(
balancer_id="lb_123",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
total_requests=1000,
requests_per_region={"us-east-1": 500, "eu-west-1": 500},
average_response_time=50.5,
@@ -115,6 +115,6 @@ def test_region_health_negative_response_time():
response_time_ms=-45.5,
success_rate=0.99,
active_connections=100,
last_check=datetime.now(datetime.UTC)
last_check=datetime.now(timezone.utc)
)
assert health.response_time_ms == -45.5

View File

@@ -5,7 +5,7 @@ Handles plugin analytics, usage tracking, and performance monitoring
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException
@@ -66,7 +66,7 @@ async def root():
return {
"service": "AITBC Plugin Analytics Service",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -85,7 +85,7 @@ async def health_check():
async def record_plugin_usage(usage: PluginUsage):
"""Record plugin usage event"""
usage_record = {
"usage_id": f"usage_{int(datetime.now(datetime.UTC).timestamp())}",
"usage_id": f"usage_{int(datetime.now(timezone.utc).timestamp())}",
"plugin_id": usage.plugin_id,
"user_id": usage.user_id,
"action": usage.action,
@@ -113,7 +113,7 @@ async def record_plugin_usage(usage: PluginUsage):
async def record_plugin_performance(performance: PluginPerformance):
"""Record plugin performance metrics"""
performance_record = {
"performance_id": f"perf_{int(datetime.now(datetime.UTC).timestamp())}",
"performance_id": f"perf_{int(datetime.now(timezone.utc).timestamp())}",
"plugin_id": performance.plugin_id,
"version": performance.version,
"cpu_usage": performance.cpu_usage,
@@ -141,7 +141,7 @@ async def record_plugin_performance(performance: PluginPerformance):
async def record_plugin_rating(rating: PluginRating):
"""Record plugin rating and review"""
rating_record = {
"rating_id": f"rating_{int(datetime.now(datetime.UTC).timestamp())}",
"rating_id": f"rating_{int(datetime.now(timezone.utc).timestamp())}",
"plugin_id": rating.plugin_id,
"user_id": rating.user_id,
"rating": rating.rating,
@@ -166,7 +166,7 @@ async def record_plugin_rating(rating: PluginRating):
async def record_plugin_event(event: PluginEvent):
"""Record generic plugin event"""
event_record = {
"event_id": f"event_{int(datetime.now(datetime.UTC).timestamp())}",
"event_id": f"event_{int(datetime.now(timezone.utc).timestamp())}",
"event_type": event.event_type,
"plugin_id": event.plugin_id,
"user_id": event.user_id,
@@ -190,7 +190,7 @@ async def record_plugin_event(event: PluginEvent):
@app.get("/api/v1/analytics/usage/{plugin_id}")
async def get_plugin_usage(plugin_id: str, days: int = 30):
"""Get usage analytics for a specific plugin"""
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=days)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days)
usage_records = plugin_usage_data.get(plugin_id, [])
recent_usage = [r for r in usage_records
@@ -204,13 +204,13 @@ async def get_plugin_usage(plugin_id: str, days: int = 30):
"period_days": days,
"usage_statistics": usage_stats,
"total_records": len(recent_usage),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/performance/{plugin_id}")
async def get_plugin_performance(plugin_id: str, hours: int = 24):
"""Get performance analytics for a specific plugin"""
cutoff_time = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=hours)
performance_records = plugin_performance_data.get(plugin_id, [])
recent_performance = [r for r in performance_records
@@ -224,7 +224,7 @@ async def get_plugin_performance(plugin_id: str, hours: int = 24):
"period_hours": hours,
"performance_statistics": performance_stats,
"total_records": len(recent_performance),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/ratings/{plugin_id}")
@@ -240,7 +240,7 @@ async def get_plugin_ratings(plugin_id: str):
"rating_statistics": rating_stats,
"total_ratings": len(rating_records),
"recent_ratings": rating_records[-10:], # Last 10 ratings
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/dashboard")
@@ -257,7 +257,7 @@ async def get_analytics_dashboard():
return {
"dashboard": dashboard_data,
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/trends")
@@ -398,7 +398,7 @@ def get_overview_statistics() -> Dict[str, Any]:
total_ratings = sum(len(data) for data in plugin_ratings.values())
# Calculate active plugins (plugins with usage in last 7 days)
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=7)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=7)
active_plugins = 0
for plugin_id, usage_records in plugin_usage_data.items():
@@ -417,7 +417,7 @@ def get_overview_statistics() -> Dict[str, Any]:
def get_trending_plugins(limit: int = 10) -> List[Dict]:
"""Get trending plugins based on recent usage"""
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=7)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=7)
plugin_scores = []
@@ -443,7 +443,7 @@ def get_trending_plugins(limit: int = 10) -> List[Dict]:
def get_global_usage_trends(days: int = 30) -> Dict[str, Any]:
"""Get global usage trends"""
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=days)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days)
global_trends = {}
for plugin_id, usage_records in plugin_usage_data.items():
@@ -541,14 +541,14 @@ def get_plugin_trends(plugin_id: str, days: int) -> Dict[str, Any]:
"""Get trends for a specific plugin"""
plugin_trends = usage_trends.get(plugin_id, {})
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=days)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days)
date_key = cutoff_date.date().isoformat()
return {
"plugin_id": plugin_id,
"trends": plugin_trends,
"period_days": days,
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Report generation functions
@@ -581,7 +581,7 @@ def generate_summary_report(plugin_id: Optional[str] = None) -> Dict[str, Any]:
"usage": get_plugin_usage(plugin_id, days=30),
"performance": get_plugin_performance(plugin_id, hours=24),
"ratings": get_plugin_ratings(plugin_id),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
else:
return get_analytics_dashboard()
@@ -613,7 +613,7 @@ def update_analytics_cache():
def cleanup_old_data():
"""Clean up old analytics data"""
cutoff_date = datetime.now(datetime.UTC) - timedelta(days=90)
cutoff_date = datetime.now(timezone.utc) - timedelta(days=90)
cutoff_iso = cutoff_date.isoformat()
# Clean usage data

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginUsage, PluginPerformance, PluginRating, PluginEvent, plugin_usage_data, plugin_performance_data, plugin_ratings, plugin_events
@@ -32,7 +32,7 @@ def test_plugin_usage_empty_plugin_id():
plugin_id="",
user_id="user_123",
action="install",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert usage.plugin_id == ""
@@ -48,7 +48,7 @@ def test_plugin_performance_negative_values():
response_time=-0.1,
error_rate=-0.01,
uptime=-50.0,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert perf.cpu_usage == -10.0
assert perf.memory_usage == -5.0
@@ -61,7 +61,7 @@ def test_plugin_rating_out_of_range():
plugin_id="plugin_123",
user_id="user_123",
rating=10,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert rating.rating == 10
@@ -73,7 +73,7 @@ def test_plugin_rating_zero():
plugin_id="plugin_123",
user_id="user_123",
rating=0,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert rating.rating == 0
@@ -128,7 +128,7 @@ def test_record_multiple_usage_events():
plugin_id="plugin_123",
user_id=f"user_{i}",
action="use",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
client.post("/api/v1/analytics/usage", json=usage.model_dump(mode='json'))

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginUsage, PluginPerformance, PluginRating, PluginEvent, plugin_usage_data, plugin_performance_data, plugin_ratings, plugin_events
@@ -56,7 +56,7 @@ def test_record_plugin_usage():
plugin_id="plugin_123",
user_id="user_123",
action="install",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/analytics/usage", json=usage.model_dump(mode='json'))
assert response.status_code == 200
@@ -77,7 +77,7 @@ def test_record_plugin_performance():
response_time=0.123,
error_rate=0.001,
uptime=99.9,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/analytics/performance", json=perf.model_dump(mode='json'))
assert response.status_code == 200
@@ -95,7 +95,7 @@ def test_record_plugin_rating():
user_id="user_123",
rating=5,
review="Great plugin!",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/analytics/rating", json=rating.model_dump(mode='json'))
assert response.status_code == 200
@@ -113,7 +113,7 @@ def test_record_plugin_event():
plugin_id="plugin_123",
user_id="user_123",
data={"error": "timeout"},
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
response = client.post("/api/v1/analytics/event", json=event.model_dump(mode='json'))
assert response.status_code == 200
@@ -131,7 +131,7 @@ def test_get_plugin_usage():
plugin_id="plugin_123",
user_id="user_123",
action="install",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
client.post("/api/v1/analytics/usage", json=usage.model_dump(mode='json'))
@@ -155,7 +155,7 @@ def test_get_plugin_performance():
response_time=0.123,
error_rate=0.001,
uptime=99.9,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
client.post("/api/v1/analytics/performance", json=perf.model_dump(mode='json'))
@@ -175,7 +175,7 @@ def test_get_plugin_ratings():
plugin_id="plugin_123",
user_id="user_123",
rating=5,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
client.post("/api/v1/analytics/rating", json=rating.model_dump(mode='json'))

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginUsage, PluginPerformance, PluginRating, PluginEvent
@@ -25,7 +25,7 @@ def test_plugin_usage_model():
plugin_id="plugin_123",
user_id="user_123",
action="install",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
metadata={"source": "marketplace"}
)
assert usage.plugin_id == "plugin_123"
@@ -41,7 +41,7 @@ def test_plugin_usage_defaults():
plugin_id="plugin_123",
user_id="user_123",
action="use",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert usage.metadata == {}
@@ -57,7 +57,7 @@ def test_plugin_performance_model():
response_time=0.123,
error_rate=0.001,
uptime=99.9,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert perf.plugin_id == "plugin_123"
assert perf.version == "1.0.0"
@@ -76,7 +76,7 @@ def test_plugin_rating_model():
user_id="user_123",
rating=5,
review="Great plugin!",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert rating.plugin_id == "plugin_123"
assert rating.rating == 5
@@ -90,7 +90,7 @@ def test_plugin_rating_defaults():
plugin_id="plugin_123",
user_id="user_123",
rating=4,
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert rating.review is None
@@ -103,7 +103,7 @@ def test_plugin_event_model():
plugin_id="plugin_123",
user_id="user_123",
data={"error": "timeout"},
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert event.event_type == "error"
assert event.plugin_id == "plugin_123"
@@ -117,7 +117,7 @@ def test_plugin_event_defaults():
event = PluginEvent(
event_type="info",
plugin_id="plugin_123",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
assert event.user_id is None
assert event.data == {}

View File

@@ -5,7 +5,7 @@ Provides web interface and marketplace functionality for plugins
import asyncio
import json
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException, Request
@@ -120,7 +120,7 @@ async def get_featured_plugins_api():
"""Get featured plugins for marketplace"""
return {
"featured_plugins": get_featured_plugins(),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/marketplace/popular")
@@ -128,7 +128,7 @@ async def get_popular_plugins_api(limit: int = 12):
"""Get popular plugins"""
return {
"popular_plugins": get_popular_plugins(limit),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/marketplace/recent")
@@ -136,7 +136,7 @@ async def get_recent_plugins_api(limit: int = 12):
"""Get recently added plugins"""
return {
"recent_plugins": get_recent_plugins(limit),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/marketplace/stats")
@@ -144,13 +144,13 @@ async def get_marketplace_stats_api():
"""Get marketplace statistics"""
return {
"stats": get_marketplace_stats(),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.post("/api/v1/reviews")
async def create_review(review: MarketplaceReview):
"""Create a plugin review"""
review_id = f"review_{int(datetime.now(datetime.UTC).timestamp())}"
review_id = f"review_{int(datetime.now(timezone.utc).timestamp())}"
review_record = {
"review_id": review_id,
@@ -162,7 +162,7 @@ async def create_review(review: MarketplaceReview):
"pros": review.pros,
"cons": review.cons,
"helpful_votes": 0,
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"verified_purchase": False
}
@@ -202,7 +202,7 @@ async def get_plugin_reviews_api(plugin_id: str):
@app.post("/api/v1/purchases")
async def create_purchase(purchase: PluginPurchase):
"""Create a plugin purchase"""
purchase_id = f"purchase_{int(datetime.now(datetime.UTC).timestamp())}"
purchase_id = f"purchase_{int(datetime.now(timezone.utc).timestamp())}"
purchase_record = {
"purchase_id": purchase_id,
@@ -211,8 +211,8 @@ async def create_purchase(purchase: PluginPurchase):
"price": purchase.price,
"payment_method": purchase.payment_method,
"status": "completed",
"created_at": datetime.now(datetime.UTC).isoformat(),
"refund_deadline": (datetime.now(datetime.UTC) + timedelta(days=30)).isoformat()
"created_at": datetime.now(timezone.utc).isoformat(),
"refund_deadline": (datetime.now(timezone.utc) + timedelta(days=30)).isoformat()
}
if purchase.plugin_id not in purchases:
@@ -235,7 +235,7 @@ async def create_purchase(purchase: PluginPurchase):
@app.post("/api/v1/developers/apply")
async def apply_developer(application: DeveloperApplication):
"""Apply to become a verified developer"""
application_id = f"dev_app_{int(datetime.now(datetime.UTC).timestamp())}"
application_id = f"dev_app_{int(datetime.now(timezone.utc).timestamp())}"
application_record = {
"application_id": application_id,
@@ -247,7 +247,7 @@ async def apply_developer(application: DeveloperApplication):
"github_username": application.github_username,
"description": application.description,
"status": "pending",
"submitted_at": datetime.now(datetime.UTC).isoformat(),
"submitted_at": datetime.now(timezone.utc).isoformat(),
"reviewed_at": None,
"reviewer_notes": None
}
@@ -268,7 +268,7 @@ async def get_verified_developers_api():
return {
"verified_developers": get_verified_developers(),
"total_developers": len(verified_developers),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/revenue/{developer_id}")
@@ -278,7 +278,7 @@ async def get_developer_revenue(developer_id: str):
"total_revenue": 0.0,
"plugin_revenue": {},
"monthly_revenue": {},
"last_updated": datetime.now(datetime.UTC).isoformat()
"last_updated": datetime.now(timezone.utc).isoformat()
})
return developer_revenue
@@ -358,7 +358,7 @@ def get_recent_plugins(limit: int = 12) -> List[Dict]:
"rating": 4.9,
"downloads": 2340,
"price": 199.99,
"created_at": (datetime.now(datetime.UTC) - timedelta(days=3)).isoformat()
"created_at": (datetime.now(timezone.utc) - timedelta(days=3)).isoformat()
},
{
"plugin_id": "performance_monitor",
@@ -369,7 +369,7 @@ def get_recent_plugins(limit: int = 12) -> List[Dict]:
"rating": 4.4,
"downloads": 1890,
"price": 59.99,
"created_at": (datetime.now(datetime.UTC) - timedelta(days=7)).isoformat()
"created_at": (datetime.now(timezone.utc) - timedelta(days=7)).isoformat()
}
]
@@ -414,7 +414,7 @@ def get_plugin_details(plugin_id: str) -> Optional[Dict]:
"downloads": 15420,
"price": 99.99,
"version": "2.1.0",
"last_updated": (datetime.now(datetime.UTC) - timedelta(days=15)).isoformat(),
"last_updated": (datetime.now(timezone.utc) - timedelta(days=15)).isoformat(),
"repository_url": "https://github.com/aitbc-labs/ai-trading-bot",
"homepage_url": "https://aitbc-trading-bot.com",
"license": "MIT",
@@ -442,7 +442,7 @@ def get_plugin_reviews(plugin_id: str) -> List[Dict]:
"pros": ["Easy to use", "Great performance", "Good documentation"],
"cons": ["Initial setup complexity"],
"helpful_votes": 23,
"created_at": (datetime.now(datetime.UTC) - timedelta(days=10)).isoformat()
"created_at": (datetime.now(timezone.utc) - timedelta(days=10)).isoformat()
},
{
"review_id": "review_2",
@@ -453,7 +453,7 @@ def get_plugin_reviews(plugin_id: str) -> List[Dict]:
"pros": ["Powerful features", "Good support"],
"cons": ["UI could be better", "Learning curve"],
"helpful_votes": 15,
"created_at": (datetime.now(datetime.UTC) - timedelta(days=25)).isoformat()
"created_at": (datetime.now(timezone.utc) - timedelta(days=25)).isoformat()
}
]

View File

@@ -6,7 +6,7 @@ Handles plugin registration, discovery, versioning, and security validation
import asyncio
import json
import hashlib
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException, UploadFile, File
@@ -66,7 +66,7 @@ async def root():
return {
"service": "AITBC Plugin Registry",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -79,7 +79,7 @@ async def health_check():
"security_scans": len(security_scans),
"downloads_today": len([d for downloads_list in downloads.values()
for d in downloads_list
if datetime.fromisoformat(d["timestamp"]).date() == datetime.now(datetime.UTC).date()])
if datetime.fromisoformat(d["timestamp"]).date() == datetime.now(timezone.utc).date()])
}
@app.post("/api/v1/plugins/register")
@@ -105,8 +105,8 @@ async def register_plugin(plugin: PluginRegistration):
"aitbc_version": plugin.aitbc_version,
"plugin_type": plugin.plugin_type,
"status": "active",
"created_at": datetime.now(datetime.UTC).isoformat(),
"updated_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"updated_at": datetime.now(timezone.utc).isoformat(),
"verified": False,
"featured": False,
"download_count": 0,
@@ -158,14 +158,14 @@ async def add_plugin_version(plugin_id: str, version: PluginVersion):
"release_date": version.release_date.isoformat(),
"downloads": 0,
"security_scan_passed": False,
"created_at": datetime.now(datetime.UTC).isoformat()
"created_at": datetime.now(timezone.utc).isoformat()
}
plugin_versions[plugin_id].append(version_record)
# Update plugin's latest version
plugins[plugin_id]["latest_version"] = version.version
plugins[plugin_id]["updated_at"] = datetime.now(datetime.UTC).isoformat()
plugins[plugin_id]["updated_at"] = datetime.now(timezone.utc).isoformat()
# Sort versions by version number (semantic versioning)
plugin_versions[plugin_id].sort(key=lambda x: x["version"], reverse=True)
@@ -272,7 +272,7 @@ async def download_plugin(plugin_id: str, version: str):
# Record download
download_record = {
"version": version,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"ip_address": "client_ip", # In production, get actual IP
"user_agent": "user_agent" # In production, get actual user agent
}
@@ -284,7 +284,7 @@ async def download_plugin(plugin_id: str, version: str):
# Update analytics
if plugin_id not in analytics:
analytics[plugin_id] = {"downloads": [], "views": [], "ratings": []}
analytics[plugin_id]["downloads"].append(datetime.now(datetime.UTC).timestamp())
analytics[plugin_id]["downloads"].append(datetime.now(timezone.utc).timestamp())
# Update plugin download count
plugins[plugin_id]["download_count"] += 1
@@ -319,7 +319,7 @@ async def create_security_scan(plugin_id: str, scan: SecurityScan):
"vulnerabilities": scan.vulnerabilities,
"risk_score": scan.risk_score,
"passed": scan.passed,
"created_at": datetime.now(datetime.UTC).isoformat()
"created_at": datetime.now(timezone.utc).isoformat()
}
# Update version security status
@@ -400,7 +400,7 @@ async def get_popular_plugins(limit: int = 10):
return {
"popular_plugins": popular_plugins,
"limit": limit,
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/recent")
@@ -411,7 +411,7 @@ async def get_recent_plugins(limit: int = 10):
return {
"recent_plugins": recent_plugins,
"limit": limit,
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/analytics/dashboard")
@@ -429,7 +429,7 @@ async def get_analytics_dashboard():
# Recent activity
recent_downloads = 0
today = datetime.now(datetime.UTC).date()
today = datetime.now(timezone.utc).date()
for download_list in downloads.values():
recent_downloads += len([d for d in download_list
if datetime.fromisoformat(d["timestamp"]).date() == today])
@@ -444,7 +444,7 @@ async def get_analytics_dashboard():
"security_scans": len(security_scans),
"passed_scans": len([s for s in security_scans.values() if s["passed"]])
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Background task for analytics processing
@@ -454,7 +454,7 @@ async def process_analytics():
await asyncio.sleep(3600) # Process every hour
# Update daily statistics
current_date = datetime.now(datetime.UTC).date()
current_date = datetime.now(timezone.utc).date()
for plugin_id, plugin_analytics in analytics.items():
daily_key = current_date.isoformat()

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginRegistration, PluginVersion, SecurityScan, plugins, plugin_versions, security_scans, analytics, downloads
@@ -74,7 +74,7 @@ def test_plugin_version_empty_changelog():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
assert version.changelog == ""
@@ -86,7 +86,7 @@ def test_security_scan_empty_vulnerabilities():
scan_id="scan_123",
plugin_id="test_plugin",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[],
risk_score="low",
passed=True
@@ -104,7 +104,7 @@ def test_add_version_nonexistent_plugin():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
response = client.post("/api/v1/plugins/nonexistent/versions", json=version.model_dump(mode='json'))
assert response.status_code == 404
@@ -152,7 +152,7 @@ def test_security_scan_nonexistent_plugin():
scan_id="scan_123",
plugin_id="nonexistent",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[],
risk_score="low",
passed=True
@@ -187,7 +187,7 @@ def test_security_scan_nonexistent_version():
scan_id="scan_123",
plugin_id="test_plugin",
version="2.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[],
risk_score="low",
passed=True
@@ -296,7 +296,7 @@ def test_security_scan_failed():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
client.post("/api/v1/plugins/test_plugin/versions", json=version.model_dump(mode='json'))
@@ -305,7 +305,7 @@ def test_security_scan_failed():
scan_id="scan_123",
plugin_id="test_plugin",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[{"severity": "high", "description": "Critical issue"}],
risk_score="high",
passed=False

View File

@@ -5,7 +5,7 @@ import sys
import sys
from pathlib import Path
from fastapi.testclient import TestClient
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginRegistration, PluginVersion, SecurityScan, plugins, plugin_versions, security_scans, analytics, downloads
@@ -129,7 +129,7 @@ def test_add_plugin_version():
download_url="https://github.com/test/plugin/archive/v1.1.0.tar.gz",
checksum="def456",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
response = client.post("/api/v1/plugins/test_plugin/versions", json=version.model_dump(mode='json'))
assert response.status_code == 200
@@ -166,7 +166,7 @@ def test_add_duplicate_version():
download_url="https://github.com/test/plugin/archive/v1.1.0.tar.gz",
checksum="def456",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
client.post("/api/v1/plugins/test_plugin/versions", json=version.model_dump(mode='json'))
@@ -280,7 +280,7 @@ def test_download_plugin():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
client.post("/api/v1/plugins/test_plugin/versions", json=version.model_dump(mode='json'))
@@ -320,7 +320,7 @@ def test_create_security_scan():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
client.post("/api/v1/plugins/test_plugin/versions", json=version.model_dump(mode='json'))
@@ -329,7 +329,7 @@ def test_create_security_scan():
scan_id="scan_123",
plugin_id="test_plugin",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[],
risk_score="low",
passed=True

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, PluginRegistration, PluginVersion, SecurityScan
@@ -72,7 +72,7 @@ def test_plugin_version_model():
download_url="https://github.com/test/plugin/archive/v1.0.0.tar.gz",
checksum="abc123",
aitbc_compatibility=["1.0.0", "1.1.0"],
release_date=datetime.now(datetime.UTC)
release_date=datetime.now(timezone.utc)
)
assert version.version == "1.0.0"
assert version.changelog == "Initial release"
@@ -88,7 +88,7 @@ def test_security_scan_model():
scan_id="scan_123",
plugin_id="test_plugin",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
vulnerabilities=[{"severity": "low", "description": "Test"}],
risk_score="low",
passed=True

View File

@@ -8,7 +8,7 @@ import json
import subprocess
import tempfile
import os
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from pathlib import Path
from typing import Dict, Any, List, Optional
from fastapi import FastAPI, HTTPException, UploadFile, File
@@ -63,7 +63,7 @@ async def root():
return {
"service": "AITBC Plugin Security Service",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -80,7 +80,7 @@ async def health_check():
@app.post("/api/v1/security/scan")
async def initiate_security_scan(scan: SecurityScan):
"""Initiate a security scan for a plugin"""
scan_id = f"scan_{int(datetime.now(datetime.UTC).timestamp())}"
scan_id = f"scan_{int(datetime.now(timezone.utc).timestamp())}"
# Create scan record
scan_record = {
@@ -91,7 +91,7 @@ async def initiate_security_scan(scan: SecurityScan):
"scan_type": scan.scan_type,
"priority": scan.priority,
"status": "queued",
"created_at": datetime.now(datetime.UTC).isoformat(),
"created_at": datetime.now(timezone.utc).isoformat(),
"started_at": None,
"completed_at": None,
"duration": None,
@@ -182,7 +182,7 @@ async def list_vulnerabilities(severity: Optional[str] = None,
@app.post("/api/v1/security/policies")
async def create_security_policy(policy: Dict[str, Any]):
"""Create a new security policy"""
policy_id = f"policy_{int(datetime.now(datetime.UTC).timestamp())}"
policy_id = f"policy_{int(datetime.now(timezone.utc).timestamp())}"
policy_record = {
"policy_id": policy_id,
@@ -197,8 +197,8 @@ async def create_security_policy(policy: Dict[str, Any]):
}),
"plugin_types": policy.get("plugin_types", []),
"active": True,
"created_at": datetime.now(datetime.UTC).isoformat(),
"updated_at": datetime.now(datetime.UTC).isoformat()
"created_at": datetime.now(timezone.utc).isoformat(),
"updated_at": datetime.now(timezone.utc).isoformat()
}
security_policies[policy_id] = policy_record
@@ -261,7 +261,7 @@ async def get_security_dashboard():
"""Get security dashboard data"""
total_scans = len(scan_reports)
recent_scans = [r for r in scan_reports.values()
if datetime.fromisoformat(r["scan_date"]) > datetime.now(datetime.UTC) - timedelta(days=7)]
if datetime.fromisoformat(r["scan_date"]) > datetime.now(timezone.utc) - timedelta(days=7)]
# Calculate statistics
scan_results = list(scan_reports.values())
@@ -294,7 +294,7 @@ async def get_security_dashboard():
"queue_size": len(scan_queue),
"active_policies": len([p for p in security_policies.values() if p["active"]])
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Core security scanning functions
@@ -305,15 +305,15 @@ async def process_scan_file(scan_id: str, file_path: str, filename: str):
for scan_record in scan_queue:
if scan_record["scan_id"] == scan_id:
scan_record["status"] = "running"
scan_record["started_at"] = datetime.now(datetime.UTC).isoformat()
scan_record["started_at"] = datetime.now(timezone.utc).isoformat()
break
start_time = datetime.now(datetime.UTC)
start_time = datetime.now(timezone.utc)
# Perform security scan
scan_result = await perform_security_scan(file_path, filename)
end_time = datetime.now(datetime.UTC)
end_time = datetime.now(timezone.utc)
duration = (end_time - start_time).total_seconds()
# Create security report
@@ -360,7 +360,7 @@ async def process_scan_file(scan_id: str, file_path: str, filename: str):
for scan_record in scan_queue:
if scan_record["scan_id"] == scan_id:
scan_record["status"] = "failed"
scan_record["completed_at"] = datetime.now(datetime.UTC).isoformat()
scan_record["completed_at"] = datetime.now(timezone.utc).isoformat()
break
async def perform_security_scan(file_path: str, filename: str) -> Dict[str, Any]:
@@ -392,7 +392,7 @@ async def perform_security_scan(file_path: str, filename: str) -> Dict[str, Any]
"vulnerability_count": len(vulnerabilities),
"severity_distribution": get_severity_distribution(vulnerabilities),
"file_type": filename.split('.')[-1],
"scan_timestamp": datetime.now(datetime.UTC).isoformat()
"scan_timestamp": datetime.now(timezone.utc).isoformat()
})
except Exception as e:

View File

@@ -4,7 +4,7 @@ import pytest
import sys
import sys
from pathlib import Path
from datetime import datetime, UTC
from datetime import datetime, timezone
from main import app, SecurityScan, Vulnerability, SecurityReport, calculate_overall_score, generate_recommendations, get_severity_distribution, estimate_scan_time
@@ -76,7 +76,7 @@ def test_security_report_model():
scan_id="scan_123",
plugin_id="plugin_123",
version="1.0.0",
scan_date=datetime.now(datetime.UTC),
scan_date=datetime.now(timezone.utc),
scan_duration=120.5,
overall_score="passed",
vulnerabilities=[],

View File

@@ -1,7 +1,7 @@
"""Miner Registry Implementation"""
from typing import List, Optional, Dict, Any
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from dataclasses import dataclass, field
import asyncio
@@ -22,8 +22,8 @@ class MinerInfo:
jobs_completed: int = 0
jobs_failed: int = 0
uptime_percent: float = 100.0
registered_at: datetime = field(default_factory=datetime.now(datetime.UTC))
last_heartbeat: datetime = field(default_factory=datetime.now(datetime.UTC))
registered_at: datetime = field(default_factory=datetime.now(timezone.utc))
last_heartbeat: datetime = field(default_factory=datetime.now(timezone.utc))
gpu_utilization: float = 0.0
memory_used_gb: float = 0.0
@@ -43,7 +43,7 @@ class PoolInfo:
total_hashrate: float = 0.0
jobs_completed_24h: int = 0
earnings_24h: float = 0.0
created_at: datetime = field(default_factory=datetime.now(datetime.UTC))
created_at: datetime = field(default_factory=datetime.now(timezone.utc))
@dataclass
@@ -55,7 +55,7 @@ class JobAssignment:
pool_id: str
model: str
status: str = "assigned"
assigned_at: datetime = field(default_factory=datetime.now(datetime.UTC))
assigned_at: datetime = field(default_factory=datetime.now(timezone.utc))
deadline: Optional[datetime] = None
completed_at: Optional[datetime] = None
@@ -142,7 +142,7 @@ class MinerRegistry:
miner.current_jobs = current_jobs
miner.gpu_utilization = gpu_utilization
miner.memory_used_gb = memory_used_gb
miner.last_heartbeat = datetime.now(datetime.UTC)
miner.last_heartbeat = datetime.now(timezone.utc)
async def update_capabilities(self, miner_id: str, capabilities: List[str]):
"""Update miner capabilities."""
@@ -271,7 +271,7 @@ class MinerRegistry:
if job_id in self._jobs:
job = self._jobs[job_id]
job.status = status
job.completed_at = datetime.now(datetime.UTC)
job.completed_at = datetime.now(timezone.utc)
if miner_id in self._miners:
miner = self._miners[miner_id]
@@ -314,7 +314,7 @@ class MinerRegistry:
# Update job
job.miner_id = new_miner_id
job.status = "assigned"
job.assigned_at = datetime.now(datetime.UTC)
job.assigned_at = datetime.now(timezone.utc)
# Update new miner
if new_miner_id in self._miners:

View File

@@ -1,7 +1,7 @@
"""Health check routes for Pool Hub"""
from fastapi import APIRouter
from datetime import datetime, UTC
from datetime import datetime, timezone
from sqlalchemy import text
router = APIRouter(tags=["health"])
@@ -13,7 +13,7 @@ async def health_check():
return {
"status": "ok",
"service": "pool-hub",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
@@ -28,7 +28,7 @@ async def readiness_check():
return {
"ready": all_ready,
"checks": checks,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}

View File

@@ -2,7 +2,7 @@
from fastapi import APIRouter, HTTPException, Depends, Query
from typing import List, Optional
from datetime import datetime, UTC
from datetime import datetime, timezone
from pydantic import BaseModel
from ..registry import MinerRegistry
@@ -86,7 +86,7 @@ async def assign_job(
job_id=job.job_id,
miner_id=best_miner.miner_id,
pool_id=best_miner.pool_id,
assigned_at=datetime.now(datetime.UTC),
assigned_at=datetime.now(timezone.utc),
deadline=job.deadline
)

View File

@@ -2,7 +2,7 @@
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
import math
@@ -74,7 +74,7 @@ class ScoringEngine:
success_rate = 100.0 # New miners start with perfect score
# Heartbeat freshness penalty
heartbeat_age = (datetime.now(datetime.UTC) - miner.last_heartbeat).total_seconds()
heartbeat_age = (datetime.now(timezone.utc) - miner.last_heartbeat).total_seconds()
if heartbeat_age > 300: # 5 minutes
freshness_penalty = min(20, heartbeat_age / 60)
else:
@@ -137,7 +137,7 @@ class ScoringEngine:
weight_total = 0
for record in history:
age_days = (datetime.now(datetime.UTC) - record["timestamp"]).days
age_days = (datetime.now(timezone.utc) - record["timestamp"]).days
weight = math.exp(-age_days / self.DECAY_HALF_LIFE_DAYS)
if record["success"]:
@@ -153,7 +153,7 @@ class ScoringEngine:
def _get_hours_active(self, miner) -> float:
"""Get hours since miner registered."""
delta = datetime.now(datetime.UTC) - miner.registered_at
delta = datetime.now(timezone.utc) - miner.registered_at
return max(1, delta.total_seconds() / 3600)
def _parse_memory(self, memory_str: str) -> float:
@@ -204,7 +204,7 @@ class ScoringEngine:
self._history[miner_id] = []
self._history[miner_id].append({
"timestamp": datetime.now(datetime.UTC),
"timestamp": datetime.now(timezone.utc),
"success": True,
"metrics": metrics or {}
})
@@ -219,7 +219,7 @@ class ScoringEngine:
self._history[miner_id] = []
self._history[miner_id].append({
"timestamp": datetime.now(datetime.UTC),
"timestamp": datetime.now(timezone.utc),
"success": False,
"error": error
})

View File

@@ -3,7 +3,7 @@ SLA and Billing API Endpoints for Pool-Hub
Provides endpoints for SLA metrics, capacity planning, and billing integration.
"""
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from typing import Dict, List, Optional, Any
from decimal import Decimal
@@ -165,7 +165,7 @@ async def get_capacity_snapshots(
):
"""Get capacity planning snapshots"""
try:
cutoff = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff = datetime.now(timezone.utc) - timedelta(hours=hours)
stmt = (
db.query(CapacitySnapshot)
.filter(CapacitySnapshot.timestamp >= cutoff)
@@ -236,7 +236,7 @@ async def configure_capacity_alerts(
return {
"status": "configured",
"alert_config": alert_config,
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
except Exception as e:
logger.error(f"Error configuring capacity alerts: {e}")
@@ -270,7 +270,7 @@ async def sync_billing_usage(
try:
if request.miner_id:
# Sync specific miner
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=request.hours_back)
result = await billing_integration.sync_miner_usage(
miner_id=request.miner_id, start_date=start_date, end_date=end_date
@@ -350,7 +350,7 @@ async def get_sla_status(db: Session = Depends(get_db)):
"status": status,
"active_violations": len(active_violations),
"recent_metrics_count": len(recent_metrics),
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
}
except Exception as e:
logger.error(f"Error getting SLA status: {e}")

View File

@@ -40,7 +40,7 @@ class Miner(Base):
miner_id: Mapped[str] = mapped_column(String(64), primary_key=True)
api_key_hash: Mapped[str] = mapped_column(String(128), nullable=False)
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
last_seen_at: Mapped[Optional[dt.datetime]] = mapped_column(DateTime(timezone=True))
addr: Mapped[str] = mapped_column(String(256))
@@ -78,7 +78,7 @@ class MinerStatus(Base):
uptime_pct: Mapped[Optional[float]] = mapped_column(Float) # SLA metric
last_heartbeat_at: Mapped[Optional[dt.datetime]] = mapped_column(DateTime(timezone=True))
updated_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC), onupdate=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc), onupdate=dt.datetime.now(timezone.utc)
)
miner: Mapped[Miner] = relationship(back_populates="status")
@@ -95,7 +95,7 @@ class MatchRequest(Base):
hints: Mapped[Dict[str, object]] = mapped_column(JSON, default=dict)
top_k: Mapped[int] = mapped_column(Integer, default=1)
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
results: Mapped[List["MatchResult"]] = relationship(
@@ -119,7 +119,7 @@ class MatchResult(Base):
price: Mapped[Optional[float]] = mapped_column(Float)
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
request: Mapped[MatchRequest] = relationship(back_populates="results")
@@ -140,7 +140,7 @@ class Feedback(Base):
fail_code: Mapped[Optional[str]] = mapped_column(String(64))
tokens_spent: Mapped[Optional[float]] = mapped_column(Float)
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
miner: Mapped[Miner] = relationship(back_populates="feedback")
@@ -164,10 +164,10 @@ class ServiceConfig(Base):
capabilities: Mapped[List[str]] = mapped_column(JSON, default=list)
max_concurrent: Mapped[int] = mapped_column(Integer, default=1)
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
updated_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC), onupdate=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc), onupdate=dt.datetime.now(timezone.utc)
)
# Add unique constraint for miner_id + service_type
@@ -192,7 +192,7 @@ class SLAMetric(Base):
threshold: Mapped[float] = mapped_column(Float, nullable=False)
is_violation: Mapped[bool] = mapped_column(Boolean, default=False)
timestamp: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
meta_data: Mapped[Dict[str, str]] = mapped_column(JSON, default=dict)
@@ -217,7 +217,7 @@ class SLAViolation(Base):
violation_duration_ms: Mapped[Optional[int]] = mapped_column(Integer)
resolved_at: Mapped[Optional[dt.datetime]] = mapped_column(DateTime(timezone=True))
created_at: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
meta_data: Mapped[Dict[str, str]] = mapped_column(JSON, default=dict)
@@ -241,6 +241,6 @@ class CapacitySnapshot(Base):
recommended_scaling: Mapped[str] = mapped_column(String(32), nullable=False)
scaling_reason: Mapped[str] = mapped_column(Text)
timestamp: Mapped[dt.datetime] = mapped_column(
DateTime(timezone=True), default=dt.datetime.now(datetime.UTC)
DateTime(timezone=True), default=dt.datetime.now(timezone.utc)
)
meta_data: Mapped[Dict[str, Any]] = mapped_column(JSON, default=dict)

View File

@@ -40,7 +40,7 @@ class FeedbackRepository:
latency_ms=latency_ms,
fail_code=fail_code,
tokens_spent=tokens_spent,
created_at=dt.datetime.now(datetime.UTC),
created_at=dt.datetime.now(timezone.utc),
)
self._session.add(feedback)
await self._session.flush()

View File

@@ -34,7 +34,7 @@ class MatchRepository:
requirements=requirements,
hints=hints or {},
top_k=top_k,
created_at=dt.datetime.now(datetime.UTC),
created_at=dt.datetime.now(timezone.utc),
)
self._session.add(request)
await self._session.flush()
@@ -58,7 +58,7 @@ class MatchRepository:
publish: bool = True,
) -> List[MatchResult]:
results: List[MatchResult] = []
created_at = dt.datetime.now(datetime.UTC)
created_at = dt.datetime.now(timezone.utc)
for candidate in candidates:
result = MatchResult(
request_id=request_id,

View File

@@ -69,7 +69,7 @@ class MinerRepository:
miner.capabilities = capabilities
miner.region = region
miner.last_seen_at = dt.datetime.now(datetime.UTC)
miner.last_seen_at = dt.datetime.now(timezone.utc)
await self._session.flush()
await self._sync_miner_to_redis(miner_id)
@@ -97,7 +97,7 @@ class MinerRepository:
"avg_latency_ms": avg_latency_ms,
"temp_c": temp_c,
"mem_free_gb": mem_free_gb,
"updated_at": dt.datetime.now(datetime.UTC),
"updated_at": dt.datetime.now(timezone.utc),
}.items()
if v is not None
}
@@ -107,7 +107,7 @@ class MinerRepository:
miner = await self._session.get(Miner, miner_id)
if miner:
miner.last_seen_at = dt.datetime.now(datetime.UTC)
miner.last_seen_at = dt.datetime.now(timezone.utc)
await self._session.flush()
await self._sync_miner_to_redis(miner_id)
@@ -115,7 +115,7 @@ class MinerRepository:
miner = await self._session.get(Miner, miner_id)
if miner is None:
return
miner.last_seen_at = dt.datetime.now(datetime.UTC)
miner.last_seen_at = dt.datetime.now(timezone.utc)
await self._session.flush()
await self._sync_miner_to_redis(miner_id)

View File

@@ -4,7 +4,7 @@ Integrates pool-hub usage data with coordinator-api's billing system.
"""
import asyncio
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from typing import Dict, List, Optional, Any
@@ -76,7 +76,7 @@ class BillingIntegration:
"unit_price": float(unit_price),
"total_amount": float(total_cost),
"currency": "USD",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"metadata": metadata or {},
}
@@ -139,7 +139,7 @@ class BillingIntegration:
) -> Dict[str, Any]:
"""Sync usage data for all miners to coordinator-api billing"""
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=hours_back)
# Get all miners

View File

@@ -4,7 +4,7 @@ Collects and tracks SLA metrics for miners including uptime, response time, job
"""
import asyncio
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from typing import Dict, List, Optional, Any
@@ -57,7 +57,7 @@ class SLACollector:
metric_value=metric_value,
threshold=threshold,
is_violation=is_violation,
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
meta_data=metadata or {},
)
@@ -90,7 +90,7 @@ class SLACollector:
# Calculate uptime based on last heartbeat
if miner_status.last_heartbeat_at:
time_since_heartbeat = (
datetime.now(datetime.UTC) - miner_status.last_heartbeat_at
datetime.now(timezone.utc) - miner_status.last_heartbeat_at
).total_seconds()
# Consider miner down if no heartbeat for 5 minutes
@@ -153,7 +153,7 @@ class SLACollector:
stmt = (
select(Feedback)
.where(Feedback.miner_id == miner_id)
.where(Feedback.created_at >= datetime.now(datetime.UTC) - timedelta(days=7))
.where(Feedback.created_at >= datetime.now(timezone.utc) - timedelta(days=7))
.order_by(Feedback.created_at.desc())
.limit(100)
)
@@ -206,7 +206,7 @@ class SLACollector:
forecast_capacity=total_miners, # Would be calculated from forecasting
recommended_scaling="stable",
scaling_reason="Capacity within normal range",
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
meta_data={"method": "real_time_collection"},
)
@@ -266,7 +266,7 @@ class SLACollector:
stmt = (
select(func.count(SLAViolation.id))
.where(SLAViolation.resolved_at.is_(None))
.where(SLAViolation.created_at >= datetime.now(datetime.UTC) - timedelta(hours=1))
.where(SLAViolation.created_at >= datetime.now(timezone.utc) - timedelta(hours=1))
)
results["violations_detected"] = self.db.execute(stmt).scalar() or 0
@@ -282,7 +282,7 @@ class SLACollector:
) -> List[SLAMetric]:
"""Get SLA metrics for a miner or all miners"""
cutoff = datetime.now(datetime.UTC) - timedelta(hours=hours)
cutoff = datetime.now(timezone.utc) - timedelta(hours=hours)
stmt = select(SLAMetric).where(SLAMetric.timestamp >= cutoff)
@@ -349,7 +349,7 @@ class SLACollector:
metric_value=metric_value,
threshold=threshold,
violation_duration_ms=None, # Will be updated when resolved
created_at=datetime.now(datetime.UTC),
created_at=datetime.now(timezone.utc),
meta_data=metadata or {},
)

View File

@@ -4,7 +4,7 @@ Tests for Billing Integration Service
import sys
import pytest
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from unittest.mock import AsyncMock, patch
from sqlalchemy.orm import Session
@@ -84,7 +84,7 @@ async def test_record_usage_with_fallback_pricing(billing_integration: BillingIn
@pytest.mark.asyncio
async def test_sync_miner_usage(billing_integration: BillingIntegration, sample_miner: Miner):
"""Test syncing usage for a specific miner"""
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=24)
with patch("poolhub.services.billing_integration.httpx.AsyncClient") as mock_client:
@@ -123,7 +123,7 @@ async def test_sync_all_miners_usage(billing_integration: BillingIntegration, sa
def test_collect_miner_usage(billing_integration: BillingIntegration, sample_miner: Miner):
"""Test collecting usage data for a miner"""
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=24)
usage_data = billing_integration.db.run_sync(
@@ -169,7 +169,7 @@ async def test_trigger_invoice_generation(billing_integration: BillingIntegratio
mock_client.return_value.__aenter__.return_value.post = AsyncMock(return_value=mock_response)
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(days=30)
result = await billing_integration.trigger_invoice_generation(

View File

@@ -5,7 +5,7 @@ Tests the integration between pool-hub and coordinator-api's billing system.
import sys
import pytest
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from sqlalchemy.orm import Session
@@ -70,7 +70,7 @@ def test_end_to_end_sla_to_billing_workflow(
assert len(metrics) > 0
# Step 3: Collect usage data for billing
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=1)
usage_data = sla_collector.db.run_sync(
lambda sess: billing_integration._collect_miner_usage(
@@ -126,7 +126,7 @@ def test_sla_violation_billing_correlation(
assert len(violations) > 0
# Usage should still be recorded even with violations
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=1)
usage_data = sla_collector.db.run_sync(
lambda sess: billing_integration._collect_miner_usage(
@@ -172,7 +172,7 @@ def test_billing_sync_with_coordinator_api(
"""Test billing sync with coordinator-api (mocked)"""
from unittest.mock import AsyncMock, patch
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(hours=1)
with patch("poolhub.services.billing_integration.httpx.AsyncClient") as mock_client:

View File

@@ -4,7 +4,7 @@ Tests for SLA Collector Service
import sys
import pytest
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from sqlalchemy.orm import Session
@@ -48,7 +48,7 @@ def sample_miner_status(db_session: Session, sample_miner: Miner) -> MinerStatus
avg_latency_ms=150,
temp_c=65,
mem_free_gb=32.0,
last_heartbeat_at=datetime.now(datetime.UTC),
last_heartbeat_at=datetime.now(timezone.utc),
)
db_session.add(status)
db_session.commit()

View File

@@ -4,7 +4,7 @@ Tests for SLA API Endpoints
import sys
import pytest
from datetime import datetime, UTC, timedelta
from datetime import datetime, timezone, timedelta
from decimal import Decimal
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
@@ -65,7 +65,7 @@ def sample_sla_metric(db_session: Session, sample_miner: Miner) -> SLAMetric:
metric_value=98.5,
threshold=95.0,
is_violation=False,
timestamp=datetime.now(datetime.UTC),
timestamp=datetime.now(timezone.utc),
metadata={"test": "true"},
)
db_session.add(metric)
@@ -191,7 +191,7 @@ def test_record_usage(test_client: TestClient):
def test_generate_invoice(test_client: TestClient):
"""Test triggering invoice generation"""
end_date = datetime.now(datetime.UTC)
end_date = datetime.now(timezone.utc)
start_date = end_date - timedelta(days=30)
request_data = {

View File

@@ -6,7 +6,7 @@ Handles order matching, trade execution, and settlement
import asyncio
import json
from collections import defaultdict, deque
from datetime import datetime, UTC
from datetime import datetime, timezone
from pathlib import Path
from typing import Dict, Any, List, Optional, Tuple
from fastapi import FastAPI, HTTPException
@@ -70,7 +70,7 @@ async def root():
return {
"service": "AITBC Trading Engine",
"status": "running",
"timestamp": datetime.now(datetime.UTC).isoformat(),
"timestamp": datetime.now(timezone.utc).isoformat(),
"version": "1.0.0"
}
@@ -98,7 +98,7 @@ async def submit_order(order: Order):
"volume_24h": 0.0,
"high_24h": None,
"low_24h": None,
"created_at": datetime.now(datetime.UTC).isoformat()
"created_at": datetime.now(timezone.utc).isoformat()
}
# Store order
@@ -185,7 +185,7 @@ async def get_order_book(symbol: str, depth: int = 10):
"volume_24h": book["volume_24h"],
"high_24h": book["high_24h"],
"low_24h": book["low_24h"],
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/trades")
@@ -216,7 +216,7 @@ async def get_ticker(symbol: str):
trades_24h = [t for t in trades.values()
if t["symbol"] == symbol and
datetime.fromisoformat(t["timestamp"]) >
datetime.now(datetime.UTC) - timedelta(hours=24)]
datetime.now(timezone.utc) - timedelta(hours=24)]
if trades_24h:
prices = [t["price"] for t in trades_24h]
@@ -276,7 +276,7 @@ async def cancel_order(order_id: str):
# Update order status
order["status"] = "cancelled"
order["cancelled_at"] = datetime.now(datetime.UTC).isoformat()
order["cancelled_at"] = datetime.now(timezone.utc).isoformat()
logger.info(f"Order cancelled: {order_id}")
@@ -295,7 +295,7 @@ async def get_market_data():
trades_24h = [t for t in trades.values()
if t["symbol"] == symbol and
datetime.fromisoformat(t["timestamp"]) >
datetime.now(datetime.UTC) - timedelta(hours=24)]
datetime.now(timezone.utc) - timedelta(hours=24)]
market_summary[symbol] = {
"last_price": book["last_price"],
@@ -310,7 +310,7 @@ async def get_market_data():
return {
"market_data": market_summary,
"total_symbols": len(market_summary),
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
@app.get("/api/v1/engine/stats")
@@ -338,7 +338,7 @@ async def get_engine_stats():
"active_order_books": len(order_books),
"uptime": "running"
},
"generated_at": datetime.now(datetime.UTC).isoformat()
"generated_at": datetime.now(timezone.utc).isoformat()
}
# Core trading engine logic
@@ -457,7 +457,7 @@ async def execute_trade(order1: Dict, order2: Dict, price: float) -> Optional[Di
return None
# Create trade record
trade_id = f"trade_{int(datetime.now(datetime.UTC).timestamp())}_{len(trades)}"
trade_id = f"trade_{int(datetime.now(timezone.utc).timestamp())}_{len(trades)}"
trade = {
"trade_id": trade_id,
@@ -466,7 +466,7 @@ async def execute_trade(order1: Dict, order2: Dict, price: float) -> Optional[Di
"sell_order_id": order2["order_id"] if order2["side"] == "sell" else order1["order_id"],
"quantity": trade_quantity,
"price": price,
"timestamp": datetime.now(datetime.UTC).isoformat()
"timestamp": datetime.now(timezone.utc).isoformat()
}
trades[trade_id] = trade
@@ -524,7 +524,7 @@ def update_market_data(symbol: str, trades_executed: List[Dict]):
trades_24h = [t for t in trades.values()
if t["symbol"] == symbol and
datetime.fromisoformat(t["timestamp"]) >
datetime.now(datetime.UTC) - timedelta(hours=24)]
datetime.now(timezone.utc) - timedelta(hours=24)]
if trades_24h:
prices = [t["price"] for t in trades_24h]
@@ -548,7 +548,7 @@ async def simulate_market_activity():
side = random.choice(["buy", "sell"])
quantity = random.uniform(10, 1000)
order_id = f"sim_order_{int(datetime.now(datetime.UTC).timestamp())}"
order_id = f"sim_order_{int(datetime.now(timezone.utc).timestamp())}"
order = Order(
order_id=order_id,
symbol=symbol,
@@ -556,7 +556,7 @@ async def simulate_market_activity():
type="market",
quantity=quantity,
user_id="sim_user",
timestamp=datetime.now(datetime.UTC)
timestamp=datetime.now(timezone.utc)
)
order_data = {

Some files were not shown because too many files have changed in this diff Show More