0fd2f875
tangwang
translate
|
1
|
"""Translator service HTTP app."""
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
2
|
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
3
|
import argparse
|
1e370dc9
tangwang
1. 翻译性能优化
|
4
|
import asyncio
|
0fd2f875
tangwang
translate
|
5
|
import logging
|
cd4ce66d
tangwang
trans logs
|
6
7
8
|
import os
import pathlib
import time
|
14e67b71
tangwang
分句后的 batching 现在是...
|
9
|
import uuid
|
0fd2f875
tangwang
translate
|
10
|
from contextlib import asynccontextmanager
|
1e370dc9
tangwang
1. 翻译性能优化
|
11
|
from functools import lru_cache, partial
|
cd4ce66d
tangwang
trans logs
|
12
|
from logging.handlers import TimedRotatingFileHandler
|
0fd2f875
tangwang
translate
|
13
14
|
from typing import List, Optional, Union
|
1e370dc9
tangwang
1. 翻译性能优化
|
15
|
import anyio
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
16
|
import uvicorn
|
14e67b71
tangwang
分句后的 batching 现在是...
|
17
|
from fastapi import FastAPI, HTTPException, Request
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
18
|
from fastapi.middleware.cors import CORSMiddleware
|
0fd2f875
tangwang
translate
|
19
20
|
from fastapi.responses import JSONResponse
from pydantic import BaseModel, ConfigDict, Field
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
21
|
|
d4cadc13
tangwang
翻译重构
|
22
|
from config.services_config import get_translation_config
|
14e67b71
tangwang
分句后的 batching 现在是...
|
23
24
25
26
27
|
from translation.logging_utils import (
TranslationRequestFilter,
bind_translation_request_id,
reset_translation_request_id,
)
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
28
|
from translation.service import TranslationService
|
0fd2f875
tangwang
translate
|
29
30
31
32
33
|
from translation.settings import (
get_enabled_translation_models,
normalize_translation_model,
normalize_translation_scene,
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
34
|
|
cd4ce66d
tangwang
trans logs
|
35
36
37
38
39
40
41
42
43
|
def configure_translator_logging() -> None:
log_dir = pathlib.Path("logs")
verbose_dir = log_dir / "verbose"
log_dir.mkdir(exist_ok=True)
verbose_dir.mkdir(parents=True, exist_ok=True)
log_level = os.getenv("LOG_LEVEL", "INFO").upper()
numeric_level = getattr(logging, log_level, logging.INFO)
|
14e67b71
tangwang
分句后的 batching 现在是...
|
44
45
|
formatter = logging.Formatter("%(asctime)s | reqid:%(reqid)s | %(name)s | %(levelname)s | %(message)s")
request_filter = TranslationRequestFilter()
|
cd4ce66d
tangwang
trans logs
|
46
47
48
49
50
51
52
53
|
root_logger = logging.getLogger()
root_logger.setLevel(numeric_level)
root_logger.handlers.clear()
console_handler = logging.StreamHandler()
console_handler.setLevel(numeric_level)
console_handler.setFormatter(formatter)
|
14e67b71
tangwang
分句后的 batching 现在是...
|
54
|
console_handler.addFilter(request_filter)
|
cd4ce66d
tangwang
trans logs
|
55
56
57
58
59
60
61
62
63
64
65
|
root_logger.addHandler(console_handler)
file_handler = TimedRotatingFileHandler(
filename=log_dir / "translator_api.log",
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
)
file_handler.setLevel(numeric_level)
file_handler.setFormatter(formatter)
|
14e67b71
tangwang
分句后的 batching 现在是...
|
66
|
file_handler.addFilter(request_filter)
|
cd4ce66d
tangwang
trans logs
|
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
root_logger.addHandler(file_handler)
verbose_logger = logging.getLogger("translator.verbose")
verbose_logger.setLevel(numeric_level)
verbose_logger.handlers.clear()
verbose_logger.propagate = False
verbose_handler = TimedRotatingFileHandler(
filename=verbose_dir / "translator_verbose.log",
when="midnight",
interval=1,
backupCount=30,
encoding="utf-8",
)
verbose_handler.setLevel(numeric_level)
verbose_handler.setFormatter(formatter)
|
14e67b71
tangwang
分句后的 batching 现在是...
|
83
|
verbose_handler.addFilter(request_filter)
|
cd4ce66d
tangwang
trans logs
|
84
85
86
87
|
verbose_logger.addHandler(verbose_handler)
configure_translator_logging()
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
88
|
logger = logging.getLogger(__name__)
|
cd4ce66d
tangwang
trans logs
|
89
|
verbose_logger = logging.getLogger("translator.verbose")
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
90
|
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
91
|
|
0fd2f875
tangwang
translate
|
92
|
@lru_cache(maxsize=1)
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
93
|
def get_translation_service() -> TranslationService:
|
0fd2f875
tangwang
translate
|
94
|
return TranslationService(get_translation_config())
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
95
96
|
|
1e370dc9
tangwang
1. 翻译性能优化
|
97
98
99
100
101
102
103
104
105
106
107
|
_TRANSLATION_MAX_INFLIGHT = int(os.getenv("TRANSLATION_MAX_INFLIGHT", "4"))
_translation_inflight_semaphore = asyncio.Semaphore(max(1, _TRANSLATION_MAX_INFLIGHT))
async def _run_translation_blocking(fn, /, *args, **kwargs):
"""Run blocking translation work in a thread with bounded concurrency."""
bound = partial(fn, *args, **kwargs)
async with _translation_inflight_semaphore:
return await anyio.to_thread.run_sync(bound)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
108
109
110
|
# Request/Response models
class TranslationRequest(BaseModel):
"""Translation request model."""
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
111
|
|
0fd2f875
tangwang
translate
|
112
113
|
model_config = ConfigDict(
json_schema_extra={
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
114
115
116
|
"example": {
"text": "商品名称",
"target_lang": "en",
|
3cd09b3b
tangwang
翻译接口改为调用qwen-mt-f...
|
117
|
"source_lang": "zh",
|
d4cadc13
tangwang
翻译重构
|
118
|
"model": "llm",
|
0fd2f875
tangwang
translate
|
119
|
"scene": "sku_name",
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
120
121
|
}
}
|
0fd2f875
tangwang
translate
|
122
123
124
125
126
127
128
|
)
text: Union[str, List[str]] = Field(..., description="Text to translate (string or list of strings)")
target_lang: str = Field(..., description="Target language code (zh, en, ru, etc.)")
source_lang: Optional[str] = Field(None, description="Source language code (optional, auto-detect if not provided)")
model: Optional[str] = Field(None, description="Enabled translation capability name")
scene: Optional[str] = Field(None, description="Translation scene, paired with model routing")
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
129
130
131
132
|
class TranslationResponse(BaseModel):
"""Translation response model."""
|
6f7840cf
tangwang
refactor: rename ...
|
133
|
text: Union[str, List[str]] = Field(..., description="Original text (string or list)")
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
134
135
|
target_lang: str = Field(..., description="Target language code")
source_lang: Optional[str] = Field(None, description="Source language code (detected or provided)")
|
6f7840cf
tangwang
refactor: rename ...
|
136
137
138
139
|
translated_text: Union[str, List[Optional[str]]] = Field(
...,
description="Translated text (string or list; list elements may be null on failure)",
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
140
|
status: str = Field(..., description="Translation status")
|
3cd09b3b
tangwang
翻译接口改为调用qwen-mt-f...
|
141
|
model: str = Field(..., description="Translation model used")
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
142
|
scene: str = Field(..., description="Translation scene used")
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
143
144
|
|
0fd2f875
tangwang
translate
|
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
def _normalize_scene(service: TranslationService, scene: Optional[str]) -> str:
return normalize_translation_scene(service.config, scene)
def _normalize_model(service: TranslationService, model: Optional[str]) -> str:
return normalize_translation_model(service.config, model or service.config["default_model"])
def _ensure_valid_text(text: Union[str, List[str]]) -> None:
if isinstance(text, list):
if not text:
raise HTTPException(status_code=400, detail="Text list cannot be empty")
return
if not text or not text.strip():
raise HTTPException(status_code=400, detail="Text cannot be empty")
def _normalize_batch_result(
original: List[str],
translated: Union[str, List[Optional[str]], None],
) -> List[Optional[str]]:
if translated is None:
return [None for _ in original]
if not isinstance(translated, list):
raise HTTPException(status_code=500, detail="Batch translation provider returned non-list result")
return [translated[idx] if idx < len(translated) else None for idx, _ in enumerate(original)]
|
cd4ce66d
tangwang
trans logs
|
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
def _text_preview(text: Optional[str], limit: int = 20) -> str:
normalized = str(text or "").replace("\n", "\\n")
return normalized[:limit]
def _request_metrics(text: Union[str, List[str]]) -> dict:
if isinstance(text, list):
lengths = [len(str(item or "")) for item in text]
return {
"request_count": len(text),
"lengths": lengths,
"first_preview": _text_preview(text[0] if text else ""),
}
return {
"request_count": 1,
"lengths": [len(str(text or ""))],
"first_preview": _text_preview(str(text or "")),
}
def _result_preview(translated: Union[str, List[Optional[str]], None]) -> str:
if isinstance(translated, list):
if not translated:
return ""
first = translated[0]
return _text_preview("" if first is None else str(first))
if translated is None:
return ""
return _text_preview(str(translated))
|
14e67b71
tangwang
分句后的 batching 现在是...
|
204
205
206
207
208
209
210
|
def _resolve_request_id(http_request: Request) -> str:
header_value = http_request.headers.get("X-Request-ID")
if header_value and header_value.strip():
return header_value.strip()[:32]
return str(uuid.uuid4())[:8]
|
0fd2f875
tangwang
translate
|
211
212
213
214
215
216
217
218
219
220
|
def _translate_batch(
service: TranslationService,
raw_text: List[str],
*,
target_lang: str,
source_lang: Optional[str],
model: str,
scene: str,
) -> List[Optional[str]]:
backend = service.get_backend(model)
|
cd4ce66d
tangwang
trans logs
|
221
|
logger.info(
|
14e67b71
tangwang
分句后的 batching 现在是...
|
222
223
|
"Translation batch dispatch | execution=%s count=%s lengths=%s first_preview=%s",
"backend-batch" if getattr(backend, "supports_batch", False) else "per-item",
|
cd4ce66d
tangwang
trans logs
|
224
225
226
|
len(raw_text),
[len(str(item or "")) for item in raw_text],
_text_preview(raw_text[0] if raw_text else ""),
|
cd4ce66d
tangwang
trans logs
|
227
|
)
|
0fd2f875
tangwang
translate
|
228
229
230
231
232
233
234
235
236
|
if getattr(backend, "supports_batch", False):
try:
translated = service.translate(
text=raw_text,
target_lang=target_lang,
source_lang=source_lang,
model=model,
scene=scene,
)
|
cd4ce66d
tangwang
trans logs
|
237
238
239
240
241
242
243
|
verbose_logger.info(
"Translation batch result | model=%s scene=%s count=%s first_result=%s",
model,
scene,
len(raw_text),
_result_preview(translated),
)
|
0fd2f875
tangwang
translate
|
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
|
return _normalize_batch_result(raw_text, translated)
except ValueError:
raise
except Exception as exc:
logger.error("Batch translation failed: %s", exc, exc_info=True)
results: List[Optional[str]] = []
for item in raw_text:
if item is None or not str(item).strip():
results.append(item) # type: ignore[arg-type]
continue
try:
out = service.translate(
text=str(item),
target_lang=target_lang,
source_lang=source_lang,
model=model,
scene=scene,
)
except ValueError:
raise
except Exception as exc:
|
cd4ce66d
tangwang
trans logs
|
266
267
268
269
270
271
272
273
274
275
276
|
logger.warning(
"Per-item translation failed | model=%s scene=%s target_lang=%s source_lang=%s item_len=%s item_preview=%s error=%s",
model,
scene,
target_lang,
source_lang or "auto",
len(str(item or "")),
_text_preview(str(item or "")),
exc,
exc_info=True,
)
|
0fd2f875
tangwang
translate
|
277
278
279
280
281
282
283
|
out = None
results.append(out)
return results
@asynccontextmanager
async def lifespan(_: FastAPI):
|
cd4ce66d
tangwang
trans logs
|
284
|
"""Initialize all enabled translation backends on process startup."""
|
0fd2f875
tangwang
translate
|
285
286
|
logger.info("Starting Translation Service API")
service = get_translation_service()
|
f07947a5
tangwang
Improve portabili...
|
287
288
|
failed_models = list(getattr(service, "failed_models", []))
backend_errors = dict(getattr(service, "backend_errors", {}))
|
0fd2f875
tangwang
translate
|
289
|
logger.info(
|
f07947a5
tangwang
Improve portabili...
|
290
|
"Translation service ready | default_model=%s default_scene=%s available_models=%s loaded_models=%s failed_models=%s",
|
0fd2f875
tangwang
translate
|
291
|
service.config["default_model"],
|
cd4ce66d
tangwang
trans logs
|
292
|
service.config["default_scene"],
|
0fd2f875
tangwang
translate
|
293
294
|
service.available_models,
service.loaded_models,
|
f07947a5
tangwang
Improve portabili...
|
295
|
failed_models,
|
0fd2f875
tangwang
translate
|
296
297
|
)
logger.info(
|
f07947a5
tangwang
Improve portabili...
|
298
|
"Translation backends initialized on startup | loaded=%s failed=%s",
|
cd4ce66d
tangwang
trans logs
|
299
|
service.loaded_models,
|
f07947a5
tangwang
Improve portabili...
|
300
|
backend_errors,
|
cd4ce66d
tangwang
trans logs
|
301
302
303
304
305
306
|
)
verbose_logger.info(
"Translation startup detail | capabilities=%s cache_ttl_seconds=%s cache_sliding_expiration=%s",
service.available_models,
service.config["cache"]["ttl_seconds"],
service.config["cache"]["sliding_expiration"],
|
0fd2f875
tangwang
translate
|
307
308
309
310
|
)
yield
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
311
312
313
|
# Create FastAPI app
app = FastAPI(
title="Translation Service API",
|
0fd2f875
tangwang
translate
|
314
|
description="Translation service with pluggable capabilities and scene routing",
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
315
316
|
version="1.0.0",
docs_url="/docs",
|
0fd2f875
tangwang
translate
|
317
318
|
redoc_url="/redoc",
lifespan=lifespan,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
319
320
321
322
323
324
325
326
327
328
329
330
|
)
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
331
332
333
334
|
@app.get("/health")
async def health_check():
"""Health check endpoint."""
try:
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
335
|
service = get_translation_service()
|
f07947a5
tangwang
Improve portabili...
|
336
337
|
failed_models = list(getattr(service, "failed_models", []))
backend_errors = dict(getattr(service, "backend_errors", {}))
|
cd4ce66d
tangwang
trans logs
|
338
|
logger.info(
|
f07947a5
tangwang
Improve portabili...
|
339
|
"Health check | default_model=%s default_scene=%s loaded_models=%s failed_models=%s",
|
cd4ce66d
tangwang
trans logs
|
340
341
342
|
service.config["default_model"],
service.config["default_scene"],
service.loaded_models,
|
f07947a5
tangwang
Improve portabili...
|
343
|
failed_models,
|
cd4ce66d
tangwang
trans logs
|
344
|
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
345
346
347
|
return {
"status": "healthy",
"service": "translation",
|
1e370dc9
tangwang
1. 翻译性能优化
|
348
|
"max_inflight": _TRANSLATION_MAX_INFLIGHT,
|
0fd2f875
tangwang
translate
|
349
350
|
"default_model": service.config["default_model"],
"default_scene": service.config["default_scene"],
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
351
|
"available_models": service.available_models,
|
0fd2f875
tangwang
translate
|
352
353
|
"enabled_capabilities": get_enabled_translation_models(service.config),
"loaded_models": service.loaded_models,
|
f07947a5
tangwang
Improve portabili...
|
354
355
|
"failed_models": failed_models,
"backend_errors": backend_errors,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
356
357
358
359
360
361
362
363
364
365
366
367
368
|
}
except Exception as e:
logger.error(f"Health check failed: {e}")
return JSONResponse(
status_code=503,
content={
"status": "unhealthy",
"error": str(e)
}
)
@app.post("/translate", response_model=TranslationResponse)
|
14e67b71
tangwang
分句后的 batching 现在是...
|
369
|
async def translate(request: TranslationRequest, http_request: Request):
|
0fd2f875
tangwang
translate
|
370
371
|
_ensure_valid_text(request.text)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
372
|
if not request.target_lang:
|
0fd2f875
tangwang
translate
|
373
374
|
raise HTTPException(status_code=400, detail="target_lang is required")
|
14e67b71
tangwang
分句后的 batching 现在是...
|
375
|
_, request_token = bind_translation_request_id(_resolve_request_id(http_request))
|
cd4ce66d
tangwang
trans logs
|
376
|
request_started = time.perf_counter()
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
377
|
try:
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
378
|
service = get_translation_service()
|
0fd2f875
tangwang
translate
|
379
380
|
scene = _normalize_scene(service, request.scene)
model = _normalize_model(service, request.model)
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
381
|
translator = service.get_backend(model)
|
6f7840cf
tangwang
refactor: rename ...
|
382
|
raw_text = request.text
|
cd4ce66d
tangwang
trans logs
|
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
|
metrics = _request_metrics(raw_text)
logger.info(
"Translation request | model=%s scene=%s target_lang=%s source_lang=%s count=%s lengths=%s first_preview=%s backend=%s",
model,
scene,
request.target_lang,
request.source_lang or "auto",
metrics["request_count"],
metrics["lengths"],
metrics["first_preview"],
getattr(translator, "model", model),
)
verbose_logger.info(
"Translation request detail | model=%s scene=%s target_lang=%s source_lang=%s payload=%s",
model,
scene,
request.target_lang,
request.source_lang or "auto",
raw_text,
)
|
6f7840cf
tangwang
refactor: rename ...
|
403
|
|
6f7840cf
tangwang
refactor: rename ...
|
404
|
if isinstance(raw_text, list):
|
1e370dc9
tangwang
1. 翻译性能优化
|
405
406
|
results = await _run_translation_blocking(
_translate_batch,
|
0fd2f875
tangwang
translate
|
407
408
409
410
411
412
413
|
service,
raw_text,
target_lang=request.target_lang,
source_lang=request.source_lang,
model=model,
scene=scene,
)
|
cd4ce66d
tangwang
trans logs
|
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
latency_ms = (time.perf_counter() - request_started) * 1000
logger.info(
"Translation response | model=%s scene=%s count=%s first_result=%s latency_ms=%.2f",
model,
scene,
len(raw_text),
_result_preview(results),
latency_ms,
)
verbose_logger.info(
"Translation response detail | model=%s scene=%s translated=%s latency_ms=%.2f",
model,
scene,
results,
latency_ms,
)
|
6f7840cf
tangwang
refactor: rename ...
|
430
431
432
433
434
435
436
|
return TranslationResponse(
text=raw_text,
target_lang=request.target_lang,
source_lang=request.source_lang,
translated_text=results,
status="success",
model=str(getattr(translator, "model", model)),
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
437
|
scene=scene,
|
6f7840cf
tangwang
refactor: rename ...
|
438
439
|
)
|
1e370dc9
tangwang
1. 翻译性能优化
|
440
441
|
translated_text = await _run_translation_blocking(
service.translate,
|
6f7840cf
tangwang
refactor: rename ...
|
442
|
text=raw_text,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
443
444
|
target_lang=request.target_lang,
source_lang=request.source_lang,
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
445
446
|
model=model,
scene=scene,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
447
|
)
|
6f7840cf
tangwang
refactor: rename ...
|
448
|
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
449
|
if translated_text is None:
|
0fd2f875
tangwang
translate
|
450
|
raise HTTPException(status_code=500, detail="Translation failed")
|
6f7840cf
tangwang
refactor: rename ...
|
451
|
|
cd4ce66d
tangwang
trans logs
|
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
|
latency_ms = (time.perf_counter() - request_started) * 1000
logger.info(
"Translation response | model=%s scene=%s count=1 first_result=%s latency_ms=%.2f",
model,
scene,
_result_preview(translated_text),
latency_ms,
)
verbose_logger.info(
"Translation response detail | model=%s scene=%s translated=%s latency_ms=%.2f",
model,
scene,
translated_text,
latency_ms,
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
468
|
return TranslationResponse(
|
6f7840cf
tangwang
refactor: rename ...
|
469
|
text=raw_text,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
470
471
472
|
target_lang=request.target_lang,
source_lang=request.source_lang,
translated_text=translated_text,
|
3cd09b3b
tangwang
翻译接口改为调用qwen-mt-f...
|
473
|
status="success",
|
5e4dc8e4
tangwang
翻译架构按“一个翻译服务 +
|
474
475
|
model=str(getattr(translator, "model", model)),
scene=scene,
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
476
477
|
)
|
cd4ce66d
tangwang
trans logs
|
478
479
480
481
482
483
484
485
|
except HTTPException as exc:
latency_ms = (time.perf_counter() - request_started) * 1000
logger.warning(
"Translation request failed | status_code=%s detail=%s latency_ms=%.2f",
exc.status_code,
exc.detail,
latency_ms,
)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
486
|
raise
|
0fd2f875
tangwang
translate
|
487
|
except ValueError as e:
|
cd4ce66d
tangwang
trans logs
|
488
|
latency_ms = (time.perf_counter() - request_started) * 1000
|
14e67b71
tangwang
分句后的 batching 现在是...
|
489
|
logger.warning("Translation validation error | error=%s latency_ms=%.2f", e, latency_ms)
|
0fd2f875
tangwang
translate
|
490
|
raise HTTPException(status_code=400, detail=str(e)) from e
|
f07947a5
tangwang
Improve portabili...
|
491
492
493
494
|
except RuntimeError as e:
latency_ms = (time.perf_counter() - request_started) * 1000
logger.warning("Translation backend unavailable | error=%s latency_ms=%.2f", e, latency_ms)
raise HTTPException(status_code=503, detail=str(e)) from e
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
495
|
except Exception as e:
|
cd4ce66d
tangwang
trans logs
|
496
497
|
latency_ms = (time.perf_counter() - request_started) * 1000
logger.error("Translation error | error=%s latency_ms=%.2f", e, latency_ms, exc_info=True)
|
0fd2f875
tangwang
translate
|
498
|
raise HTTPException(status_code=500, detail=f"Translation error: {str(e)}")
|
14e67b71
tangwang
分句后的 batching 现在是...
|
499
500
|
finally:
reset_translation_request_id(request_token)
|
768ad710
tangwang
MySQL到ES字段映射说明-业务...
|
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
|
@app.get("/")
async def root():
"""Root endpoint with API information."""
return {
"service": "Translation Service API",
"version": "1.0.0",
"status": "running",
"endpoints": {
"translate": "POST /translate",
"health": "GET /health",
"docs": "GET /docs"
}
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Start translation API service')
parser.add_argument('--host', default='0.0.0.0', help='Host to bind to')
parser.add_argument('--port', type=int, default=6006, help='Port to bind to')
parser.add_argument('--reload', action='store_true', help='Enable auto-reload')
args = parser.parse_args()
# Run server
uvicorn.run(
"api.translator_app:app",
host=args.host,
port=args.port,
reload=args.reload
)
|