amosnbn commited on
Commit
ffcccde
Β·
1 Parent(s): c3c0453
Files changed (1) hide show
  1. app.py +17 -8
app.py CHANGED
@@ -1,7 +1,7 @@
1
  # app.py
2
  # PapuaTranslate β€” Flask + SQLAlchemy (Supabase/SQLite) + mT5-LoRA (lazy)
3
  import os, re, logging, threading
4
- from datetime import datetime, timezone
5
  from functools import wraps
6
  from flask import Flask, render_template, request, redirect, url_for, session, jsonify, flash
7
  from werkzeug.middleware.proxy_fix import ProxyFix
@@ -11,22 +11,24 @@ logging.basicConfig(level=logging.INFO, format="%(asctime)s | %(levelname)s | %(
11
  log = logging.getLogger("papua-app")
12
 
13
  # ===== Flask =====
14
- # Template ada di 'frontend/' sesuai struktur kamu
15
  app = Flask(__name__, template_folder="frontend", static_folder="static")
16
 
17
- # TRUST reverse proxy di HF (agar proto https & host benar β†’ cookie Secure & redirect aman)
18
  app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
19
 
20
- # Session config: aman untuk iframe (Spaces) agar cookie tidak ditolak browser
21
  app.config.update(
22
  SECRET_KEY=os.getenv("SECRET_KEY", "dev-secret-change-me"),
23
  SESSION_COOKIE_NAME="hfspace_session",
24
- SESSION_COOKIE_SAMESITE="None", # penting: iframe = third-party context
25
  SESSION_COOKIE_SECURE=True, # wajib True kalau SAMESITE=None
26
  SESSION_COOKIE_HTTPONLY=True,
27
  SESSION_COOKIE_PATH="/",
28
  PREFERRED_URL_SCHEME="https",
29
  )
 
 
30
 
31
  # ===== DB: SQLAlchemy (Supabase Postgres / SQLite fallback) =====
32
  from sqlalchemy import create_engine, Column, Integer, Text, DateTime, ForeignKey, func
@@ -37,7 +39,7 @@ if not DATABASE_URL:
37
  DATABASE_URL = "sqlite:////tmp/app.db"
38
  log.warning("[DB] DATABASE_URL tidak diset; pakai SQLite /tmp/app.db")
39
  else:
40
- # normalisasi skema ke psycopg2 driver
41
  if DATABASE_URL.startswith("postgres://"):
42
  DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql+psycopg2://", 1)
43
  elif DATABASE_URL.startswith("postgresql://"):
@@ -103,7 +105,7 @@ def prenorm(text: str) -> str:
103
  from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
104
  from peft import PeftModel
105
 
106
- # Mulai dengan model kecil agar UI/DB bisa diuji cepat; ganti ke model kamu setelahnya
107
  BASE_MODEL_ID = os.getenv("BASE_MODEL_ID", "google/mt5-small")
108
  ADAPTER_ID = os.getenv("ADAPTER_ID", "")
109
  DEVICE = "cuda" if os.getenv("DEVICE", "cpu") == "cuda" else "cpu"
@@ -153,9 +155,10 @@ def _err(e):
153
  log.exception("Unhandled error")
154
  return "Internal Server Error", 500
155
 
156
- # ===== Debug endpoints untuk cek session cookie =====
157
  @app.get("/debug/session/set")
158
  def dbg_set():
 
159
  session["uid"] = "test-user"
160
  session["email"] = "[email protected]"
161
  return {"ok": True, "set": True}
@@ -184,7 +187,11 @@ def login_post():
184
  u = s.query(User).filter_by(email=email).first()
185
  if not u or not verify_password(u, pwd):
186
  flash("Email atau password salah", "error"); return redirect(url_for("login_get"))
 
 
 
187
  session["uid"], session["email"] = u.id, u.email
 
188
  return redirect(url_for("index"))
189
 
190
  @app.get("/register")
@@ -202,6 +209,7 @@ def register_post():
202
  flash("Email sudah terdaftar", "error"); return redirect(url_for("register_get"))
203
  u = User(email=email); set_password(u, pwd)
204
  s.add(u); s.commit()
 
205
  session["uid"], session["email"] = u.id, u.email
206
  return redirect(url_for("index"))
207
 
@@ -247,4 +255,5 @@ def api_translate():
247
  return jsonify({"error": "server error"}), 500
248
 
249
  if __name__ == "__main__":
 
250
  app.run(host="0.0.0.0", port=int(os.getenv("PORT", "7860")), debug=False)
 
1
  # app.py
2
  # PapuaTranslate β€” Flask + SQLAlchemy (Supabase/SQLite) + mT5-LoRA (lazy)
3
  import os, re, logging, threading
4
+ from datetime import datetime, timezone, timedelta
5
  from functools import wraps
6
  from flask import Flask, render_template, request, redirect, url_for, session, jsonify, flash
7
  from werkzeug.middleware.proxy_fix import ProxyFix
 
11
  log = logging.getLogger("papua-app")
12
 
13
  # ===== Flask =====
14
+ # Template HTML kamu ada di 'frontend/'
15
  app = Flask(__name__, template_folder="frontend", static_folder="static")
16
 
17
+ # Trust reverse proxy di Hugging Face -> Flask tahu proto HTTPS & host asli (perlu untuk cookie/redirect)
18
  app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
19
 
20
+ # Session config: aman untuk iframe/third-party, dan bekerja baik saat dibuka di tab langsung hf.space
21
  app.config.update(
22
  SECRET_KEY=os.getenv("SECRET_KEY", "dev-secret-change-me"),
23
  SESSION_COOKIE_NAME="hfspace_session",
24
+ SESSION_COOKIE_SAMESITE="None", # penting untuk iframe / third-party
25
  SESSION_COOKIE_SECURE=True, # wajib True kalau SAMESITE=None
26
  SESSION_COOKIE_HTTPONLY=True,
27
  SESSION_COOKIE_PATH="/",
28
  PREFERRED_URL_SCHEME="https",
29
  )
30
+ # Lama hidup session (untuk session.permanent=True)
31
+ app.permanent_session_lifetime = timedelta(hours=8)
32
 
33
  # ===== DB: SQLAlchemy (Supabase Postgres / SQLite fallback) =====
34
  from sqlalchemy import create_engine, Column, Integer, Text, DateTime, ForeignKey, func
 
39
  DATABASE_URL = "sqlite:////tmp/app.db"
40
  log.warning("[DB] DATABASE_URL tidak diset; pakai SQLite /tmp/app.db")
41
  else:
42
+ # normalisasi ke psycopg2 driver
43
  if DATABASE_URL.startswith("postgres://"):
44
  DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql+psycopg2://", 1)
45
  elif DATABASE_URL.startswith("postgresql://"):
 
105
  from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
106
  from peft import PeftModel
107
 
108
+ # Mulai dengan model kecil untuk uji UI; setelah lancar, ganti ke model kamu
109
  BASE_MODEL_ID = os.getenv("BASE_MODEL_ID", "google/mt5-small")
110
  ADAPTER_ID = os.getenv("ADAPTER_ID", "")
111
  DEVICE = "cuda" if os.getenv("DEVICE", "cpu") == "cuda" else "cpu"
 
155
  log.exception("Unhandled error")
156
  return "Internal Server Error", 500
157
 
158
+ # ===== Debug endpoints (cek cookie session) =====
159
  @app.get("/debug/session/set")
160
  def dbg_set():
161
+ session.permanent = True
162
  session["uid"] = "test-user"
163
  session["email"] = "[email protected]"
164
  return {"ok": True, "set": True}
 
187
  u = s.query(User).filter_by(email=email).first()
188
  if not u or not verify_password(u, pwd):
189
  flash("Email atau password salah", "error"); return redirect(url_for("login_get"))
190
+
191
+ # penting: buat session 'permanent' supaya cookie ditulis dengan benar
192
+ session.permanent = True
193
  session["uid"], session["email"] = u.id, u.email
194
+
195
  return redirect(url_for("index"))
196
 
197
  @app.get("/register")
 
209
  flash("Email sudah terdaftar", "error"); return redirect(url_for("register_get"))
210
  u = User(email=email); set_password(u, pwd)
211
  s.add(u); s.commit()
212
+ session.permanent = True
213
  session["uid"], session["email"] = u.id, u.email
214
  return redirect(url_for("index"))
215
 
 
255
  return jsonify({"error": "server error"}), 500
256
 
257
  if __name__ == "__main__":
258
+ # Jalankan lokal: python app.py, atau di HF pakai gunicorn
259
  app.run(host="0.0.0.0", port=int(os.getenv("PORT", "7860")), debug=False)