Spaces:
Running
Running
File size: 5,187 Bytes
f0018cc df3812c f0018cc df3812c f0018cc df3812c f0018cc df3812c f0018cc df3812c f0018cc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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="/") |