2026-07-09 20:10:10 +00:00
|
|
|
import logging
|
|
|
|
|
|
2026-07-09 18:31:29 +00:00
|
|
|
from fastapi import APIRouter, Depends
|
|
|
|
|
from geoalchemy2 import Geometry
|
|
|
|
|
from sqlalchemy import cast, func, select
|
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
|
|
|
|
from app.db.session import get_db
|
|
|
|
|
from app.models.city import City
|
|
|
|
|
from app.schemas.city import CityOut
|
|
|
|
|
from app.schemas.common import LatLon, LocalizedName
|
|
|
|
|
|
2026-07-09 20:10:10 +00:00
|
|
|
logger = logging.getLogger("guidecity.cities")
|
|
|
|
|
|
2026-07-09 18:31:29 +00:00
|
|
|
router = APIRouter(tags=["cities"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/cities", response_model=list[CityOut])
|
|
|
|
|
def list_cities(db: Session = Depends(get_db)) -> list[CityOut]:
|
|
|
|
|
stmt = select(
|
|
|
|
|
City,
|
|
|
|
|
func.ST_X(cast(City.center_point, Geometry)).label("lon"),
|
|
|
|
|
func.ST_Y(cast(City.center_point, Geometry)).label("lat"),
|
|
|
|
|
)
|
|
|
|
|
rows = db.execute(stmt).all()
|
|
|
|
|
|
|
|
|
|
out = []
|
|
|
|
|
for city, lon, lat in rows:
|
|
|
|
|
center = LatLon(lat=lat, lon=lon) if lat is not None and lon is not None else None
|
|
|
|
|
out.append(
|
|
|
|
|
CityOut(
|
|
|
|
|
id=city.id,
|
|
|
|
|
slug=city.slug,
|
|
|
|
|
name=LocalizedName(ru=city.name_ru, en=city.name_en),
|
|
|
|
|
center=center,
|
|
|
|
|
)
|
|
|
|
|
)
|
2026-07-09 20:10:10 +00:00
|
|
|
logger.debug("listed %d cities", len(out))
|
2026-07-09 18:31:29 +00:00
|
|
|
return out
|