Skip to content

Commit be79ae2

Browse files
authored
Create server.py
1 parent 61d4bd9 commit be79ae2

1 file changed

Lines changed: 162 additions & 0 deletions

File tree

vial/server.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
import asyncio
2+
import os
3+
import uuid
4+
from fastapi import FastAPI, HTTPException, UploadFile, File, Depends, Form
5+
from fastapi.security import APIKeyHeader
6+
from fastapi.middleware.cors import CORSMiddleware
7+
from pydantic import BaseModel
8+
from typing import Dict, List, Optional
9+
import logging
10+
from vial_manager import VialManager
11+
from webxos_wallet import WebXOSWallet
12+
from auth_manager import AuthManager
13+
from export_manager import ExportManager
14+
from langchain_agent import create_langchain_agent
15+
16+
# Configure logging
17+
logging.basicConfig(level=logging.INFO)
18+
logger = logging.getLogger(__name__)
19+
20+
app = FastAPI(title="Vial MCP API", version="2.1")
21+
22+
# CORS configuration
23+
app.add_middleware(
24+
CORSMiddleware,
25+
allow_origins=["*"],
26+
allow_credentials=True,
27+
allow_methods=["*"],
28+
allow_headers=["*"],
29+
)
30+
31+
# Initialize managers
32+
wallet = WebXOSWallet()
33+
auth_manager = AuthManager()
34+
vial_manager = VialManager(wallet)
35+
export_manager = ExportManager(vial_manager, wallet)
36+
langchain_agent = create_langchain_agent()
37+
38+
# Authentication
39+
API_KEY_NAME = "Authorization"
40+
api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
41+
42+
async def get_api_key(api_key: str = Depends(api_key_header)):
43+
if api_key and api_key.startswith("Bearer "):
44+
token = api_key.replace("Bearer ", "")
45+
if auth_manager.validate_token(token):
46+
return token
47+
raise HTTPException(status_code=401, detail="Invalid or missing API key")
48+
49+
# Pydantic models
50+
class AuthRequest(BaseModel):
51+
client: str
52+
deviceId: str
53+
sessionId: str
54+
networkId: str
55+
56+
class CommsRequest(BaseModel):
57+
message: str
58+
network_id: str
59+
60+
# API Endpoints
61+
@app.post("/auth")
62+
async def authenticate(auth: AuthRequest):
63+
try:
64+
token, address = auth_manager.authenticate(auth.networkId, auth.sessionId)
65+
logger.info(f"Authenticated session: {token}")
66+
return {"token": token, "address": address}
67+
except Exception as e:
68+
logger.error(f"Auth error: {str(e)}")
69+
with open("errorlog.md", "a") as f:
70+
f.write(f"- **[2025-08-10T20:23:00Z]** Auth error: {str(e)}\n")
71+
raise HTTPException(status_code=500, detail=str(e))
72+
73+
@app.post("/void")
74+
async def void_network(token: str = Depends(get_api_key)):
75+
try:
76+
auth_manager.void_session(token)
77+
vial_manager.reset_vials()
78+
logger.info("Network voided")
79+
return {"status": "voided"}
80+
except Exception as e:
81+
logger.error(f"Void error: {str(e)}")
82+
with open("errorlog.md", "a") as f:
83+
f.write(f"- **[2025-08-10T20:23:00Z]** Void error: {str(e)}\n")
84+
raise HTTPException(status_code=500, detail=str(e))
85+
86+
@app.get("/health")
87+
async def health_check():
88+
try:
89+
return {"status": "ok"}
90+
except Exception as e:
91+
logger.error(f"Health check error: {str(e)}")
92+
with open("errorlog.md", "a") as f:
93+
f.write(f"- **[2025-08-10T20:23:00Z]** Health check error: {str(e)}\n")
94+
raise HTTPException(status_code=500, detail=str(e))
95+
96+
@app.post("/train")
97+
async def train_vials(file: UploadFile = File(...), networkId: str = Form(...), token: str = Depends(get_api_key)):
98+
try:
99+
if not auth_manager.validate_session(token, networkId):
100+
raise HTTPException(status_code=403, detail="Invalid network ID")
101+
102+
content = await file.read()
103+
content_str = content.decode('utf-8')
104+
105+
balance_earned = vial_manager.train_vials(networkId, content_str, file.filename)
106+
logger.info(f"Trained vials for network: {networkId}")
107+
return {"vials": vial_manager.get_vials(), "balance": balance_earned}
108+
except Exception as e:
109+
logger.error(f"Train error: {str(e)}")
110+
with open("errorlog.md", "a") as f:
111+
f.write(f"- **[2025-08-10T20:23:00Z]** Train error: {str(e)}\n")
112+
raise HTTPException(status_code=500, detail=str(e))
113+
114+
@app.get("/export")
115+
async def export_vials(networkId: str, token: str = Depends(get_api_key)):
116+
try:
117+
if not auth_manager.validate_session(token, networkId):
118+
raise HTTPException(status_code=403, detail="Invalid network ID")
119+
120+
markdown = export_manager.export_to_markdown(token, networkId)
121+
logger.info(f"Exported vials for network: {networkId}")
122+
return {"markdown": markdown}
123+
except Exception as e:
124+
logger.error(f"Export error: {str(e)}")
125+
with open("errorlog.md", "a") as f:
126+
f.write(f"- **[2025-08-10T20:23:00Z]** Export error: {str(e)}\n")
127+
raise HTTPException(status_code=500, detail=str(e))
128+
129+
@app.post("/upload")
130+
async def upload_file(file: UploadFile = File(...), networkId: str = Form(...), token: str = Depends(get_api_key)):
131+
try:
132+
if not auth_manager.validate_session(token, networkId):
133+
raise HTTPException(status_code=403, detail="Invalid network ID")
134+
135+
content = await file.read()
136+
file_path = f"/uploads/{file.filename}"
137+
logger.info(f"File uploaded: {file_path}")
138+
return {"filePath": file_path}
139+
except Exception as e:
140+
logger.error(f"Upload error: {str(e)}")
141+
with open("errorlog.md", "a") as f:
142+
f.write(f"- **[2025-08-10T20:23:00Z]** Upload error: {str(e)}\n")
143+
raise HTTPException(status_code=500, detail=str(e))
144+
145+
@app.post("/comms_hub")
146+
async def comms_hub(request: CommsRequest, token: str = Depends(get_api_key)):
147+
try:
148+
if not auth_manager.validate_session(token, request.network_id):
149+
raise HTTPException(status_code=403, detail="Invalid network ID")
150+
151+
response = await langchain_agent.arun(request.message)
152+
logger.info(f"Comms processed: {request.message}")
153+
return {"response": response}
154+
except Exception as e:
155+
logger.error(f"Comms error: {str(e)}")
156+
with open("errorlog.md", "a") as f:
157+
f.write(f"- **[2025-08-10T20:23:00Z]** Comms error: {str(e)}\n")
158+
raise HTTPException(status_code=500, detail=str(e))
159+
160+
if __name__ == "__main__":
161+
import uvicorn
162+
uvicorn.run(app, host="0.0.0.0", port=5000)

0 commit comments

Comments
 (0)