7.7 KiB
Model Update Server
Минимальный backend-сервис на FastAPI для загрузки .pt моделей, их stub-конвертации в .ort, хранения метаданных в SQLite и выдачи последней модели устройствам.
Что умеет
POST /models- загрузка новой.ptмодели с версиейGET /models/latest- метаданные последней моделиGET /models/latest/download- скачивание последней.ortмодели
API
Все API-запросы требуют заголовок авторизации:
X-API-Key: <server-issued-key>
Ключи выпускаются вручную на сервере и задаются через переменную окружения API_KEYS.
Можно указать один ключ или несколько ключей через запятую.
POST /models
Загружает новую модель и регистрирует её как актуальную.
Принимает:
Content-Type: multipart/form-data- поле
file- файл модели в формате.pt - поле
version- строковая версия модели, например1.0.3
Возвращает:
201 Createdи JSON:
{
"version": "1.0.3",
"created_at": "2026-05-12T10:00:00Z",
"filename": "model_v1.0.3.ort",
"is_latest": true
}
Ошибки:
400- пустая версия или файл не.pt409- такая версия уже существует500- ошибка конвертации
GET /models/latest
Возвращает метаданные последней доступной модели.
Принимает:
- ничего
Возвращает:
200 OKи JSON:
{
"version": "1.0.3",
"created_at": "2026-05-12T10:00:00Z",
"filename": "model_v1.0.3.ort"
}
Ошибки:
404- если моделей ещё нет
GET /models/latest/download
Возвращает файл последней .ort модели.
Принимает:
- query-параметр
version - query-параметр
filename
Возвращает:
200 OK- бинарный файл
.ort - заголовок
Content-Dispositionдля скачивания
Ошибки:
404- если моделей нет, файл отсутствует на диске илиversion/filenameне совпадают с актуальной моделью
Требования
- Python 3.11+
Локальный запуск
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload
Сервис будет доступен на http://127.0.0.1:8000.
Пример запуска с API-ключом:
API_KEYS="local-dev-key" uvicorn app.main:app --reload
Сгенерировать 10 API-ключей и экспортировать их в текущую shell:
source scripts/generate_api_keys.sh
uvicorn app.main:app --reload
Сгенерировать 10 API-ключей и сохранить их в env-файл:
scripts/generate_api_keys.sh --env-file .env
set -a
source .env
set +a
uvicorn app.main:app --reload
Переменные окружения
MODELS_DIR- директория хранения итоговых.ortмоделейTMP_DIR- директория для временно загруженных.ptDATABASE_URL- URL подключения к SQLite, напримерsqlite:///./db/app.dbAPI_KEYS- один или несколько API-ключей через запятую, напримерkey-1,key-2
По умолчанию используются:
storage/modelstmpsqlite:///db/app.db- пустой список API-ключей, при котором API-запросы будут отклоняться с
401
Архитектура
Проект разложен по слоям clean architecture:
app/domain- сущности, интерфейсы репозиториев и доменные исключенияapp/application- use cases и DTOapp/infrastructure- SQLite, файловое хранилище, stub-конвертер, bootstrapapp/presentation- FastAPI routes, зависимости и response-схемы
Точка входа приложения: app/main.py.
Поведение stub-конвертера
Stub-конвертер уже подключен к POST /models, но реальную конвертацию пока не делает. В текущей версии он копирует загруженный .pt файл в хранилище с расширением .ort, чтобы можно было проверить сценарий загрузки и скачивания end-to-end.
Точка расширения находится в app/infrastructure/ModelConverterImpl.py.
Примеры запросов
Загрузка модели:
curl -X POST "http://127.0.0.1:8000/models" \
-H "X-API-Key: local-dev-key" \
-F "version=1.0.3" \
-F "file=@./example.pt"
Получение метаданных:
curl -H "X-API-Key: local-dev-key" \
"http://127.0.0.1:8000/models/latest"
Скачивание последней модели:
curl -OJ -H "X-API-Key: local-dev-key" \
"http://127.0.0.1:8000/models/latest/download?version=1.0.3&filename=model_v1.0.3.ort"
Docker
Сборка:
docker build -t model-update-server .
Сгенерировать ключи в .env:
scripts/generate_api_keys.sh --env-file .env
Запуск через env-файл:
docker run --rm -p 8000:8000 \
--env-file .env \
-v "$(pwd)/storage/models:/app/storage/models" \
-v "$(pwd)/db:/app/db" \
model-update-server
Файл .env содержит реальные ключи и не должен попадать в репозиторий. Шаблон без секретов находится в .env.example.
systemd
Пример unit-файла находится в deploy/systemd/model-update-server.service.
Он читает переменные окружения из /etc/model-update-server/model-update-server.env.
Установка env-файла с ключами:
sudo mkdir -p /etc/model-update-server
scripts/generate_api_keys.sh --env-file /tmp/model-update-server.env
sudo install -m 600 /tmp/model-update-server.env /etc/model-update-server/model-update-server.env
rm /tmp/model-update-server.env
Установка unit-файла:
sudo cp deploy/systemd/model-update-server.service /etc/systemd/system/model-update-server.service
sudo systemctl daemon-reload
sudo systemctl enable --now model-update-server
CI
В CI храните API_KEYS как secret/protected variable и передавайте её в окружение сборки или деплоя.
Не генерируйте новые ключи при каждом деплое, если старые клиенты должны продолжать работать.
Пример для GitHub Actions:
env:
API_KEYS: ${{ secrets.API_KEYS }}
Пример для GitLab CI:
deploy:
script:
- docker run --env API_KEYS="$API_KEYS" model-update-server
Структура данных
Таблица models:
idversionfilenamefile_pathcreated_atis_latest