|
|
|
import os |
|
import subprocess |
|
import threading |
|
import time |
|
import signal |
|
import sys |
|
from http.server import HTTPServer, SimpleHTTPRequestHandler |
|
import socket |
|
|
|
|
|
HF_PORT = int(os.environ.get("PORT", 7860)) |
|
|
|
TEN_AGENT_PORT = 8080 |
|
|
|
def is_port_in_use(port): |
|
"""Проверка занят ли порт""" |
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
|
return s.connect_ex(('localhost', port)) == 0 |
|
|
|
def run_ten_agent(): |
|
"""Запуск TEN Agent сервера""" |
|
print("Запуск TEN Agent...") |
|
|
|
|
|
os.makedirs("/tmp/ten_agent", exist_ok=True) |
|
|
|
|
|
server_process = subprocess.Popen( |
|
["/app/server/bin/api"], |
|
env={ |
|
**os.environ, |
|
"LOG_PATH": "/tmp/ten_agent", |
|
"LOG_STDOUT": "true", |
|
"SERVER_PORT": str(TEN_AGENT_PORT), |
|
"WORKERS_MAX": "10", |
|
"WORKER_QUIT_TIMEOUT_SECONDES": "60" |
|
} |
|
) |
|
|
|
return server_process |
|
|
|
|
|
class TenAgentHandler(SimpleHTTPRequestHandler): |
|
def do_GET(self): |
|
if self.path == '/': |
|
self.send_response(200) |
|
self.send_header('Content-type', 'text/html; charset=utf-8') |
|
self.end_headers() |
|
|
|
|
|
ten_agent_status = "работает" if is_port_in_use(TEN_AGENT_PORT) else "не запущен" |
|
|
|
html = f""" |
|
<html> |
|
<head> |
|
<title>TEN Agent на Hugging Face</title> |
|
<style> |
|
body {{ |
|
font-family: Arial, sans-serif; |
|
max-width: 800px; |
|
margin: 0 auto; |
|
padding: 20px; |
|
line-height: 1.6; |
|
}} |
|
h1, h2 {{ |
|
color: #2563eb; |
|
}} |
|
pre {{ |
|
background-color: #f1f5f9; |
|
padding: 15px; |
|
border-radius: 5px; |
|
overflow-x: auto; |
|
}} |
|
.status {{ |
|
padding: 8px 16px; |
|
border-radius: 4px; |
|
display: inline-block; |
|
margin-bottom: 20px; |
|
}} |
|
.status.running {{ |
|
background-color: #dcfce7; |
|
color: #166534; |
|
}} |
|
.status.stopped {{ |
|
background-color: #fee2e2; |
|
color: #991b1b; |
|
}} |
|
</style> |
|
</head> |
|
<body> |
|
<h1>TEN Agent на Hugging Face</h1> |
|
|
|
<div class="status {{'running' if ten_agent_status == 'работает' else 'stopped'}}"> |
|
Статус TEN Agent: {ten_agent_status} |
|
</div> |
|
|
|
<h2>Информация о сервере</h2> |
|
<ul> |
|
<li>TEN Agent API доступен на порту: {TEN_AGENT_PORT}</li> |
|
<li>Веб-интерфейс работает на порту: {HF_PORT}</li> |
|
</ul> |
|
|
|
<h2>Взаимодействие с API</h2> |
|
<p>Для взаимодействия с TEN Agent API используйте следующий адрес:</p> |
|
<pre>https://nitrox-ten.hf.space/api/</pre> |
|
|
|
<h2>Документация</h2> |
|
<p>Подробная информация о TEN Agent:</p> |
|
<ul> |
|
<li><a href="https://doc.theten.ai/ten-agent/overview" target="_blank">Официальная документация</a></li> |
|
<li><a href="https://github.com/TEN-framework/TEN-Agent" target="_blank">Репозиторий на GitHub</a></li> |
|
</ul> |
|
</body> |
|
</html> |
|
""" |
|
|
|
self.wfile.write(html.encode('utf-8')) |
|
else: |
|
self.send_error(404) |
|
|
|
|
|
def signal_handler(sig, frame): |
|
print("Получен сигнал завершения, останавливаю TEN Agent...") |
|
if 'server_process' in globals() and server_process: |
|
server_process.terminate() |
|
server_process.wait(timeout=10) |
|
sys.exit(0) |
|
|
|
|
|
signal.signal(signal.SIGINT, signal_handler) |
|
signal.signal(signal.SIGTERM, signal_handler) |
|
|
|
if __name__ == "__main__": |
|
|
|
server_process = run_ten_agent() |
|
|
|
|
|
print(f"Ожидаем запуск TEN Agent на порту {TEN_AGENT_PORT}...") |
|
timeout = 60 |
|
while timeout > 0 and not is_port_in_use(TEN_AGENT_PORT): |
|
time.sleep(1) |
|
timeout -= 1 |
|
|
|
if is_port_in_use(TEN_AGENT_PORT): |
|
print(f"TEN Agent успешно запущен на порту {TEN_AGENT_PORT}") |
|
else: |
|
print(f"Не удалось дождаться запуска TEN Agent на порту {TEN_AGENT_PORT}") |
|
|
|
|
|
print(f"Запуск веб-сервера на порту {HF_PORT}...") |
|
httpd = HTTPServer(('', HF_PORT), TenAgentHandler) |
|
try: |
|
httpd.serve_forever() |
|
except KeyboardInterrupt: |
|
pass |
|
finally: |
|
httpd.server_close() |
|
signal_handler(None, None) |