apiTinhThanhV3 / app.py
pmshoanghot's picture
Update app.py
9c79457 verified
from fastapi import FastAPI, HTTPException
from typing import List, Dict, Optional
import json
import requests
from pydantic import BaseModel
app = FastAPI(title="Vietnam Geographic API",
description="API để truy xuất thông tin về các đơn vị hành chính của Việt Nam")
# Mô hình Pydantic cho dữ liệu
class Ward(BaseModel):
name: str
class District(BaseModel):
name: str
wards: List[Ward]
class City(BaseModel):
name: str
districts: List[District]
# Tải dữ liệu từ URL thay vì file local
def load_geographic_data():
try:
# URL dữ liệu từ Hugging Face
url = "https://huggingface.co/spaces/pmshoanghot/api_tinh_thanh/resolve/main/vietnam-provinces.json"
response = requests.get(url)
# Kiểm tra nếu request thành công
if response.status_code == 200:
return response.json()
else:
raise HTTPException(status_code=500, detail=f"Không thể tải dữ liệu từ URL: Mã lỗi {response.status_code}")
except requests.RequestException as e:
raise HTTPException(status_code=500, detail=f"Lỗi khi kết nối đến URL: {str(e)}")
except json.JSONDecodeError:
raise HTTPException(status_code=500, detail="File JSON không hợp lệ")
# Tải dữ liệu khi khởi động ứng dụng
geographic_data = load_geographic_data()
# Endpoint gốc
@app.get("/")
async def root():
return {
"message": "Chào mừng đến với Vietnam Geographic API. Sử dụng /api/list để lấy danh sách tất cả các tỉnh thành."}
# Lấy danh sách tất cả các tỉnh thành
@app.get("/api/list", response_model=List[Dict[str, str]])
async def get_cities():
return [{"name": city["name"]} for city in geographic_data]
# Lấy danh sách quận/huyện của một tỉnh/thành phố cụ thể
@app.get("/api/city/{city_name}/districts", response_model=List[Dict[str, str]])
async def get_districts(city_name: str):
for city in geographic_data:
if city["name"] == city_name:
return [{"name": district["name"]} for district in city["districts"]]
raise HTTPException(status_code=404, detail=f"Không tìm thấy tỉnh/thành phố '{city_name}'")
# Lấy danh sách phường/xã của một quận/huyện cụ thể trong một tỉnh/thành phố
@app.get("/api/city/{city_name}/district/{district_name}/wards", response_model=List[Dict[str, str]])
async def get_wards(city_name: str, district_name: str):
for city in geographic_data:
if city["name"] == city_name:
for district in city["districts"]:
if district["name"] == district_name:
return [{"name": ward["name"]} for ward in district["wards"]]
raise HTTPException(status_code=404,
detail=f"Không tìm thấy quận/huyện '{district_name}' trong tỉnh/thành phố '{city_name}'")
raise HTTPException(status_code=404, detail=f"Không tìm thấy tỉnh/thành phố '{city_name}'")
# Lấy thông tin chi tiết về một tỉnh/thành phố cụ thể
@app.get("/api/city/{city_name}", response_model=City)
async def get_city_detail(city_name: str):
for city in geographic_data:
if city["name"] == city_name:
return city
raise HTTPException(status_code=404, detail=f"Không tìm thấy tỉnh/thành phố '{city_name}'")
# Chức năng tìm kiếm (tìm theo tên một phần)
@app.get("/api/search", response_model=List[Dict[str, str]])
async def search(q: str, type: Optional[str] = "city"):
results = []
if type == "city":
results = [{"name": city["name"]} for city in geographic_data
if q.lower() in city["name"].lower()]
elif type == "district":
for city in geographic_data:
for district in city["districts"]:
if q.lower() in district["name"].lower():
results.append({
"name": district["name"],
"city": city["name"]
})
elif type == "ward":
for city in geographic_data:
for district in city["districts"]:
for ward in district["wards"]:
if q.lower() in ward["name"].lower():
results.append({
"name": ward["name"],
"district": district["name"],
"city": city["name"]
})
return results
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)