gradio-streamlit-pg / app_gradio.py
eienmojiki's picture
Update app_gradio.py
fe3d9a4 verified
from fastapi import FastAPI
import gradio as gr
import os
import sqlalchemy
from sqlalchemy import create_engine, text, Column, Integer, String, DateTime
from sqlalchemy.orm import sessionmaker, declarative_base
from datetime import datetime
import time
# --- Cấu hình Biến Database (PHẢI KHỚP VỚI run.sh) ---
DB_USER="gradio_user"
DB_PASS="local_password_123"
DB_NAME="gradio_db"
DB_HOST="localhost" # Kết nối cục bộ
DB_PORT="5432"
# --- Thiết lập Cơ sở dữ liệu (Database Setup) ---
# 1. Tạo chuỗi kết nối cục bộ
DATABASE_URL = f"postgresql://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
DB_IS_LOCAL = True
# 2. Tạo kết nối
print("Đang kết nối tới cơ sở dữ liệu PostgreSQL cục bộ...")
try:
engine = create_engine(DATABASE_URL)
# Thử kết nối nhanh
with engine.connect() as connection:
print("Kết nối PostgreSQL cục bộ thành công.")
except Exception as e:
print(f"LỖI NGHIÊM TRỌNG: Không thể kết nối tới DB cục bộ: {e}")
print("Sử dụng cơ sở dữ liệu SQLite trong bộ nhớ để demo.")
engine = create_engine("sqlite:///:memory:")
DB_IS_LOCAL = False # Đánh dấu là đang chạy demo
Base = declarative_base()
# 3. Định nghĩa mô hình bảng (Table Model)
class Note(Base):
__tablename__ = 'notes'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(100), nullable=False)
message = Column(String(500), nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
# 4. Tạo bảng (nếu chưa tồn tại)
try:
Base.metadata.create_all(engine)
print("Bảng 'notes' đã được kiểm tra/tạo thành công.")
except Exception as e:
print(f"Lỗi khi tạo bảng (có thể bảng đã tồn tại): {e}")
# 5. Tạo một Session để tương tác với DB
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# --- Hàm xử lý Gradio ---
def add_entry(username, message):
"""Thêm một mục mới vào cơ sở dữ liệu."""
if not DB_IS_LOCAL:
print("Chạy ở chế độ demo (SQLite), không thêm vào DB.")
return get_entries()
if not username or not message:
return get_entries() # Chỉ tải lại, không thêm gì
try:
db = SessionLocal()
new_note = Note(username=username, message=message)
db.add(new_note)
db.commit()
print(f"Đã thêm mục mới từ: {username}")
except Exception as e:
print(f"Lỗi khi thêm mục: {e}")
db.rollback()
return f"Lỗi khi thêm mục: {e}"
finally:
db.close()
# Sau khi thêm, tải lại các mục
return get_entries()
def get_entries():
"""Lấy tất cả các mục từ cơ sở dữ liệu và định dạng chúng."""
if not DB_IS_LOCAL:
return "Ứng dụng đang chạy ở chế độ demo (SQLite). Không thể kết nối với DB cục bộ."
output = ""
try:
db = SessionLocal()
# Lấy 20 mục gần nhất
notes = db.query(Note).order_by(Note.created_at.desc()).limit(20).all()
if not notes:
output = "Chưa có tin nhắn nào. Hãy là người đầu tiên!"
else:
# Định dạng đầu ra (hiển thị từ mới nhất)
for note in notes:
time_str = note.created_at.strftime('%Y-%m-%d %H:%M')
output += f"[{time_str}] {note.username}:\n{note.message}\n" + "-"*20 + "\n"
except Exception as e:
print(f"Lỗi khi tải mục: {e}")
output = f"Lỗi khi tải mục: {e}"
finally:
db.close()
return output
with gr.Blocks(title="Gradio + PG (Local)") as gr_interface:
gr.Markdown("# Sổ khách (Gradio + PostgreSQL Cục bộ)")
gr.Markdown("Để lại tin nhắn và xem các tin nhắn trước đó. CẢNH BÁO: Dữ liệu sẽ bị mất khi Space khởi động lại!")
with gr.Row():
with gr.Column(scale=1):
username_input = gr.Textbox(label="Tên của bạn")
message_input = gr.Textbox(label="Tin nhắn của bạn", lines=4, placeholder="Viết gì đó...")
submit_button = gr.Button("Gửi tin nhắn", variant="primary")
with gr.Column(scale=2):
output_display = gr.Textbox(
label="Tin nhắn đã lưu (Tải lại tự động)",
lines=12,
interactive=False
)
# Tải các mục khi giao diện khởi động
gr_interface.load(get_entries, outputs=output_display)
# Liên kết nút Gửi
submit_button.click(
fn=add_entry,
inputs=[username_input, message_input],
outputs=output_display
).then(
# Xóa các ô input sau khi gửi
lambda: (gr.update(value=""), gr.update(value="")),
outputs=[username_input, message_input]
)
app = FastAPI()
app = gr.mount_gradio_app(app, gr_interface, path="/")