mt5-manager/main.py

109 lines
3.7 KiB
Python
Raw Permalink Normal View History

2025-10-14 16:04:37 +03:00
'''
File: main.py
Description: Веб-приложение для веб-сервера терминалов, основной файл FastAPI
'''
__version__ = '0.1.0'
2025-10-04 15:10:53 +03:00
# Импортируем нужные классы из библиотек
from contextlib import asynccontextmanager
2025-10-14 23:54:26 +03:00
from fastapi import FastAPI, Request, Path
2025-10-10 10:16:59 +03:00
from fastapi.staticfiles import StaticFiles
2025-10-07 21:48:20 +03:00
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from pydantic_settings import BaseSettings, JsonConfigSettingsSource, SettingsConfigDict
from pydantic import ConfigDict
2025-10-30 09:59:38 +03:00
import os
from mt5_control import MT5_Control
class Config(BaseSettings):
2025-10-30 09:59:38 +03:00
terminals: dict
mt5_folder: str
mt5_exe: str
model_config = SettingsConfigDict()
@classmethod
def settings_customise_sources(
cls,
settings_cls,
init_settings,
env_settings,
dotenv_settings,
file_secret_settings,
):
2025-10-30 09:59:38 +03:00
# Получаем путь к файлу из переменной окружения
config_file = os.getenv("CONFIG_FILE", "config.json")
return (
init_settings,
2025-10-30 09:59:38 +03:00
JsonConfigSettingsSource(settings_cls, json_file=config_file),
env_settings,
dotenv_settings,
file_secret_settings,
)
@asynccontextmanager
async def lifespan(app: FastAPI):
config = Config(_env_file=None)
2025-10-30 09:59:38 +03:00
app.state.terminals = config.terminals
app.state.instances = {}
2025-10-30 09:59:38 +03:00
for folder in app.state.terminals:
app.state.terminals[folder]['name'] = app.state.terminals[folder].get('name', folder)
global control
2025-10-30 09:59:38 +03:00
control = MT5_Control(app.state.terminals, config.mt5_folder, config.mt5_exe)
yield
2025-10-04 15:10:53 +03:00
# Создаём объект приложения
app = FastAPI(lifespan=lifespan)
2025-10-04 15:10:53 +03:00
2025-10-14 14:59:40 +03:00
# Подключаем статические файлы
2025-10-14 16:04:37 +03:00
app.mount('/static', StaticFiles(directory='static'), name='static')
2025-10-14 14:59:40 +03:00
# Создаём объект для работы с шаблонами HTML-кода
2025-10-14 16:04:37 +03:00
templates = Jinja2Templates(directory='templates')
2025-10-10 10:16:59 +03:00
2025-10-06 23:34:05 +03:00
@app.get('/', response_class=HTMLResponse)
2025-10-10 10:16:59 +03:00
async def index(request: Request):
2025-10-14 16:04:37 +03:00
'''Обработчик GET / (корневой каталог) - панель управления терминалами'''
instances = control.load_instances()
# for name in instances:
# if instances[name]['pid']:
# instances[name]['info'] = control.instance_info(name)
# print(instances)
2025-10-14 16:04:37 +03:00
return templates.TemplateResponse('index.html', {'request': request, 'instances': instances})
2025-10-07 21:48:20 +03:00
2025-10-14 14:59:40 +03:00
@app.post('/instances/{name}')
async def info_instance(name: str = Path(..., description="Информация об экземпляре", example="MetaTrader5.1")):
'''Полусение информации об экземпляре терминала'''
result = control.instance_info(name)
return JSONResponse(result)
@app.post('/start/{name}')
2025-10-14 23:54:26 +03:00
async def start_instance(name: str = Path(..., description="Название экземпляра", example="MetaTrader5.1")):
'''Запуск экземпляра терминала'''
result = control.start_mt5(name)
2025-10-07 21:48:20 +03:00
return JSONResponse(result)
2025-10-14 14:59:40 +03:00
@app.post('/stop/{name}')
2025-10-14 23:54:26 +03:00
async def stop_instance(name: str = Path(..., description="Название экземпляра", example="MetaTrader5.1")):
'''Остановка экземпляра терминала'''
result = control.stop_mt5(name)
2025-10-07 21:48:20 +03:00
return JSONResponse(result)
2025-10-16 20:41:52 +03:00
@app.post('/create/{name}')
async def create_instance(name: str = Path(..., description="Название экземпляра", example="MetaTrader5.1")):
'''Создание экземпляра терминала'''
result = control.create_mt5(name)
return JSONResponse(result)