Spaces:
Sleeping
Sleeping
Commit ·
bf68f81
1
Parent(s): 4a84c22
push
Browse files- backend/app/main.py +41 -35
- entrypoint.sh +0 -15
- requirements.txt +1 -0
backend/app/main.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
import io
|
| 3 |
-
|
|
|
|
| 4 |
import matplotlib
|
| 5 |
matplotlib.use("Agg")
|
| 6 |
import matplotlib.dates as mdates
|
|
@@ -20,8 +21,6 @@ import json
|
|
| 20 |
import math
|
| 21 |
import sys
|
| 22 |
import hashlib
|
| 23 |
-
import smtplib
|
| 24 |
-
from email.message import EmailMessage
|
| 25 |
from pathlib import Path
|
| 26 |
from typing import Any, Dict, List, Optional, Tuple
|
| 27 |
from time import perf_counter
|
|
@@ -1101,26 +1100,15 @@ def send_calc_email(
|
|
| 1101 |
pdf_bytes: bytes | None = None,
|
| 1102 |
pdf_filename: str = "wind_report.pdf",
|
| 1103 |
) -> None:
|
| 1104 |
-
""
|
| 1105 |
-
|
| 1106 |
-
|
| 1107 |
|
| 1108 |
-
|
| 1109 |
-
|
| 1110 |
-
smtp_user = os.getenv("SMTP_USER")
|
| 1111 |
-
smtp_pass = os.getenv("SMTP_PASS")
|
| 1112 |
-
smtp_from = os.getenv("SMTP_FROM", smtp_user or "")
|
| 1113 |
-
|
| 1114 |
-
if not smtp_host or not smtp_from:
|
| 1115 |
-
print("[email] SMTP not configured. Skipping email.")
|
| 1116 |
return
|
| 1117 |
|
| 1118 |
-
|
| 1119 |
-
|
| 1120 |
-
msg = EmailMessage()
|
| 1121 |
-
msg["Subject"] = "Your wind park analysis is ready"
|
| 1122 |
-
msg["From"] = smtp_from
|
| 1123 |
-
msg["To"] = to_email
|
| 1124 |
|
| 1125 |
body = (
|
| 1126 |
"Dear Sir or Madam,\n\n"
|
|
@@ -1135,28 +1123,46 @@ def send_calc_email(
|
|
| 1135 |
"Kind regards,\n"
|
| 1136 |
"Wind Model Backend Team\n"
|
| 1137 |
)
|
| 1138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1139 |
|
| 1140 |
# Attach PDF (optional)
|
| 1141 |
if pdf_bytes:
|
| 1142 |
-
|
| 1143 |
-
|
| 1144 |
-
|
| 1145 |
-
|
| 1146 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1147 |
)
|
| 1148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1149 |
|
| 1150 |
-
|
| 1151 |
-
with smtplib.SMTP(smtp_host, smtp_port, timeout=15) as server:
|
| 1152 |
-
if use_tls:
|
| 1153 |
-
server.starttls()
|
| 1154 |
-
if smtp_user and smtp_pass:
|
| 1155 |
-
server.login(smtp_user, smtp_pass)
|
| 1156 |
-
server.send_message(msg)
|
| 1157 |
-
print(f"[email] Sent calculation email to {to_email}")
|
| 1158 |
except Exception as e:
|
| 1159 |
-
print(f"[email] Failed to send email to {to_email}: {e}")
|
|
|
|
| 1160 |
|
| 1161 |
|
| 1162 |
# ============================================================
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
import io
|
| 3 |
+
import base64
|
| 4 |
+
import requests
|
| 5 |
import matplotlib
|
| 6 |
matplotlib.use("Agg")
|
| 7 |
import matplotlib.dates as mdates
|
|
|
|
| 21 |
import math
|
| 22 |
import sys
|
| 23 |
import hashlib
|
|
|
|
|
|
|
| 24 |
from pathlib import Path
|
| 25 |
from typing import Any, Dict, List, Optional, Tuple
|
| 26 |
from time import perf_counter
|
|
|
|
| 1100 |
pdf_bytes: bytes | None = None,
|
| 1101 |
pdf_filename: str = "wind_report.pdf",
|
| 1102 |
) -> None:
|
| 1103 |
+
api_key = "0a87a8fed6c0c3a9e0ad1f75822de83fcebfc82ca06fe315d46277431e8a61b8"
|
| 1104 |
+
from_addr = "no-reply@c9a9257150c29993.maileroo.org"
|
| 1105 |
+
from_name = "Wind Model Backend Team"
|
| 1106 |
|
| 1107 |
+
if not api_key or not from_addr:
|
| 1108 |
+
print("[email] MAILEROO_API_KEY / MAILEROO_FROM not set. Skipping email.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1109 |
return
|
| 1110 |
|
| 1111 |
+
subject = "Your wind park analysis is ready"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1112 |
|
| 1113 |
body = (
|
| 1114 |
"Dear Sir or Madam,\n\n"
|
|
|
|
| 1123 |
"Kind regards,\n"
|
| 1124 |
"Wind Model Backend Team\n"
|
| 1125 |
)
|
| 1126 |
+
|
| 1127 |
+
payload = {
|
| 1128 |
+
"from": {"address": from_addr, "display_name": from_name},
|
| 1129 |
+
"to": {"address": to_email},
|
| 1130 |
+
"subject": subject,
|
| 1131 |
+
"plain": body,
|
| 1132 |
+
# If you want HTML too, add: "html": "<p>...</p>"
|
| 1133 |
+
}
|
| 1134 |
|
| 1135 |
# Attach PDF (optional)
|
| 1136 |
if pdf_bytes:
|
| 1137 |
+
payload["attachments"] = [
|
| 1138 |
+
{
|
| 1139 |
+
"file_name": pdf_filename,
|
| 1140 |
+
"content_type": "application/pdf",
|
| 1141 |
+
"content": base64.b64encode(pdf_bytes).decode("ascii"),
|
| 1142 |
+
"inline": False,
|
| 1143 |
+
}
|
| 1144 |
+
]
|
| 1145 |
+
|
| 1146 |
+
try:
|
| 1147 |
+
resp = requests.post(
|
| 1148 |
+
"https://smtp.maileroo.com/api/v2/emails",
|
| 1149 |
+
headers={
|
| 1150 |
+
"Content-Type": "application/json",
|
| 1151 |
+
"X-Api-Key": api_key, # Maileroo auth header
|
| 1152 |
+
},
|
| 1153 |
+
json=payload,
|
| 1154 |
+
timeout=20,
|
| 1155 |
)
|
| 1156 |
|
| 1157 |
+
# Helpful debug output if something goes wrong
|
| 1158 |
+
if resp.status_code >= 400:
|
| 1159 |
+
print("[email] Maileroo error:", resp.status_code, resp.text)
|
| 1160 |
+
return
|
| 1161 |
|
| 1162 |
+
print(f"[email] Sent calculation email to {to_email} via Maileroo.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1163 |
except Exception as e:
|
| 1164 |
+
print(f"[email] Failed to send email to {to_email} via Maileroo: {e}")
|
| 1165 |
+
|
| 1166 |
|
| 1167 |
|
| 1168 |
# ============================================================
|
entrypoint.sh
CHANGED
|
@@ -107,21 +107,6 @@ except Exception:
|
|
| 107 |
print("[FATAL] Import of app.main failed. Full traceback:")
|
| 108 |
traceback.print_exc()
|
| 109 |
raise SystemExit(1)
|
| 110 |
-
PY
|
| 111 |
-
python - <<'PY'
|
| 112 |
-
import socket
|
| 113 |
-
|
| 114 |
-
def test(host, port):
|
| 115 |
-
try:
|
| 116 |
-
s = socket.create_connection((host, port), timeout=5)
|
| 117 |
-
s.close()
|
| 118 |
-
print("OK ", host, port)
|
| 119 |
-
except Exception as e:
|
| 120 |
-
print("FAIL", host, port, repr(e))
|
| 121 |
-
|
| 122 |
-
test("www.google.com", 443)
|
| 123 |
-
test("smtp.gmail.com", 587)
|
| 124 |
-
PY
|
| 125 |
# Uvicorn: lade app.main:app (entspricht /app/backend/app/main.py)
|
| 126 |
exec python -m uvicorn app.main:app --host 0.0.0.0 --port "${PORT:-7860}" --log-level info
|
| 127 |
|
|
|
|
| 107 |
print("[FATAL] Import of app.main failed. Full traceback:")
|
| 108 |
traceback.print_exc()
|
| 109 |
raise SystemExit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
# Uvicorn: lade app.main:app (entspricht /app/backend/app/main.py)
|
| 111 |
exec python -m uvicorn app.main:app --host 0.0.0.0 --port "${PORT:-7860}" --log-level info
|
| 112 |
|
requirements.txt
CHANGED
|
@@ -16,6 +16,7 @@ h5netcdf
|
|
| 16 |
scikit-learn==1.8.0
|
| 17 |
dask
|
| 18 |
dask[dataframe]
|
|
|
|
| 19 |
# --- add for your backend/app/main.py deployment ---
|
| 20 |
reportlab
|
| 21 |
huggingface_hub
|
|
|
|
| 16 |
scikit-learn==1.8.0
|
| 17 |
dask
|
| 18 |
dask[dataframe]
|
| 19 |
+
requests
|
| 20 |
# --- add for your backend/app/main.py deployment ---
|
| 21 |
reportlab
|
| 22 |
huggingface_hub
|