API
Note
Questa documentazione potrebbe contenere contenuti generati dall'IA. Sebbene ci impegniamo per l'accuratezza, potrebbero esserci delle imprecisioni. Si prega di segnalare eventuali problemi tramite:
- GitHub Issues
- Contributo della comunità (PR sono benvenuti!)
Python API: do_translate_async_stream
Panoramica
- do_translate_async_stream è il punto di ingresso asincrono di basso livello che traduce un singolo PDF e restituisce un flusso di eventi (progresso/errore/fine).
- È adatto per costruire la propria UI o CLI in cui si desidera un progresso in tempo reale e il controllo completo sui risultati.
- Accetta un SettingsModel validato e un percorso del file e restituisce un generatore asincrono di eventi dict.
Firma
- Import:
from pdf2zh_next.high_level import do_translate_async_stream - Chiamata:
async for event in do_translate_async_stream(settings, file): ... - Parametri:
- settings: SettingsModel. Deve essere valido; la funzione chiamerà
settings.validate_settings(). - file: str | pathlib.Path. Il singolo PDF da tradurre. Deve esistere.
NOTE
settings.basic.input_filesviene ignorato da questa funzione; viene tradotto solo ilfilespecificato.- Se
settings.basic.debugè True, la traduzione viene eseguita nel processo principale; altrimenti viene eseguita in un sottoprocesso. Lo schema degli eventi è identico in entrambi i casi.
Contratto del flusso di eventi
Il generatore asincrono produce eventi di tipo dict simili a JSON con i seguenti tipi:
- Evento di riepilogo fase:
stage_summary(opzionale, può apparire per primo) -
Campi
type: "stage_summary"stages: lista di oggetti{ "name": str, "percent": float }che descrivono la distribuzione stimata del lavoropart_index: può essere 0 per questo evento di riepilogototal_parts: numero totale di parti (>= 1)
-
Eventi di avanzamento:
progress_start,progress_update,progress_end -
Campi comuni
type: uno dei precedentistage: nome della fase leggibile dall'uomo (ad es. "Analizza PDF e Crea Rappresentazione Intermedia", "Traduci Paragrafi", "Salva PDF")stage_progress: float in [0, 100] che indica l'avanzamento all'interno della fase correnteoverall_progress: float in [0, 100] che indica l'avanzamento complessivopart_index: indice della parte corrente (tipicamente basato su 1 per gli eventi di avanzamento)total_parts: numero totale di parti (>= 1). Documenti di grandi dimensioni possono essere suddivisi automaticamente.stage_current: passo corrente all'interno della fasestage_total: passi totali all'interno della fase
-
Evento di completamento:
finish -
Campi
type: "finish"translate_result: un oggetto che fornisce gli output finali (NOTA: non un dizionario, ma un'istanza di classe)original_pdf_path: Percorso del PDF di inputmono_pdf_path: Percorso del PDF tradotto monolingue (o None)dual_pdf_path: Percorso del PDF tradotto bilingue (o None)no_watermark_mono_pdf_path: Percorso dell'output monolingue senza filigrana (se prodotto), altrimenti Noneno_watermark_dual_pdf_path: Percorso dell'output bilingue senza filigrana (se prodotto), altrimenti Noneauto_extracted_glossary_path: Percorso del glossario CSV estratto automaticamente (o None)total_seconds: secondi trascorsi (float)peak_memory_usage: utilizzo approssimativo della memoria di picco durante la traduzione (float; unità dipendenti dall'implementazione)
-
Evento di errore:
error - Campi
type: "error"error: messaggio di errore leggibile dall'uomoerror_type: uno traBabeldocError,SubprocessError,IPCError,SubprocessCrashError, ecc.details: dettagli opzionali (ad es. errore originale o traceback)
Comportamento importante: - Un stage_summary opzionale può essere emesso prima che il progresso inizi. - In caso di determinati fallimenti, il generatore emetterà prima un evento error e poi solleverà un'eccezione derivata da TranslationError. Dovresti sia controllare la presenza di eventi di errore che essere pronto a catturare le eccezioni. - Gli eventi progress_update possono ripetersi con valori identici; i consumatori dovrebbero eseguire il debounce se necessario. - Interrompi il consumo del flusso quando ricevi un evento finish.
Esempio di utilizzo minimo (Async)
import asyncio
from pathlib import Path
from pdf2zh_next.high_level import do_translate_async_stream
# Assume you already have a valid SettingsModel instance named `settings`
# and a PDF file path
async def translate_one(settings, pdf_path: str | Path):
try:
async for event in do_translate_async_stream(settings, pdf_path):
etype = event.get("type")
if etype == "stage_summary":
# Optional pre-flight summary of stages
stages = event.get("stages", [])
print("Stage summary:", ", ".join(f"{s['name']}:{s['percent']:.2f}" for s in stages))
elif etype in {"progress_start", "progress_update", "progress_end"}:
stage = event.get("stage")
stage_prog = event.get("stage_progress") # 0..100
overall = event.get("overall_progress") # 0..100
part_i = event.get("part_index")
part_n = event.get("total_parts")
print(f"[{etype}] {stage} | stage {stage_prog:.1f}% | overall {overall:.1f}% (part {part_i}/{part_n})")
elif etype == "error":
# You will also get a raised exception after this yield
print("[error]", event.get("error"), event.get("error_type"))
elif etype == "finish":
result = event["translate_result"]
print("Done in", getattr(result, "total_seconds", None), "s")
print("Mono:", getattr(result, "mono_pdf_path", None))
print("Dual:", getattr(result, "dual_pdf_path", None))
print("No-watermark Mono:", getattr(result, "no_watermark_mono_pdf_path", None))
print("No-watermark Dual:", getattr(result, "no_watermark_dual_pdf_path", None))
print("Glossary:", getattr(result, "auto_extracted_glossary_path", None))
print("Peak memory:", getattr(result, "peak_memory_usage", None))
break
except Exception as exc:
# Catch exceptions raised by the stream after an error event
print("Translation failed:", exc)
# asyncio.run(translate_one(settings, "/path/to/file.pdf"))
Annullamento
Puoi annullare l'attività consumando il flusso. L'annullamento viene propagato al processo di traduzione sottostante.
import asyncio
from pdf2zh_next.high_level import do_translate_async_stream
async def cancellable(settings, pdf):
task = asyncio.create_task(_consume(settings, pdf))
await asyncio.sleep(1.0) # let it start
task.cancel()
try:
await task
except asyncio.CancelledError:
print("Cancelled")
async def _consume(settings, pdf):
async for event in do_translate_async_stream(settings, pdf):
if event["type"] == "finish":
break
Forme di Evento di Esempio
Riepilogo dello stage evento (esempio):
{
"type": "stage_summary",
"stages": [
{"name": "Parse PDF and Create Intermediate Representation", "percent": 0.1086},
{"name": "DetectScannedFile", "percent": 0.0188},
{"name": "Parse Page Layout", "percent": 0.1079}
// ... more stages ...
],
"part_index": 0,
"total_parts": 1
}
Progress event (esempio):
{
"type": "progress_update",
"stage": "Translate Paragraphs",
"stage_progress": 2.04,
"stage_current": 1,
"stage_total": 49,
"overall_progress": 53.44,
"part_index": 1,
"total_parts": 1
}
Finish event (esempio):
{
"type": "finish",
"translate_result": {
"original_pdf_path": "pdf2zh_files/<session>/table.pdf",
"mono_pdf_path": "pdf2zh_files/<session>/table.zh-CN.mono.pdf",
"dual_pdf_path": "pdf2zh_files/<session>/table.zh-CN.dual.pdf",
"no_watermark_mono_pdf_path": "pdf2zh_files/<session>/table.no_watermark.zh-CN.mono.pdf",
"no_watermark_dual_pdf_path": "pdf2zh_files/<session>/table.no_watermark.zh-CN.dual.pdf",
"auto_extracted_glossary_path": "pdf2zh_files/<session>/table.zh-CN.glossary.csv",
"total_seconds": 42.83,
"peak_memory_usage": 4651.55
}
}
Evento di errore (esempio):
{
"type": "error",
"error": "Babeldoc translation error: <message>",
"error_type": "BabeldocError",
"details": "<optional original error or traceback>"
}
Note e migliori pratiche
- Gestire sempre sia gli eventi di errore che le eccezioni dal generatore.
- Interrompere il ciclo su
finishper evitare lavoro non necessario. - Assicurarsi che il
fileesista e chesettings.validate_settings()passi prima della chiamata. - I documenti di grandi dimensioni potrebbero essere divisi; utilizzare
part_index/total_partseoverall_progressper guidare la tua UI. - Debounce
progress_updatese la tua UI è sensibile a ripetuti aggiornamenti identici. report_interval(SettingsModel): controlla solo la frequenza di emissione degli eventiprogress_update. Non influisce sustage_summary,progress_start,progress_endofinish. Il valore predefinito è 0.1s e il minimo consentito è 0.05s. Come da logica del monitor di avanzamento, quandostage_total <= 3, gli aggiornamenti non sono limitati dareport_interval.