ten / app.py
3v324v23's picture
Исправлена проблема с правами Go при сборке и прокси для работы Playground UI
2455e56
raw
history blame
5.75 kB
#!/usr/bin/env python3
import os
import subprocess
import sys
import time
from pathlib import Path
import signal
import shutil
def main():
processes = []
try:
# Пути к исполняемым файлам
api_binary = Path("/app/server/bin/api")
playground_dir = Path("/app/playground")
# Проверяем существование файлов
if not api_binary.exists():
print(f"ERROR: API binary not found at {api_binary}", file=sys.stderr)
return 1
if not playground_dir.exists():
print(f"ERROR: Playground directory not found at {playground_dir}", file=sys.stderr)
return 1
# Запускаем API сервер
print("Starting TEN-Agent API server on port 8080...")
api_server_process = subprocess.Popen([str(api_binary)])
processes.append(api_server_process)
# Даем время API серверу запуститься
time.sleep(3)
# Запускаем Playground UI
print("Starting Playground UI on port 3000...")
playground_env = os.environ.copy()
playground_env["AGENT_SERVER_URL"] = "http://localhost:8080" # Подключаемся к локальному API серверу
playground_process = subprocess.Popen(
["pnpm", "start", "--", "-p", "3000"],
cwd=str(playground_dir),
env=playground_env
)
processes.append(playground_process)
# Запускаем прокси для Hugging Face
from http.server import HTTPServer, SimpleHTTPRequestHandler
import http.client
import socketserver
class ProxyHandler(SimpleHTTPRequestHandler):
def do_GET(self):
# Направляем запросы к Playground UI
if self.path == '/' or self.path.startswith('/about') or self.path.startswith('/_next') or self.path.startswith('/favicon.ico'):
self._proxy_request('localhost', 3000, self.path)
# Направляем API запросы к API серверу
elif self.path.startswith('/health') or self.path.startswith('/list') or self.path.startswith('/graphs'):
self._proxy_request('localhost', 8080, self.path)
else:
# По умолчанию отправляем на Playground
self._proxy_request('localhost', 3000, self.path)
def do_POST(self):
# Все POST запросы направляем в API
self._proxy_request('localhost', 8080, self.path)
def _proxy_request(self, host, port, path):
try:
# Создаем соединение с целевым сервером
conn = http.client.HTTPConnection(host, port)
# Копируем заголовки запроса
headers = {}
for header in self.headers:
headers[header] = self.headers[header]
# Получаем данные запроса
content_length = int(self.headers.get('Content-Length', 0))
body = self.rfile.read(content_length) if content_length > 0 else None
# Отправляем запрос на целевой сервер
conn.request(self.command, path, body=body, headers=headers)
resp = conn.getresponse()
# Отправляем ответ клиенту
self.send_response(resp.status)
for header in resp.headers:
self.send_header(header, resp.headers[header])
self.end_headers()
# Отправляем тело ответа
self.wfile.write(resp.read())
conn.close()
except Exception as e:
print(f"Proxy error: {e}", file=sys.stderr)
self.send_response(500)
self.send_header('Content-type', 'text/plain; charset=utf-8')
self.end_headers()
self.wfile.write(f"Proxy error: {e}".encode('utf-8'))
# Запускаем HTTP прокси-сервер
port = 7860 # Hugging Face Space ожидает сервер на этом порту
print(f"Starting proxy server on port {port}, forwarding to Playground UI and API...")
# Разрешаем повторное использование адреса и порта
class ReuseAddressServer(socketserver.TCPServer):
allow_reuse_address = True
httpd = ReuseAddressServer(('0.0.0.0', port), ProxyHandler)
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down...")
finally:
# Завершаем все процессы при выходе
for proc in processes:
try:
proc.terminate()
proc.wait(timeout=5)
except:
proc.kill()
return 0
if __name__ == "__main__":
# Корректная обработка сигналов завершения
signal.signal(signal.SIGINT, lambda sig, frame: sys.exit(0))
signal.signal(signal.SIGTERM, lambda sig, frame: sys.exit(0))
sys.exit(main())