Aus_F / app.py
minhvtt's picture
Upload 3 files
0668f26 verified
Raw
History Blame
5.76 kB
"""
Real Estate Description Formatter API
Uses lightweight AI models from HuggingFace to format real estate descriptions
"""
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional
import os
from huggingface_hub import InferenceClient
# FastAPI app
app = FastAPI(
title="Real Estate Description Formatter",
description="API to format real estate descriptions with AI",
version="1.0.0"
)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Initialize HuggingFace Inference Client
# Sử dụng model mạnh: Qwen2.5-7B-Instruct (7B params, hỗ trợ tiếng Việt)
# Alternatives: mistralai/Mistral-7B-Instruct-v0.3, google/gemma-2-7b-it
MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-7B-Instruct")
HF_TOKEN = os.getenv("HF_TOKEN", None) # Optional: for private models or faster inference
client = InferenceClient(model=MODEL_NAME, token=HF_TOKEN)
# Request/Response Models
class RealEstateInput(BaseModel):
description: str
class RealEstateOutput(BaseModel):
original: str
formatted_html: str
success: bool
error: Optional[str] = None
# Prompt phức tạp để xử lý form description bất động sản
SYSTEM_PROMPT = """Bạn là một chuyên gia định dạng nội dung bất động sản chuyên nghiệp.
NHIỆM VỤ: Chuyển đổi mô tả bất động sản "xấu" (không có cấu trúc, viết tắt, thiếu dấu câu) thành HTML được format đẹp mắt với CSS inline.
QUY TẮC QUAN TRỌNG:
1. KHÔNG ĐƯỢC thay đổi nội dung text gốc - CHỈ thêm HTML tags và CSS styling
2. PHẢI giữ nguyên tất cả thông tin: giá, diện tích, số phòng, địa chỉ, số điện thoại
3. PHẢI phân tích và nhận diện các thành phần:
- Tiêu đề (tên BDS, loại nhà)
- Thông tin kỹ thuật (diện tích, hướng, pháp lý)
- Mô tả chi tiết (kết cấu, nội thất)
- Vị trí (địa chỉ, khu vực, tiện ích xung quanh)
- Giá bán
- Liên hệ (SĐT, tên người bán)
- ... các thành phần khác
4. SỬ DỤNG CẤU TRÚC HTML:
- <div class="property-card"> cho toàn bộ nội dung
- <h1 class="title"> cho tiêu đề chính
- <div class="specs"> cho thông số kỹ thuật (badge style)
- <div class="description"> cho mô tả chi tiết
- <div class="location"> cho thông tin vị trí
- <div class="price"> cho giá (highlight, font lớn)
- <div class="contact"> cho thông tin liên hệ
5. CSS INLINE STYLING - Màu sắc hiện đại, dễ đọc:
- Property card: background, border radius, shadow
- Title: màu đậm, font-size lớn, text-transform uppercase
- Specs: badge style với background color khác nhau
- Price: màu phù hợp, không quá chói mắt, cũng không quá trầm, nổi bật, font-weight bold, font-size lớn
- Icons: không sử dụng icon gì khác.
6. XỬ LÝ VIẾT TẮT:
- Giữ nguyên viết tắt nhưng thêm tooltip/title
- Ví dụ: <span title="Phòng ngủ">Pn</span>, <span title="Phòng vệ sinh">wc</span>
OUTPUT FORMAT: Chỉ trả về HTML thuần, KHÔNG kèm markdown hoặc giải thích.
"""
USER_PROMPT_TEMPLATE = """Hãy format mô tả bất động sản sau thành HTML đẹp với CSS inline:
{description}
Nhớ: GIỮ NGUYÊN nội dung text, CHỈ thêm HTML/CSS để trình bày đẹp hơn."""
@app.get("/")
async def root():
"""API root"""
return {
"name": "Real Estate Description Formatter",
"version": "1.0.0",
"model": MODEL_NAME,
"endpoint": "/format"
}
@app.post("/format", response_model=RealEstateOutput)
async def format_description(input_data: RealEstateInput):
"""
Format real estate description with AI
Example input:
{
"description": "NHÀ 2 TẦNG HẺM OTO LIÊN HOA VĨNH NGỌC - TÂY NHA TRANG- Diện tích 92m² full ONT- Hướng Đông Bắc- Pháp lý sổ hồng hoàn công..."
}
"""
try:
# Prepare messages for chat model
messages = [
{
"role": "system",
"content": SYSTEM_PROMPT
},
{
"role": "user",
"content": USER_PROMPT_TEMPLATE.format(description=input_data.description)
}
]
# Call HuggingFace Inference API
response = client.chat_completion(
messages=messages,
max_tokens=2000,
temperature=0.3, # Low temperature for consistent formatting
)
# Extract formatted HTML
formatted_html = response.choices[0].message.content.strip()
# Clean up markdown if model added it
if formatted_html.startswith("```html"):
formatted_html = formatted_html.replace("```html", "").replace("```", "").strip()
return RealEstateOutput(
original=input_data.description,
formatted_html=formatted_html,
success=True
)
except Exception as e:
return RealEstateOutput(
original=input_data.description,
formatted_html="",
success=False,
error=str(e)
)
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {
"status": "healthy",
"model": MODEL_NAME,
"service": "Real Estate Formatter"
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app:app",
host="0.0.0.0",
port=7860,
reload=False
)