PowerShell-клиент predict.ps1 + charset=utf-8 в ответах сервиса (фикс кириллицы в PS 5.1)

This commit is contained in:
DUB-AI committed 2026-10-27 16:47:45 +07:00
1 parent 8dbca3f4a3
commit 98e4031037
4 files changed
+91 -1

No files matched your search

+21
View File
@@ -84,6 +84,27 @@ const { tracks } = await res.json();
Типизированная версия — `examples/typescript/predict.ts` (запуск: `npx tsx predict.ts --text "..."`). Типизированная версия — `examples/typescript/predict.ts` (запуск: `npx tsx predict.ts --text "..."`).
### PowerShell (examples/powershell/predict.ps1)
Скрипт (работает и в Windows PowerShell 5.1, и в PowerShell 7):
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File examples\powershell\predict.ps1 -Text "Перевод: Дублированный | MovieDalen"
pwsh -File examples\powershell\predict.ps1 -HtmlFile page.html -Url http://host:8000
```
Однострочник (POST с кириллицей; UTF-8 байтами — важно для PS 5.1, где
строковый `-Body` уходит в ISO-8859-1):
```powershell
$b = [Text.Encoding]::UTF8.GetBytes((@{ text = "Перевод: Дублированный | MovieDalen" } | ConvertTo-Json))
(Invoke-RestMethod -Uri http://127.0.0.1:8000/predict -Method Post -ContentType "application/json" -Body $b).tracks
```
Проверка живости: `Invoke-RestMethod http://127.0.0.1:8000/health`.
Ответ сервис отдаёт с `charset=utf-8`, поэтому кириллица в ответе
корректно декодируется и в PS 5.1.
## Путь Б: ONNX без Python ## Путь Б: ONNX без Python
Экспорт (из корня проекта, после обучения): Экспорт (из корня проекта, после обучения):
+1
View File
@@ -7,6 +7,7 @@
| `typescript/predict.mjs` | Node.js >= 18 | HTTP | CLI-клиент сервиса: `--text` / `--html`, без зависимостей | | `typescript/predict.mjs` | Node.js >= 18 | HTTP | CLI-клиент сервиса: `--text` / `--html`, без зависимостей |
| `typescript/predict.ts` | TypeScript | HTTP | то же с типами (`npx tsx predict.ts --text "..."`) | | `typescript/predict.ts` | TypeScript | HTTP | то же с типами (`npx tsx predict.ts --text "..."`) |
| `typescript/onnx_local.mjs` | Node.js | ONNX | локальный инференс без Python (`onnxruntime-node` + `@huggingface/transformers`) | | `typescript/onnx_local.mjs` | Node.js | ONNX | локальный инференс без Python (`onnxruntime-node` + `@huggingface/transformers`) |
| `powershell/predict.ps1` | PowerShell 5.1/7 | HTTP | `-Text "..."` / `-HtmlFile страница.html` (кириллица и кодировки учтены) |
| `rust/http_client` | Rust | HTTP | `cargo run -- --text "..."` / `--html файл` (reqwest + tokio) | | `rust/http_client` | Rust | HTTP | `cargo run -- --text "..."` / `--html файл` (reqwest + tokio) |
| `rust/onnx_local` | Rust | ONNX | локальный инференс (`ort` + `tokenizers`) | | `rust/onnx_local` | Rust | ONNX | локальный инференс (`ort` + `tokenizers`) |
+56
View File
@@ -0,0 +1,56 @@
# Вызов сервиса DUB-AI из PowerShell.
#
# Примеры (из корня проекта):
# powershell -NoProfile -ExecutionPolicy Bypass -File examples\powershell\predict.ps1 -Text "Перевод: Дублированный | MovieDalen"
# powershell -NoProfile -ExecutionPolicy Bypass -File examples\powershell\predict.ps1 -HtmlFile page.html
# pwsh -File examples\powershell\predict.ps1 -Text "..." -Url http://host:8000
#
# Тело запроса отправляется UTF-8 байтами — это одинаково работает и в
# Windows PowerShell 5.1, и в PowerShell 7 (в 5.1 строковый -Body без этого
# уходит в ISO-8859-1 и кириллица ломается).
param(
[string]$Url = "http://127.0.0.1:8000",
[Parameter(Mandatory = $true, ParameterSetName = 'Text')]
[string]$Text,
[Parameter(Mandatory = $true, ParameterSetName = 'Html')]
[string]$HtmlFile
)
$ErrorActionPreference = 'Stop'
try { [Console]::OutputEncoding = [Text.Encoding]::UTF8 } catch { }
if ($HtmlFile) {
# [IO.File]::ReadAllText даёт чистую строку (Get-Content прикрепляет
# свойства PSPath, и ConvertTo-Json отправил бы объект вместо строки)
$path = (Resolve-Path -LiteralPath $HtmlFile).Path
$html = [IO.File]::ReadAllText($path, [Text.Encoding]::UTF8)
if ($html.Contains([string][char]0xFFFD)) { # utf-8 не вышел — пробуем cp1251
$html = [IO.File]::ReadAllText($path, [Text.Encoding]::GetEncoding(1251))
}
$payload = @{ html = $html }
} else {
$payload = @{ text = $Text }
}
$json = $payload | ConvertTo-Json
$bytes = [Text.Encoding]::UTF8.GetBytes($json)
try {
$r = Invoke-RestMethod -Uri "$Url/predict" -Method Post `
-ContentType 'application/json' -Body $bytes
} catch {
Write-Error "Сервис недоступен ($Url). Запуск: python -m src.service`n$_"
exit 1
}
if ($r.tracks) {
$r.tracks | Format-Table translation_type, studio, is_18plus,
type_confidence -AutoSize
foreach ($t in $r.tracks) {
" текст: $($t.segment)"
if ($t.studio_span) { " спан: $($t.studio_span)" }
}
} else {
"дорожки озвучки не найдены"
}
+13 -1
View File
@@ -14,11 +14,22 @@ from __future__ import annotations
import argparse import argparse
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel from pydantic import BaseModel
from .predict import DubPredictor from .predict import DubPredictor
class Utf8JSONResponse(JSONResponse):
"""application/json с явным charset=utf-8.
Без этого Windows PowerShell 5.1 (Invoke-RestMethod) декодирует ответ
как ISO-8859-1 и кириллица превращается в «кракозябры».
"""
media_type = "application/json; charset=utf-8"
class PredictRequest(BaseModel): class PredictRequest(BaseModel):
"""Либо text (одна дорожка), либо html (страница целиком).""" """Либо text (одна дорожка), либо html (страница целиком)."""
text: str | None = None text: str | None = None
@@ -27,7 +38,8 @@ class PredictRequest(BaseModel):
def create_app(predictor: DubPredictor) -> FastAPI: def create_app(predictor: DubPredictor) -> FastAPI:
app = FastAPI(title="DUB-AI", version="0.1.0", app = FastAPI(title="DUB-AI", version="0.1.0",
description="Тип озвучки + автор озвучки") description="Тип озвучки + автор озвучки",
default_response_class=Utf8JSONResponse)
@app.get("/health") @app.get("/health")
def health(): def health():