基础错误已修复,准备后续的开发

This commit is contained in:
3 2025-06-16 13:59:04 +08:00
parent c5b6a9b8f3
commit 46ac2e63b4
15 changed files with 91 additions and 24 deletions

View File

@ -3,8 +3,8 @@ from src.backend.app.api.endpoints import router
from src.backend.app.utils.logger import setup_logging
from src.backend.config import settings
app = FastAPI()
app.include_router(router,prefix="/api")
api_app = FastAPI()
api_app.include_router(router,prefix="/api")
def create_app() -> FastAPI:
# 设置日志

View File

@ -1,8 +1,7 @@
from typing import Dict, Any
from typing import Dict, Any, Optional
from src.backend.app.services.ai_services import AIService
from src.backend.config import settings
class CommandParser:
def __init__(self):
self.ai_service = AIService(settings.SILICONFLOW_API_KEY, settings.SILICONFLOW_API_URL)
@ -19,7 +18,8 @@ class CommandParser:
# 本地无法解析则调用AI服务
return await self.ai_service.parse_command(command)
def _try_local_parse(self, command: str) -> Dict[str, Any]:
@staticmethod
def _try_local_parse(command: str) -> Optional[Dict[str, Any]]:
"""
尝试本地解析常见命令
"""
@ -28,12 +28,13 @@ class CommandParser:
# VLAN配置
if "vlan" in command and "创建" in command:
parts = command.split()
vlan_id = next((p for p in parts if p.isdigit()), None)
if vlan_id:
vlan_id_str = next((p for p in parts if p.isdigit()), None)
if vlan_id_str:
vlan_id = int(vlan_id_str) # 转换为整数
return {
"type": "vlan",
"vlan_id": int(vlan_id),
"name": f"VLAN{vlan_id}",
"vlan_id": vlan_id, # 使用整数
"name": f"VLAN{vlan_id}", # 使用转换后的整数
"interfaces": []
}
@ -60,9 +61,9 @@ class CommandParser:
config["description"] = description
if "vlan" in command:
vlan_id = next((p for p in parts if p.isdigit()), None)
if vlan_id:
config["vlan"] = int(vlan_id)
vlan_id_str = next((p for p in parts if p.isdigit()), None)
if vlan_id_str:
config["vlan"] = int(vlan_id_str) # 转换为整数
return config

View File

@ -3,7 +3,7 @@ from typing import List, Dict
from pydantic import BaseModel
from ...config import settings
from ..services.network_scanner import NetworkScanner
from ..api.network_config import SwitchConfigurator, SwitchConfig
from ..api.network_config import SwitchConfigurator
router = APIRouter(prefix="/api", tags=["API"])
scanner = NetworkScanner()

View File

@ -1,6 +1,7 @@
import asyncio
import logging
import telnetlib3
import time
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional, Union
@ -142,6 +143,14 @@ class SwitchConfigurator:
except Exception as e:
raise EnspConnectionException(f"eNSP连接失败: {str(e)}")
async def _clean_idle_connections(self):
"""连接池清理机制"""
now = time.time()
for ip, (conn, last_used) in list(self._connection_pool.items()):
if now - last_used > 300: # 5分钟空闲超时
conn.close()
del self._connection_pool[ip]
async def _send_ssh_commands(self, ip: str, commands: List[str]) -> str:
"""SSH协议执行"""
async with self.semaphore:

View File

@ -58,4 +58,7 @@ class AIService:
return json.loads(config_str)
raise SiliconFlowAPIException("Invalid JSON format returned from AI")
except httpx.HTTPError as e:
raise SiliconFlowAPIException(str(e))
raise SiliconFlowAPIException(
detail=f"API请求失败: {str(e)}",
status_code=e.response.status_code if hasattr(e, "response") else 500
)

View File

@ -0,0 +1,36 @@
import networkx as nx
from scipy.optimize import minimize
class NetworkOptimizer:
def __init__(self, devices):
"""基于图论的网络优化模型"""
self.graph = self.build_topology_graph(devices)
def build_topology_graph(self, devices):
"""构建网络拓扑图"""
G = nx.Graph()
for device in devices:
G.add_node(device['ip'], type=device['type'])
# 添加连接关系(示例)
G.add_edge('192.168.1.1', '192.168.1.2', bandwidth=1000)
return G
def optimize_path(self, source, target):
"""计算最优路径"""
return nx.shortest_path(self.graph, source, target)
def bandwidth_optimization(self):
"""带宽优化模型"""
def objective(x):
# 最小化最大链路利用率
return max(x)
constraints = (
{'type': 'eq', 'fun': lambda x: sum(x) - total_bandwidth}
)
result = minimize(objective, initial_guess, constraints=constraints)
return result.x

View File

@ -1,5 +1,14 @@
from fastapi import HTTPException, status
from typing import Optional
class SiliconFlowAPIException(Exception):
"""硅基流动API异常"""
def __init__(self, detail: str, status_code: int = 500):
self.detail = detail
self.status_code = status_code
super().__init__(detail)
def __str__(self):
return f"SiliconFlowAPI Error [{self.status_code}]: {self.detail}"
class AICommandParseException(HTTPException):
def __init__(self, detail: str):
@ -23,9 +32,9 @@ class ConfigBackupException(SwitchConfigException):
"""配置备份失败异常"""
def __init__(self, ip: str):
super().__init__(
detail=f"无法备份设备 {ip} 的配置",
recovery_guide="检查设备存储空间或权限"
detail=f"无法备份设备 {ip} 的配置"
)
self.recovery_guide = "检查设备存储空间或权限" # 在子类中存储恢复指南
class ConfigRollbackException(SwitchConfigException):
"""回滚失败异常"""
@ -34,3 +43,4 @@ class ConfigRollbackException(SwitchConfigException):
detail=f"设备 {ip} 回滚失败(原始错误:{original_error}",
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY
)
self.recovery_guide = "尝试手动恢复配置或重启设备"

View File

@ -24,8 +24,8 @@ class BulkConfigurator:
return "\n".join(r.stdout for r in results)
finally:
await self.pool.release_connection(ip, conn)
def _generate_commands(self, config: BulkSwitchConfig) -> List[str]:
@staticmethod
def _generate_commands(config: BulkSwitchConfig) -> List[str]:
"""命令生成(纯业务逻辑)"""
commands = []
if config.vlan_id:

View File

@ -1,9 +1,7 @@
import asyncio
import time
import asyncssh
from typing import Dict
class SwitchConnectionPool:
"""
交换机连接池支持自动重连和负载均衡
@ -35,10 +33,15 @@ class SwitchConnectionPool:
async def release_connection(self, ip: str, conn: asyncssh.SSHClientConnection):
async with self._lock:
if conn.is_connected() and self._pools[ip].qsize() < self._max_conn:
if hasattr(conn, 'is_closed') and not conn.is_closed() and self._pools[ip].qsize() < self._max_conn:
await self._pools[ip].put(conn)
elif hasattr(conn, 'closed') and not conn.closed and self._pools[ip].qsize() < self._max_conn:
await self._pools[ip].put(conn)
else:
try:
conn.close()
except:
pass
async def close_all(self):
async with self._lock:

View File

@ -12,3 +12,8 @@ aiofiles>=24.1.0
telnetlib3>=2.0.4
asyncssh>=2.14.0
aiofiles>=24.1.0
networkx==3.1
scipy==1.11.1
stable-baselines3==2.0.0
plotly==5.15.0
pandas==2.0.3