76 lines
3.0 KiB
Markdown
76 lines
3.0 KiB
Markdown
# Gemini Proxy
|
||
|
||
Минимальный изолированный HTTP-прокси для вызова Gemini с изображением.
|
||
|
||
## Назначение
|
||
|
||
Прокси принимает один crop изображения от основного российского сервера,
|
||
передаёт его в Gemini Developer API и возвращает текст модели вместе с
|
||
метаданными использования токенов.
|
||
|
||
В прокси нет бизнес-логики распознавания рецептов, словаря лекарств,
|
||
нормализации, scoring или хранения результатов. Эти функции находятся на
|
||
основном сервере.
|
||
|
||
## API
|
||
|
||
### `GET /health`
|
||
|
||
Возвращает:
|
||
|
||
```json
|
||
{"status":"ok"}
|
||
```
|
||
|
||
### `POST /gemini`
|
||
|
||
Формат: `multipart/form-data`.
|
||
|
||
Поле `image` должно содержать JPEG, PNG или WEBP размером не более 10 MB.
|
||
|
||
Необязательное поле `api_key_override` позволяет передать ключ только для
|
||
текущего запроса. Если оно не задано, используется `GEMINI_API_KEY` из
|
||
серверной конфигурации. Передача ключа в запросе менее безопасна и допустима
|
||
только по защищённому каналу между доверенными серверами; ключ не записывается
|
||
прокси в логи или на диск.
|
||
|
||
Ответ:
|
||
|
||
```json
|
||
{
|
||
"text": "{\"date\":null,\"medicines\":[]}",
|
||
"usage": {}
|
||
}
|
||
```
|
||
|
||
## Секреты
|
||
|
||
API-ключ не хранится в коде и не коммитится. Сервис читает:
|
||
|
||
- `GEMINI_API_KEY` — обязательный ключ;
|
||
- `GEMINI_MODEL` — модель, по умолчанию `gemini-3.6-flash`.
|
||
|
||
На сервере секрет хранится отдельно в `/etc/gemini-proxy/gemini-proxy.env`
|
||
с правами `600`, владельцем `root:gemini-proxy` и не доступен через HTTP.
|
||
|
||
## Изоляция
|
||
|
||
- отдельный пользователь `gemini-proxy`;
|
||
- отдельный каталог `/opt/gemini-proxy`;
|
||
- отдельный virtualenv;
|
||
- отдельный systemd-юнит;
|
||
- bind только на `127.0.0.1:8768`;
|
||
- изображения обрабатываются в памяти и не сохраняются приложением;
|
||
- существующие сервисы и их virtualenv не используются и не перезапускаются.
|
||
|
||
## Запуск
|
||
|
||
```text
|
||
systemctl status gemini-proxy
|
||
systemctl restart gemini-proxy
|
||
curl http://127.0.0.1:8768/health
|
||
```
|
||
|
||
Для внешнего доступа потребуется отдельный reverse-proxy маршрут nginx и
|
||
аутентификация между российским сервером и этим сервисом. До этого endpoint
|
||
доступен только локально на немецкой ВМ. |