gigadoc_ws.py: поддержка пути в --sdk-host; test_fpg.py: переведён на DNR-стенд (bearer subprotocol, Origin, хосты с путём)
This commit is contained in:
1 parent
eb1c7ae276
commit
f11ec6298d
2 files changed
+71
-14
No files matched your search
+28
-3
@@ -211,6 +211,22 @@ def normalize_prefix(prefix: str) -> str:
|
|||||||
return prefix.rstrip("/")
|
return prefix.rstrip("/")
|
||||||
|
|
||||||
|
|
||||||
|
def split_host_path(host: str) -> tuple:
|
||||||
|
"""Разделить 'host/path' на (scheme, hostname, base_path).
|
||||||
|
|
||||||
|
Поддерживает варианты: "domain.com", "domain.com/v1/giga",
|
||||||
|
"https://domain.com/v1/giga". Схема возвращается без "://".
|
||||||
|
"""
|
||||||
|
host = host.strip().rstrip("/")
|
||||||
|
scheme = ""
|
||||||
|
if "://" in host:
|
||||||
|
scheme, host = host.split("://", 1)
|
||||||
|
parts = host.split("/", 1)
|
||||||
|
hostname = parts[0]
|
||||||
|
base_path = "/" + parts[1] if len(parts) > 1 else ""
|
||||||
|
return scheme, hostname, base_path
|
||||||
|
|
||||||
|
|
||||||
def build_ssl_context(
|
def build_ssl_context(
|
||||||
insecure: bool,
|
insecure: bool,
|
||||||
) -> Optional[ssl.SSLContext]:
|
) -> Optional[ssl.SSLContext]:
|
||||||
@@ -329,7 +345,8 @@ async def create_predict_session(
|
|||||||
)
|
)
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"https://{args.sdk_host}"
|
f"https://{args.sdk_hostname}"
|
||||||
|
f"{args.sdk_base_path}"
|
||||||
f"{rest_prefix}/predict/new"
|
f"{rest_prefix}/predict/new"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -494,7 +511,8 @@ async def websocket_predict(
|
|||||||
for port in ports:
|
for port in ports:
|
||||||
|
|
||||||
ws_url = (
|
ws_url = (
|
||||||
f"wss://{args.sdk_host}:{port}"
|
f"wss://{args.sdk_hostname}:{port}"
|
||||||
|
f"{args.sdk_base_path}"
|
||||||
f"{ws_prefix}/{uid}/image"
|
f"{ws_prefix}/{uid}/image"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -918,7 +936,8 @@ async def delete_predict_session(
|
|||||||
)
|
)
|
||||||
|
|
||||||
url = (
|
url = (
|
||||||
f"https://{args.sdk_host}"
|
f"https://{args.sdk_hostname}"
|
||||||
|
f"{args.sdk_base_path}"
|
||||||
f"{rest_prefix}/predict/{uid}"
|
f"{rest_prefix}/predict/{uid}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -993,6 +1012,12 @@ async def main():
|
|||||||
|
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|
||||||
|
# sdk_host может содержать путь (domain.com/v1/giga) —
|
||||||
|
# разделяем на hostname и base_path.
|
||||||
|
_scheme, args.sdk_hostname, args.sdk_base_path = split_host_path(
|
||||||
|
args.sdk_host
|
||||||
|
)
|
||||||
|
|
||||||
setup_logging(
|
setup_logging(
|
||||||
args.verbose
|
args.verbose
|
||||||
)
|
)
|
||||||
|
|||||||
+43
-11
@@ -1,9 +1,12 @@
|
|||||||
"""
|
"""
|
||||||
Тестовый скрипт для SDK ФПГ (GigaDoc).
|
Тестовый скрипт для SDK ФПГ (GigaDoc, персональный стенд DNR).
|
||||||
Покрывает: авторизацию → создание сессии → WebSocket (изображения) → удаление сессии.
|
Покрывает: авторизацию → создание сессии → WebSocket (изображения) → удаление сессии.
|
||||||
|
|
||||||
Использование:
|
Использование:
|
||||||
python3 test_fpg.py [--ws-host HOST] [--ws-port PORT] [--image-dir DIR]
|
python3 test_fpg.py [--ws-host HOST] [--ws-port PORT] [--image-dir DIR]
|
||||||
|
|
||||||
|
Хосты можно переопределить через env: FPG_REST_HOST, FPG_WS_HOST, FPG_WS_PORT.
|
||||||
|
Хост может содержать путь (domain.com/v1/giga) — он учитывается при сборке URL.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -17,17 +20,37 @@ import time
|
|||||||
import requests
|
import requests
|
||||||
|
|
||||||
# ─── Конфигурация ─────────────────────────────────────────────
|
# ─── Конфигурация ─────────────────────────────────────────────
|
||||||
OAUTH_URL = "https://oauth.sbermed.ai/token"
|
OAUTH_URL = os.environ.get("FPG_OAUTH_URL", "https://oauth.sbermed.ai/token")
|
||||||
CLIENT_ID = "client_fpg_front"
|
CLIENT_ID = os.environ.get("FPG_CLIENT_ID", "client_fpg_front_dnr")
|
||||||
CLIENT_SECRET = os.environ.get("FPG_CLIENT_SECRET", "")
|
CLIENT_SECRET = os.environ.get("FPG_CLIENT_SECRET", "")
|
||||||
|
|
||||||
REST_HOST = "gigadoc-sdk.sbermed.ai"
|
REST_HOST = os.environ.get("FPG_REST_HOST", "gigadoc-dnr-sdk.sbermed.ai")
|
||||||
REST_BASE = f"https://{REST_HOST}"
|
WS_HOST = os.environ.get("FPG_WS_HOST", "gigadoc-dnr-sdk.sbermed.ai")
|
||||||
|
WS_PORT = int(os.environ.get("FPG_WS_PORT", "8443"))
|
||||||
|
WS_ORIGIN = os.environ.get("FPG_WS_ORIGIN", "https://gigadoc-dnr-sdk.sbermed.ai")
|
||||||
|
|
||||||
DEVICE_ID = "web_prod"
|
DEVICE_ID = "web_prod"
|
||||||
FORM_FACTOR = "web_prod"
|
FORM_FACTOR = "web_prod"
|
||||||
|
|
||||||
|
|
||||||
|
def split_host_path(host: str) -> tuple:
|
||||||
|
"""Разделить 'host/path' на (scheme, hostname, base_path)."""
|
||||||
|
host = host.strip().rstrip("/")
|
||||||
|
scheme = ""
|
||||||
|
if "://" in host:
|
||||||
|
scheme, host = host.split("://", 1)
|
||||||
|
parts = host.split("/", 1)
|
||||||
|
hostname = parts[0]
|
||||||
|
base_path = "/" + parts[1] if len(parts) > 1 else ""
|
||||||
|
return scheme, hostname, base_path
|
||||||
|
|
||||||
|
|
||||||
|
_rest_scheme, _rest_hostname, _rest_base_path = split_host_path(REST_HOST)
|
||||||
|
REST_BASE = f"{_rest_scheme or 'https'}://{_rest_hostname}{_rest_base_path}"
|
||||||
|
|
||||||
|
_ws_scheme, WS_HOSTNAME, WS_BASE_PATH = split_host_path(WS_HOST)
|
||||||
|
|
||||||
|
|
||||||
def get_token() -> str:
|
def get_token() -> str:
|
||||||
"""Получить access token через client_credentials."""
|
"""Получить access token через client_credentials."""
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
@@ -76,13 +99,20 @@ async def ws_scan(token: str, uid: str, ws_host: str, ws_port: int, image_dir: s
|
|||||||
"""Подключиться по WebSocket, отправить изображения, получить результат."""
|
"""Подключиться по WebSocket, отправить изображения, получить результат."""
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
uri = f"wss://{ws_host}:{ws_port}/api/v2/ws/predict/{uid}/image"
|
# ws_host может быть с путём (domain.com/v1/giga) — разделяем.
|
||||||
|
_scheme, _hostname, _base_path = split_host_path(ws_host)
|
||||||
|
_base_path = _base_path or WS_BASE_PATH
|
||||||
|
|
||||||
|
uri = f"wss://{_hostname}:{ws_port}{_base_path}/api/v2/ws/predict/{uid}/image"
|
||||||
print(f"[WS] Подключение: {uri}")
|
print(f"[WS] Подключение: {uri}")
|
||||||
|
|
||||||
|
# Авторизация через subprotocol bearer.<token> (как фронт),
|
||||||
|
# Origin — обязательный заголовок.
|
||||||
async with websockets.connect(
|
async with websockets.connect(
|
||||||
uri,
|
uri,
|
||||||
open_timeout=10,
|
open_timeout=10,
|
||||||
additional_headers={"Authorization": f"Bearer {token}"},
|
subprotocols=[f"bearer.{token}"],
|
||||||
|
extra_headers={"Origin": WS_ORIGIN},
|
||||||
) as ws:
|
) as ws:
|
||||||
print("[WS] Соединение установлено")
|
print("[WS] Соединение установлено")
|
||||||
|
|
||||||
@@ -145,16 +175,18 @@ def create_test_image():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Тест SDK ФПГ")
|
parser = argparse.ArgumentParser(description="Тест SDK ФПГ (DNR)")
|
||||||
parser.add_argument("--ws-host", default="sdk.sbermed.ai", help="WebSocket host")
|
parser.add_argument("--ws-host", default=WS_HOSTNAME, help="WebSocket host (может быть с путём)")
|
||||||
parser.add_argument("--ws-port", type=int, default=8443, help="WebSocket port")
|
parser.add_argument("--ws-port", type=int, default=WS_PORT, help="WebSocket port")
|
||||||
parser.add_argument("--image-dir", default=".", help="Директория с JPEG-файлами")
|
parser.add_argument("--image-dir", default=".", help="Директория с JPEG-файлами")
|
||||||
parser.add_argument("--rest-only", action="store_true", help="Только REST API (без WS)")
|
parser.add_argument("--rest-only", action="store_true", help="Только REST API (без WS)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
print("🏥 Тестирование SDK ФПГ (GigaDoc)")
|
print("🏥 Тестирование SDK ФПГ (GigaDoc DNR)")
|
||||||
print("=" * 60)
|
print("=" * 60)
|
||||||
|
print(f"[CONFIG] REST: {REST_BASE}")
|
||||||
|
print(f"[CONFIG] WS: wss://{args.ws_host}:{args.ws_port}")
|
||||||
|
|
||||||
# 0. Тестовое изображение
|
# 0. Тестовое изображение
|
||||||
create_test_image()
|
create_test_image()
|
||||||
|
|||||||
Reference in new issue
Block a user