Robustly wire email subjects from env vars with safe fallbacks and logging
Mirror and run GitLab CI / build (push) Has been cancelled
Ruff / ruff (push) Has been cancelled

This commit is contained in:
admin
2026-06-14 16:31:03 +00:00
parent a8f48b9e58
commit f7c9c70bfc
+24 -36
View File
@@ -39,7 +39,6 @@ def _safe_filename(base: str, local: str, date_tag: str, ext: str) -> str:
Uses mktemp for uniqueness but keeps the desired name pattern.
"""
name = f"{base}-{local}-{date_tag}{ext}"
# Ensure uniqueness while preserving the logical name pattern
return tempfile.mktemp(prefix=name.replace(".", ""), suffix=ext)
@@ -56,6 +55,17 @@ def _remove_file(path: str):
logger.warning("Failed to remove file %s: %s", path, e)
def _get_subject(env_var: str, default: str) -> str:
"""
Safely read an email subject from an environment variable.
Uses default if unset or blank. Logs the final value.
"""
value = (os.getenv(env_var) or "").strip()
subject = value or default
logger.info("Email subject [%s] = %s", env_var, subject)
return subject
def get_queue_position(task_id: str) -> int:
"""
Estimate the job's position in the queue.
@@ -80,12 +90,11 @@ def send_initial_email(to: str, queue_pos: int):
Send initial confirmation email with queue position.
Subject is customizable via EMAIL_SUBJECT_UPLOAD.
"""
subject = os.getenv(
subject = _get_subject(
"EMAIL_SUBJECT_UPLOAD",
"ScrAIbe: Your transcription request has been received",
)
# Build plain-text fallback
body = (
"Hello,\n\n"
"We have received your audio file for transcription.\n"
@@ -105,7 +114,6 @@ def send_initial_email(to: str, queue_pos: int):
"This is an automated message from ScrAIbe.\n"
)
# Build HTML using template; only dynamic value is queue_position
html = None
try:
html = load_template(
@@ -133,12 +141,11 @@ def send_success_email(
Send final email with transcript and attachments.
Subject is customizable via EMAIL_SUBJECT_SUCCESS.
"""
subject = os.getenv(
subject = _get_subject(
"EMAIL_SUBJECT_SUCCESS",
"ScrAIbe: Your transcript is ready",
)
# Build plain-text fallback
body = (
"Hello,\n\n"
"Your transcription is ready.\n\n"
@@ -161,12 +168,9 @@ def send_success_email(
"This is an automated message from ScrAIbe.\n"
)
# Build HTML using template; no dynamic placeholders needed
html = None
try:
html = load_template(
"success_template.html",
)
html = load_template("success_template.html")
except EmailError as e:
logger.warning("Failed to render success template: %s", e)
@@ -188,12 +192,11 @@ def send_error_email(to: str, error_message: str, task_id: str):
Send error notification email.
Subject is customizable via EMAIL_SUBJECT_ERROR.
"""
subject = os.getenv(
subject = _get_subject(
"EMAIL_SUBJECT_ERROR",
"ScrAIbe: Error with your transcription request",
)
# Build plain-text fallback
body = (
"Hello,\n\n"
"We encountered an error while processing your transcription request.\n\n"
@@ -205,7 +208,6 @@ def send_error_email(to: str, error_message: str, task_id: str):
"This is an automated message from ScrAIbe.\n"
)
# Build HTML using template; only dynamic placeholder is exception
html = None
try:
html = load_template(
@@ -243,19 +245,15 @@ def process_transcription_task(
"""
task_id = self.request.id
# Ensure logging
log_level = os.getenv("LOG_LEVEL", "INFO")
setup_logging(level=log_level)
# Track all temporary files to clean up later
temp_files = []
# Derive naming components
local = _local_part(email_to)
date_tag = _date_tag()
try:
# 1) Determine queue position and send initial email
# 1) Queue position and initial email
queue_pos = get_queue_position(task_id)
send_initial_email(to=email_to, queue_pos=queue_pos)
@@ -270,7 +268,7 @@ def process_transcription_task(
)
raise
# 3) Perform transcription
# 3) Transcription
if task_type == "transcript_and_summarize":
result = scraibe.transcript_and_summarize(
audio_file=audio_path,
@@ -296,21 +294,21 @@ def process_transcription_task(
segments = result.get("segments", [])
raw_result = result.get("raw_result")
# 4) Prepare files for email with required naming
# 4) Prepare files
# Transcript as .md
# Transcript .md
md_transcript_path = _safe_filename("TRANSCRIPT", local, date_tag, ".md")
with open(md_transcript_path, "w", encoding="utf-8") as f:
f.write("# Transcript\n\n")
f.write(transcript_text)
temp_files.append(md_transcript_path)
# Transcript as .docx (with required style)
# Transcript .docx
docx_transcript_path = _safe_filename("TRANSCRIPT", local, date_tag, ".docx")
create_transcript_docx(transcript_text, docx_transcript_path)
temp_files.append(docx_transcript_path)
# JSON with diarization as SOURCE
# JSON as SOURCE
json_data = {
"task": task_type,
"transcript": transcript_text,
@@ -320,10 +318,8 @@ def process_transcription_task(
"job_id": task_id,
},
}
if summary_text:
json_data["summary"] = summary_text
if raw_result is not None:
json_data["raw_result"] = raw_result
@@ -332,7 +328,7 @@ def process_transcription_task(
json.dump(json_data, f, indent=2, ensure_ascii=False)
temp_files.append(json_path)
# Summary as .md (only when summary is available)
# Summary files (if present)
if summary_text:
md_summary_path = _safe_filename("SUMMARY", local, date_tag, ".md")
with open(md_summary_path, "w", encoding="utf-8") as f:
@@ -340,22 +336,17 @@ def process_transcription_task(
f.write(summary_text)
temp_files.append(md_summary_path)
# Summary as .docx
docx_summary_path = _safe_filename("SUMMARY", local, date_tag, ".docx")
create_summary_docx(summary_text, docx_summary_path)
temp_files.append(docx_summary_path)
# All attachments
attachments = [
md_transcript_path,
docx_transcript_path,
json_path,
]
if summary_text:
attachments += [
md_summary_path,
docx_summary_path,
]
attachments += [md_summary_path, docx_summary_path]
# 5) Send success email
send_success_email(
@@ -377,12 +368,9 @@ def process_transcription_task(
)
raise e
finally:
# 6) Cleanup temporary files (best-effort)
# 6) Cleanup
for path in temp_files:
_remove_file(path)
# Also remove uploaded audio file
if audio_path:
_remove_file(audio_path)
logger.info("Cleanup completed for job %s.", task_id)