Spaces:
Runtime error
Runtime error
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 | |
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 | |
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ể | |
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ố | |
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ể | |
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) | |
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) |